- /* 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.
- */
+ int width = image->width;
+ int height = image->height;
+ int pcx_depth = pcx->bits_per_pixel * pcx->color_planes;
+ int bytes_per_row = pcx->color_planes * pcx->bytes_per_line;
+ byte *row_buffer = checked_malloc(bytes_per_row);
+ byte *bitmap_ptr = image->data;
+ int y;
+
+ 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 value = 0, count = 0;
+ int value_int;
+ int i;
+
+ for (i = 0; i < bytes_per_row; i++)
+ {
+ 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
+ count = 1;
+ }
+
+ dst_ptr[i] = value;
+ count--;
+
+ if (pcx_depth == 8)
+ image->rgb.color_used[value] = TRUE;
+ }