# HG changeset patch # User Matti Hamalainen # Date 1543856467 -7200 # Node ID 416af5a842ec65dc761b5ccf56018cc66d83b6d1 # Parent a945a5f2fd7034276561f3451a94327d62d28eec Fixes to the ByteRun1 encoder. Could use some cleanups now, tho. diff -r a945a5f2fd70 -r 416af5a842ec tools/libgfx.c --- a/tools/libgfx.c Mon Dec 03 18:58:45 2018 +0200 +++ b/tools/libgfx.c Mon Dec 03 19:01:07 2018 +0200 @@ -2048,80 +2048,105 @@ }; -BOOL dmIFFEncodeByteRun1Flush( - DMResource *fp, const int mode, const BOOL flush, - size_t *l_offs, const size_t offs, const Uint8 *buf, - const Uint8 data, unsigned int *r_count) +BOOL dmIFFEncodeByteRun1LIT(DMResource *fp, + const Uint8 *buf, const size_t offs, + const size_t count) { - if (mode == DMODE_LIT) - { - size_t l_count = offs - *l_offs; - if (l_count > *r_count || flush) - { - size_t count = l_count - *r_count; - Uint8 tmp = count - 1; - - if (!dmf_write_byte(fp, tmp) || - !dmf_write_str(fp, buf + *l_offs, count)) - return FALSE; - } - (*r_count)++; - } - else - { - if (*r_count > 0) - { - unsigned int count = *r_count; - Uint8 tmp = ((Uint8) count - 2) ^ 0xff; - - if (!dmf_write_byte(fp, tmp) || - !dmf_write_byte(fp, data)) - return FALSE; - - *r_count = 0; - } - *l_offs = offs; - } - - return TRUE; + if (count <= 0) + return TRUE; + + Uint8 tmp = count - 1; + + return + dmf_write_byte(fp, tmp) && + dmf_write_str(fp, buf + offs, count); +} + + +BOOL dmIFFEncodeByteRun1RLE(DMResource *fp, + const Uint8 *buf, const size_t offs, + const size_t count) +{ + if (count <= 0) + return TRUE; + + Uint8 + tmp = ((Uint8) count - 2) ^ 0xff, + data = buf[offs]; + + return + dmf_write_byte(fp, tmp) && + dmf_write_byte(fp, data); } BOOL dmIFFEncodeByteRun1Row(DMResource *fp, const Uint8 *buf, const size_t bufLen) { - unsigned int r_count = 0; int prev = -1, mode = DMODE_LIT; - size_t offs, l_offs = 0; - - for (offs = 0; offs < bufLen; offs++) + size_t offs, l_offs, r_offs; + BOOL ret = TRUE; + + for (offs = l_offs = r_offs = 0; offs < bufLen; offs++) { Uint8 data = buf[offs]; - int next_mode; - BOOL flush; + BOOL flush = FALSE; + int pmode = mode; if (data == prev) { - r_count++; - next_mode = DMODE_RLE; + if (mode == DMODE_LIT && + offs - r_offs >= 2) + { + ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, r_offs - l_offs); + mode = DMODE_RLE; + } } else { - next_mode = DMODE_LIT; + if (mode != DMODE_LIT) + { + ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs); + mode = DMODE_LIT; + l_offs = offs; + } + r_offs = offs; } - flush = offs - l_offs >= 126 || r_count >= 126; - if ((next_mode != mode || flush) && - !dmIFFEncodeByteRun1Flush(fp, mode, flush, &l_offs, offs, buf, prev, &r_count)) - return FALSE; - - mode = next_mode; + if (!ret) + goto out; + + // NOTE! RLE and LIT max are both 128, checked against DP2e + flush = + (pmode == DMODE_RLE && offs - r_offs >= 128) || + (pmode == DMODE_LIT && offs - l_offs >= 128); + + // Check for last byte of input + if (offs == bufLen - 1) + { + offs++; + flush = TRUE; + pmode = mode; + } + + if (flush) + { + if (pmode == DMODE_RLE) + ret = dmIFFEncodeByteRun1RLE(fp, buf, r_offs, offs - r_offs); + else + ret = dmIFFEncodeByteRun1LIT(fp, buf, l_offs, offs - l_offs); + + r_offs = l_offs = offs; + mode = DMODE_LIT; + + if (!ret) + goto out; + } + prev = data; } - if (!dmIFFEncodeByteRun1Flush(fp, mode, TRUE, &l_offs, offs, buf, prev, &r_count)) - return FALSE; - - return TRUE; +out: + return ret; } @@ -2256,6 +2281,7 @@ if ((res = dmWriteIFFChunkFinish(fp, &iff.chCMAP)) != DMERR_OK) goto out; + // // Encode the body //