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;