]> git.sur5r.net Git - cc65/blobdiff - src/sp65/pcx.c
Removed the flags and optimized the Attr structure.
[cc65] / src / sp65 / pcx.c
index 3a9ccb3b0c8f8bb579e9ede50a2dce43559c27d1..7dc9d9c9b46bb1a2443822c8e8a8c89a2ecaea0a 100644 (file)
@@ -42,6 +42,7 @@
 #include "xmalloc.h"
 
 /* sp65 */
+#include "attr.h"
 #include "error.h"
 #include "fileio.h"
 #include "pcx.h"
@@ -105,6 +106,14 @@ static PCXHeader* NewPCXHeader (void)
 
 
 
+static void FreePCXHeader (PCXHeader* H)
+/* Free a PCX header structure */
+{
+    xfree (H);
+}
+
+
+
 static PCXHeader* ReadPCXHeader (FILE* F, const char* Name)
 /* Read a structured PCX header from the given file and return it */
 {
@@ -235,16 +244,19 @@ static void ReadPlane (FILE* F, PCXHeader* P, unsigned char* L)
 
 
 
-Bitmap* ReadPCXFile (const char* Name)
+Bitmap* ReadPCXFile (const Collection* A)
 /* Read a bitmap from a PCX file */
 {
     PCXHeader* P;
     Bitmap* B;
     unsigned char* L;
     Pixel* Px;
+    unsigned MaxIdx = 0;
     unsigned X, Y;
 
 
+    /* Get the file name */
+    const char* Name = NeedAttrVal (A, "name", "read pcx file");
 
     /* Open the file */
     FILE* F = fopen (Name, "rb");
@@ -271,8 +283,8 @@ Bitmap* ReadPCXFile (const char* Name)
         default:Internal ("Unexpected number of planes");
     }
 
-    /* Remember the PCX header in the tag */
-    B->Tag = P;
+    /* Copy the name */
+    SB_CopyStr (&B->Name, Name);
 
     /* Allocate memory for the scan line */
     L = xmalloc (P->Width);
@@ -313,6 +325,9 @@ Bitmap* ReadPCXFile (const char* Name)
 
                 /* Create pixels */
                 for (X = 0; X < P->Width; ++X, ++Px) {
+                    if (L[X] > MaxIdx) {
+                        MaxIdx = L[X];
+                    }
                     Px->Index = L[X];
                 }
             }
@@ -388,22 +403,26 @@ Bitmap* ReadPCXFile (const char* Name)
                 Error ("Invalid palette marker in PCX file `%s'", Name);
             }
 
-            /* Read the palette */
-            ReadData (F, Palette, sizeof (Palette));
-            Count = 256;
-
         } else if (EndPos == CurPos) {
 
             /* The palette is in the header */
             FileSetPos (F, 16);
-            ReadData (F, Palette, 48);
-            Count = 16;
+
+            /* Check the maximum index for safety */
+            if (MaxIdx > 15) {
+                Error ("PCX file `%s' contains more than 16 indexed colors "
+                       "but no extra palette", Name);
+            }
 
         } else {
             Error ("Error in PCX file `%s': %lu bytes at end of pixel data",
                    Name, EndPos - CurPos);
         }
 
+        /* Read the palette. We will just read what we need. */
+        Count = MaxIdx + 1;
+        ReadData (F, Palette, Count * sizeof (Palette[0]));
+
         /* Create the palette from the data */
         B->Pal = NewPalette (Count);
         for (I = 0; I < Count; ++I) {
@@ -412,11 +431,18 @@ Bitmap* ReadPCXFile (const char* Name)
             B->Pal->Entries[I].B = Palette[I][2];
             B->Pal->Entries[I].A = 0;
         }
+
     }
 
     /* Close the file */
     fclose (F);
 
+    /* Free memory for the scan line */
+    xfree (L);
+
+    /* Free the PCX header */
+    FreePCXHeader (P);
+
     /* Return the bitmap */
     return B;
 }