Mercurial > hg > dmlib
diff tools/lib64gfx.c @ 1660:7555c8803529
More work on improving the generic RLE decoder/encoder.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 30 May 2018 17:05:19 +0300 |
parents | 9233da9de92c |
children | 1741717b1ae5 |
line wrap: on
line diff
--- a/tools/lib64gfx.c Wed May 30 14:45:14 2018 +0300 +++ b/tools/lib64gfx.c Wed May 30 17:05:19 2018 +0300 @@ -308,19 +308,18 @@ { if (stats[n] < smallest) { - selected = n; + cfg->rleMarkerW = selected; + cfg->rleMarkerB = selected = n; smallest = stats[n]; } } - - cfg->rleMarker1 = selected; } break; case DM_COMP_RLE_MASK: - cfg->rleMarker1 = 0xC0; - cfg->rleMask1 = 0xC0; - cfg->rleMask2 = 0x3f; + cfg->rleMarkerMask = 0xC0; + cfg->rleMarkerBits = 0xC0; + cfg->rleCountMask = 0x3f; break; } @@ -341,7 +340,7 @@ if (cfg->type == DM_COMP_RLE_MARKER) { // A simple marker byte RLE variant: [Marker] [count] [data] - if (data == cfg->rleMarker1 && (cfg->flags & DM_RLE_8BIT_RUNS)) + if (data == cfg->rleMarkerB && (cfg->flags & DM_RLE_BYTE_RUNS)) { if (srcEnd - src + 1 < 2) { @@ -364,7 +363,7 @@ src += 2; } else - if (data == cfg->rleMarker2 && (cfg->flags & DM_RLE_16BIT_RUNS)) + if (data == cfg->rleMarkerW && (cfg->flags & DM_RLE_WORD_RUNS)) { if (srcEnd - src + 1 < 3) { @@ -392,7 +391,7 @@ { // Mask marker RLE: usually high bit(s) of byte mark RLE sequence // and the lower bits contain the count: [Mask + count] [data] - if ((data & cfg->rleMask1) == cfg->rleMarker1) + if ((data & cfg->rleMarkerMask) == cfg->rleMarkerBits) { if (srcEnd - src + 1 < 1) { @@ -400,7 +399,7 @@ goto err; } - count = data & cfg->rleMask2; + count = data & cfg->rleCountMask; data = *src++; } } @@ -432,17 +431,41 @@ } -static BOOL dmEncodeGenericRLESequence(DMGrowBuf *dst, const Uint8 data, Uint8 count, const DMCompParams *cfg) +static BOOL dmEncodeGenericRLESequence(DMGrowBuf *dst, const Uint8 data, int count, const DMCompParams *cfg) { BOOL copyOnly = FALSE; switch (cfg->type) { case DM_COMP_RLE_MARKER: - if (count >= cfg->rleMinCount || data == cfg->rleMarker1) + if ((cfg->flags & DM_RLE_WORD_RUNS) && + (count >= cfg->rleMinCountW || data == cfg->rleMarkerW)) { // A simple marker byte RLE variant: [Marker] [count] [data] - if (!dmGrowBufPutU8(dst, cfg->rleMarker1)) + if (!dmGrowBufPutU8(dst, cfg->rleMarkerW)) + return FALSE; + + switch (cfg->flags & DM_RLE_ORDER_MASK) + { + case DM_RLE_ORDER_1: + if (!dmGrowBufPutU16LE(dst, count) || + !dmGrowBufPutU8(dst, data)) + return FALSE; + break; + + case DM_RLE_ORDER_2: + if (!dmGrowBufPutU8(dst, data) || + !dmGrowBufPutU16LE(dst, count)) + return FALSE; + break; + } + } + else + if ((cfg->flags & DM_RLE_BYTE_RUNS) && + (count >= cfg->rleMinCountB || data == cfg->rleMarkerB)) + { + // A simple marker byte RLE variant: [Marker] [count] [data] + if (!dmGrowBufPutU8(dst, cfg->rleMarkerB)) return FALSE; switch (cfg->flags & DM_RLE_ORDER_MASK) @@ -465,11 +488,11 @@ break; case DM_COMP_RLE_MASK: - if (count >= cfg->rleMinCount || (data & cfg->rleMask1) == cfg->rleMarker1) + if (count >= cfg->rleMinCountB || (data & cfg->rleMarkerMask) == cfg->rleMarkerBits) { // Mask marker RLE: usually high bit(s) of byte mark RLE sequence // and the lower bits contain the count: [Mask + count] [data] - if (!dmGrowBufPutU8(dst, cfg->rleMarker1 | count) || + if (!dmGrowBufPutU8(dst, cfg->rleMarkerBits | count) || !dmGrowBufPutU8(dst, data)) return FALSE; } @@ -499,7 +522,11 @@ { Uint8 data = *src++; - if (data != prev || count >= cfg->rleMaxCount) + // If new data byte is different, or we exceed the rleMaxCount + // for the active runs mode(s) .. then encode the run. + if (data != prev || + ((cfg->flags & DM_RLE_WORD_RUNS) && count >= cfg->rleMaxCountW) || + (((cfg->flags & DM_RLE_RUNS_MASK) == DM_RLE_BYTE_RUNS) && count >= cfg->rleMaxCountB)) { if (!dmEncodeGenericRLESequence(dst, prev, count, cfg)) goto err;