changeset 1284:28be63226b05

More work on PCX loader.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 18 Aug 2017 03:09:26 +0300
parents 642a0dd98c6e
children e4bda4909d72
files src/libgfx.c
diffstat 1 files changed, 30 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/libgfx.c	Fri Aug 18 02:52:35 2017 +0300
+++ b/src/libgfx.c	Fri Aug 18 03:09:26 2017 +0300
@@ -839,7 +839,7 @@
     hdr.hScreenSize  = hdr.hres;
     hdr.vScreenSize  = hdr.vres;
 
-    res = (img->width * spec->scaleX);
+    res = img->width * spec->scaleX;
     hdr.bpl = res / 2;
     if (res % 2) hdr.bpl++;
     hdr.bpl *= 2;
@@ -950,7 +950,7 @@
 }
 
 
-static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen)
+static BOOL dmPCXDecodeRLERow(FILE *fp, Uint8 *buf, const size_t bufLen, const int errorMode)
 {
     size_t offs = 0;
     do
@@ -963,8 +963,30 @@
 
         if ((data & 0xC0) == 0xC0)
         {
+            BOOL skip = FALSE;
             count = data & 0x3F;
-            if (!dm_fread_byte(fp, &data))
+            if (count == 0)
+            {
+                switch (errorMode)
+                {
+                    case 1:
+                        // Use as literal
+                        skip = TRUE;
+                        count = 1;
+                        break;
+
+                    case 2:
+                        // Ignore completely
+                        skip = TRUE;
+                        break;
+
+                    default:
+                        // Error out on "invalid" data
+                        return FALSE;
+                }
+            }
+
+            if (!skip && !dm_fread_byte(fp, &data))
                 return FALSE;
         }
         else
@@ -973,6 +995,10 @@
         while (count-- && offs < bufLen)
             buf[offs++] = data;
 
+        // Check for remaining output count, error out if we wish to
+        if (count > 0 && errorMode != 0)
+            return FALSE;
+
     } while (offs < bufLen);
 
     return TRUE;
@@ -1077,7 +1103,7 @@
     for (int yc = 0; yc < img->height; yc++)
     {
         // Decode row of RLE'd data
-        if (!dmPCXDecodeRLERow(fp, pcx.buf, pcx.bufLen))
+        if (!dmPCXDecodeRLERow(fp, pcx.buf, pcx.bufLen, 0))
         {
             res = dmError(DMERR_INVALID_DATA,
                 "PCX: Error decoding RLE compressed data.\n");