Mercurial > hg > dmlib
changeset 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 | 99b8ab61dc1b |
children | dc3fbd130db7 |
files | tools/lib64fmts.c tools/lib64gfx.c tools/lib64gfx.h |
diffstat | 3 files changed, 91 insertions(+), 52 deletions(-) [+] |
line wrap: on
line diff
--- a/tools/lib64fmts.c Wed May 30 14:45:14 2018 +0300 +++ b/tools/lib64fmts.c Wed May 30 17:05:19 2018 +0300 @@ -52,8 +52,8 @@ DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_2; - cfg.rleMarker1 = 0xfe; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2; + cfg.rleMarkerB = 0xfe; if ((res = dmDecodeGenericRLEAlloc(&mem, buf, buf + len, &cfg)) != DMERR_OK) goto out; @@ -76,11 +76,11 @@ goto out; // And now RLE compress the data to the existing buffer - cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_2; - cfg.rleMarker1 = 0xfe; - cfg.rleMinCount = 3; - cfg.rleMaxCount = 255; + cfg.type = DM_COMP_RLE_MARKER; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_2; + cfg.rleMarkerB = 0xfe; + cfg.rleMinCountB = 3; + cfg.rleMaxCountB = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); out: @@ -113,8 +113,8 @@ DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMarker1 = buf[0x0d]; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMarkerB = buf[0x0d]; if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 0x0e, buf + len, &cfg)) != DMERR_OK) goto out; @@ -140,14 +140,14 @@ // Analyze and setup RLE dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); - cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMinCount = 3; - cfg.rleMaxCount = 255; + cfg.type = DM_COMP_RLE_MARKER; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMinCountB = 3; + cfg.rleMaxCountB = 255; // Add the header bits if (!dmGrowBufPut(buf, magicID, strlen(magicID)) || - !dmGrowBufPutU8(buf, cfg.rleMarker1)) + !dmGrowBufPutU8(buf, cfg.rleMarkerB)) { res = DMERR_MALLOC; goto out; @@ -212,9 +212,9 @@ DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_16BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMarker1 = buf[8]; - cfg.rleMarker2 = buf[9]; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_WORD_RUNS | DM_RLE_ORDER_1; + cfg.rleMarkerB = buf[8]; + cfg.rleMarkerW = buf[9]; if ((res = dmDecodeGenericRLEAlloc(&mem, buf + 10, buf + len, &cfg)) != DMERR_OK) goto out; @@ -280,8 +280,8 @@ // Now do an RLE decode on the enlarged buffer cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMarker1 = 0xC2; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMarkerB = 0xC2; if ((res = dmDecodeGenericRLEAlloc(&mem, tmp.data, tmp.data + tmp.len, &cfg)) != DMERR_OK) goto out; @@ -307,11 +307,11 @@ goto out; // And now RLE compress the data to the existing buffer - cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMarker1 = 0xC2; - cfg.rleMinCount = 3; - cfg.rleMaxCount = 255; + cfg.type = DM_COMP_RLE_MARKER; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMarkerB = 0xC2; + cfg.rleMinCountB = 3; + cfg.rleMaxCountB = 255; res = dmEncodeGenericRLE(buf, tmp.data, tmp.data + tmp.len, &cfg); @@ -548,8 +548,8 @@ DMCompParams cfg; cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMarker1 = buf[15]; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMarkerB = buf[15]; if ((res = dmDecodeGenericRLEAlloc( &mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, &cfg)) == DMERR_OK) @@ -589,14 +589,14 @@ // Analyze and setup RLE dmGenericRLEAnalyze(tmp.data, tmp.len, &cfg); - cfg.type = DM_COMP_RLE_MARKER; - cfg.flags = DM_RLE_8BIT_RUNS | DM_RLE_ORDER_1; - cfg.rleMinCount = 3; - cfg.rleMaxCount = 255; + cfg.type = DM_COMP_RLE_MARKER; + cfg.flags = DM_RLE_BYTE_RUNS | DM_RLE_ORDER_1; + cfg.rleMinCountB = 3; + cfg.rleMaxCountB = 255; // Add the header bits if (!dmGrowBufPut(buf, fmtFunPaint2MagicID, strlen(fmtFunPaint2MagicID)) || - !dmGrowBufPutU8(buf, cfg.rleMarker1)) + !dmGrowBufPutU8(buf, cfg.rleMarkerB)) { res = DMERR_MALLOC; goto out;
--- 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;
--- a/tools/lib64gfx.h Wed May 30 14:45:14 2018 +0300 +++ b/tools/lib64gfx.h Wed May 30 17:05:19 2018 +0300 @@ -214,8 +214,8 @@ enum { - DM_RLE_8BIT_RUNS = 0x0001, // Uses one-byte runs - DM_RLE_16BIT_RUNS = 0x0002, // Uses two-byte runs + DM_RLE_BYTE_RUNS = 0x0001, // Uses one-byte run lengths + DM_RLE_WORD_RUNS = 0x0002, // Uses two-byte (word) run lengths DM_RLE_RUNS_MASK = 0x000f, DM_RLE_ORDER_1 = 0x0000, // Order: <marker>, <count/run length>, <data> @@ -229,9 +229,21 @@ int type; int flags; Uint8 - rleMarker1, rleMarker2, - rleMask1, rleMask2, - rleMinCount, rleMaxCount; + // DM_COMP_RLE_MARKER mode + rleMarkerB, // Marker byte for byte length runs (if DM_RLE_BYTE_RUNS used) + rleMarkerW, // Marker byte for word length runs (if DM_RLE_WORD_RUNS used) + + // DM_COMP_RLE_MASK mode + rleMarkerBits, + rleMarkerMask, // Mask bits for marker: data & rleMarkerMask == rleMarkerBits + rleCountMask; // Mask bits for length: count = data & rleCountMask + + int + // Minimum and maximum run lengths + rleMinCountB, + rleMinCountW, + rleMaxCountB, + rleMaxCountW; } DMCompParams;