Skip to content
Snippets Groups Projects
Commit 89d74a14 authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

More LZH updates

- Make lzh_update() return a bool indicating success
- Eliminated calculating array size, use macro
- Fail if the current entry is not in the frequency array
parent c0374478
No related branches found
No related tags found
No related merge requests found
Pipeline #7617 passed
...@@ -415,7 +415,7 @@ static void lzh_reconst(huffman_t* huff) ...@@ -415,7 +415,7 @@ static void lzh_reconst(huffman_t* huff)
   
/* update freq tree */ /* update freq tree */
   
static void lzh_update(huffman_t* huff, uint16_t c) static bool lzh_update(huffman_t* huff, uint16_t c)
{ {
uint16_t l; uint16_t l;
uint16_t tmp; uint16_t tmp;
...@@ -427,24 +427,32 @@ static void lzh_update(huffman_t* huff, uint16_t c) ...@@ -427,24 +427,32 @@ static void lzh_update(huffman_t* huff, uint16_t c)
} }
c = huff->parent[c + LZH_TABLE_SZ]; c = huff->parent[c + LZH_TABLE_SZ];
do { do {
/*
* This is not actually possible.
*/
if (c >= LZH_TABLE_SZ)
return false;
tmp = ++huff->freq[c]; tmp = ++huff->freq[c];
   
/* /*
* If we now have a greater freq than the next node... * If we now have a greater freq than the next node...
* and are not already the last node * and are not already the last node
*/ */
if (c < LZH_TABLE_SZ && tmp > huff->freq[c + 1]) { if (tmp > huff->freq[c + 1]) {
/* /*
* Find the last node after the current one * Find the last node after the current one
* that has a lower frequency than our new one * that has a lower frequency than our new one
*
* There's a sentry at LZH_TABLE_SZ, so we can't
* "find" that one (and we don't actually need
* the second test here)
*
* We can do the range check second because
* huff->freq[LZH_TABLE_SZ] is valid
*/ */
for (l = c + 1; l <= LZH_TABLE_SZ && tmp > huff->freq[l]; l++) for (l = c + 1; tmp > huff->freq[l + 1] && l < (LZH_TABLE_SZ - 1); l++)
; ;
   
// If we exited before the end of table, decrement l
if (tmp <= huff->freq[l])
l--;
// Now swap nodes // Now swap nodes
huff->freq[c] = huff->freq[l]; huff->freq[c] = huff->freq[l];
huff->freq[l] = tmp; huff->freq[l] = tmp;
...@@ -464,7 +472,8 @@ static void lzh_update(huffman_t* huff, uint16_t c) ...@@ -464,7 +472,8 @@ static void lzh_update(huffman_t* huff, uint16_t c)
   
c = l; c = l;
} }
} while (((c = huff->parent[c]) != 0) && c < ((sizeof(huff->child)/sizeof(huff->child[0]))-1)); /* do it until reaching the root */ } while ((c = huff->parent[c]) != 0); /* do it until reaching the root */
return true;
} }
   
static bool lzh_encode_char(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint32_t *outlen) static bool lzh_encode_char(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint32_t *outlen)
...@@ -492,8 +501,7 @@ static bool lzh_encode_char(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint ...@@ -492,8 +501,7 @@ static bool lzh_encode_char(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint
} while ((k = lzh->huff.parent[k]) != LZH_ROOT); } while ((k = lzh->huff.parent[k]) != LZH_ROOT);
if (!lzh_putcode(lzh, j, i, outbuf, outlen)) if (!lzh_putcode(lzh, j, i, outbuf, outlen))
return false; return false;
lzh_update(&lzh->huff,c); return lzh_update(&lzh->huff,c);
return true;
} }
   
static bool lzh_encode_position(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint32_t *outlen) static bool lzh_encode_position(lzh_encode_t* lzh, uint16_t c, uint8_t *outbuf, uint32_t *outlen)
...@@ -519,11 +527,9 @@ static bool lzh_encode_end(lzh_encode_t* lzh, uint8_t *outbuf, uint32_t *outlen) ...@@ -519,11 +527,9 @@ static bool lzh_encode_end(lzh_encode_t* lzh, uint8_t *outbuf, uint32_t *outlen)
return true; return true;
} }
   
static uint16_t lzh_decode_char(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_t *incnt, uint32_t inlen) static bool lzh_decode_char(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_t *incnt, uint32_t inlen, uint16_t *outc)
{ {
uint16_t c; uint16_t c = lzh->huff.child[LZH_ROOT];
c = lzh->huff.child[LZH_ROOT];
   
/* /*
* start searching tree from the root to leaves. * start searching tree from the root to leaves.
...@@ -535,8 +541,8 @@ static uint16_t lzh_decode_char(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_ ...@@ -535,8 +541,8 @@ static uint16_t lzh_decode_char(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_
c = lzh->huff.child[c]; c = lzh->huff.child[c];
} }
c -= LZH_TABLE_SZ; c -= LZH_TABLE_SZ;
lzh_update(&lzh->huff,c); *outc = c;
return c; return lzh_update(&lzh->huff,c);
} }
   
static uint16_t lzh_decode_position(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_t *incnt, uint32_t inlen) static uint16_t lzh_decode_position(lzh_decode_t* lzh, const uint8_t *inbuf, uint32_t *incnt, uint32_t inlen)
...@@ -659,7 +665,8 @@ uint32_t lzh_decode(const uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, size_ ...@@ -659,7 +665,8 @@ uint32_t lzh_decode(const uint8_t *inbuf, uint32_t inlen, uint8_t *outbuf, size_
*(lzh.text_buf+i) = ' '; *(lzh.text_buf+i) = ' ';
r = LZH_STRBUF_SZ - LZH_LOOKAHD_SZ; r = LZH_STRBUF_SZ - LZH_LOOKAHD_SZ;
for (count = 0; count < textsize; ) { for (count = 0; count < textsize; ) {
c = lzh_decode_char(&lzh,inbuf,&incnt,inlen); if (!lzh_decode_char(&lzh,inbuf,&incnt,inlen,&c))
return 0;
if (c < 256) { if (c < 256) {
if (count >= outlen || count == UINT32_MAX) if (count >= outlen || count == UINT32_MAX)
return 0; return 0;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment