rnd-20051126-1-src
[rocksndiamonds.git] / src / libgame / pcx.c
index f6ef16c99362e47e7364a173b46e4229395c0785..8bf4d6c1424a2ca62fc61a8ccbfe68ef6ade2111 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Artsoft Retro-Game Library                               *
 *----------------------------------------------------------*
-* (c) 1994-2001 Artsoft Entertainment                      *
+* (c) 1994-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -19,7 +19,7 @@
 #include "misc.h"
 
 
-#define PCX_DEBUG              FALSE
+#define PCX_DEBUG              0
 
 #define PCX_MAGIC              0x0a    /* first byte in a PCX image file    */
 #define PCX_SUPPORTED_VERSION  5       /* last acceptable version number    */
@@ -53,52 +53,6 @@ struct PCX_Header
 /* global PCX error value */
 int errno_pcx = PCX_Success;
 
-#if 0
-static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last)
-{
-  /* Run Length Encoding: If the two high bits are set,
-   * then the low 6 bits contain a repeat count, and the byte to
-   * repeat is the next byte in the file.  If the two high bits are
-   * not set, then this is the byte to write.
-   */
-
-  unsigned int bytes_per_pixel = (image->depth + 7) / 8;
-  register byte *bitmap_ptr, *bitmap_last;
-  register byte value, count;
-
-  bitmap_ptr = image->data;
-  bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel);
-
-  while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last)
-  {
-    value = *buffer_ptr++;
-
-    if ((value & 0xc0) == 0xc0)                /* this is a repeat count byte */
-    {
-      count = value & 0x3f;            /* extract repeat count from byte */
-      value = *buffer_ptr++;           /* next byte is value to repeat */
-
-      for (; count && bitmap_ptr < bitmap_last; count--)
-       *bitmap_ptr++ = value;
-
-      if (count)                       /* repeat count spans end of bitmap */
-       return NULL;
-    }
-    else
-      *bitmap_ptr++ = value;
-
-    image->rgb.color_used[value] = TRUE;
-  }
-
-  /* check if end of buffer was reached before end of bitmap */
-  if (bitmap_ptr < bitmap_last)
-    return NULL;
-
-  /* return current buffer position for next decoding function */
-  return buffer_ptr;
-}
-#endif
-
 static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
 {
   int width = image->width;
@@ -112,7 +66,7 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
   for (y = 0; y < height; y++)
   {
     /* decode a scan line into a temporary buffer first */
-    byte *dst_ptr = (pcx_depth == 8) ? bitmap_ptr : row_buffer;
+    byte *dst_ptr = (pcx_depth == 8 ? bitmap_ptr : row_buffer);
     byte value = 0, count = 0;
     int value_int;
     int i;
@@ -122,14 +76,23 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
       if (count == 0)
       {
        if ((value_int = fgetc(file)) == EOF)
+       {
+         free(row_buffer);
          return FALSE;
+       }
+
        value = (byte)value_int;
 
        if ((value & 0xc0) == 0xc0)     /* this is a repeat count byte */
        {
          count = value & 0x3f;         /* extract repeat count from byte */
+
          if ((value_int = fgetc(file)) == EOF)
+         {
+           free(row_buffer);
            return FALSE;
+         }
+
          value = (byte)value_int;
        }
        else
@@ -152,14 +115,17 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
       {
        int i, j, x = 0;
 
-       for(i = 0; i < pcx->bytes_per_line; i++)
+       for (i = 0; i < pcx->bytes_per_line; i++)
        {
          byte value = *src_ptr++;
 
-         for(j = 7; j >= 0; j--)
+         for (j = 7; j >= 0; j--)
          {
            byte bit = (value >> j) & 1;
 
+           if (i * 8 + j >= width)     /* skip padding bits */
+             continue;
+
            bitmap_ptr[x++] |= bit << plane;
          }
        }
@@ -170,12 +136,12 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
       byte *src_ptr = row_buffer;
       int plane;
 
-      for(plane = 0; plane < pcx->color_planes; plane++)
+      for (plane = 0; plane < pcx->color_planes; plane++)
       {
        int x;
 
        dst_ptr = bitmap_ptr + plane;
-       for(x = 0; x < width; x++)
+       for (x = 0; x < width; x++)
        {
          *dst_ptr = *src_ptr++;
          dst_ptr += pcx->color_planes;
@@ -186,37 +152,10 @@ static boolean PCX_ReadBitmap(FILE *file, struct PCX_Header *pcx, Image *image)
     bitmap_ptr += image->bytes_per_row;
   }
 
-  return TRUE;
-}
-
-#if 0
-static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last)
-{
-  int i, magic;
-
-  /* read colormap magic byte */
-  magic = *buffer_ptr++;
-
-  /* check magic colormap header byte */
-  if (magic != PCX_256COLORS_MAGIC)
-    return NULL;
-
-  /* check if enough bytes left for a complete colormap */
-  if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last)
-    return NULL;
-
-  /* read 256 colors from PCX colormap */
-  for (i=0; i<PCX_MAXCOLORS; i++)
-  {
-    image->rgb.red[i]   = *buffer_ptr++ << 8;
-    image->rgb.green[i] = *buffer_ptr++ << 8;
-    image->rgb.blue[i]  = *buffer_ptr++ << 8;
-  }
+  free(row_buffer);
 
-  /* return current buffer position for next decoding function */
-  return buffer_ptr;
+  return TRUE;
 }
-#endif
 
 static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image)
 {
@@ -242,7 +181,7 @@ static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image)
     while (value != PCX_256COLORS_MAGIC);
 
     /* read 256 colors from PCX colormap */
-    for(i = 0; i < PCX_MAXCOLORS; i++)
+    for (i = 0; i < PCX_MAXCOLORS; i++)
     {
       image->rgb.red[i]   = (byte)fgetc(file) << 8;
       image->rgb.green[i] = (byte)fgetc(file) << 8;
@@ -251,7 +190,7 @@ static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image)
   }
   else
   {
-    for(i = 0; i < num_colors; i++)
+    for (i = 0; i < num_colors; i++)
     {
       image->rgb.red[i]   = pcx->palette[i][0] << 8;
       image->rgb.green[i] = pcx->palette[i][1] << 8;
@@ -321,6 +260,7 @@ Image *Read_PCX_to_Image(char *filename)
 #if PCX_DEBUG
   if (options.verbose)
   {
+    printf("\n");
     printf("%s is a %dx%d PC Paintbrush image\n", filename, width, height);
     printf("depth: %d\n", depth);
     printf("bits_per_pixel: %d\n", pcx.bits_per_pixel);
@@ -360,15 +300,14 @@ Image *Read_PCX_to_Image(char *filename)
   if (pcx_depth == 8)
   {
     /* determine number of used colormap entries for 8-bit PCX images */
-    image->rgb.used = 0;
-    for (i=0; i<PCX_MAXCOLORS; i++)
+    for (i = 0; i < PCX_MAXCOLORS; i++)
       if (image->rgb.color_used[i])
        image->rgb.used++;
   }
 
 #if PCX_DEBUG
   if (options.verbose)
-    printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used);
+    printf("Read_PCX_to_Image: %d colors in colormap\n", image->rgb.used);
 #endif
 
   return image;