#include "xmalloc.h"
/* sp65 */
+#include "attr.h"
#include "error.h"
#include "fileio.h"
#include "pcx.h"
+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 */
{
-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");
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);
/* Create pixels */
for (X = 0; X < P->Width; ++X, ++Px) {
+ if (L[X] > MaxIdx) {
+ MaxIdx = L[X];
+ }
Px->Index = L[X];
}
}
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) {
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;
}