Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 95931d60fe986cb88dac43d05c397ef3 > files > 14

gimp-2.2.13-2.0.10.el5.src.rpm

diff -up gimp-2.2.13/plug-ins/common/pcx.c.pcx-endianness gimp-2.2.13/plug-ins/common/pcx.c
--- gimp-2.2.13/plug-ins/common/pcx.c.pcx-endianness	2007-09-10 16:29:33.000000000 +0200
+++ gimp-2.2.13/plug-ins/common/pcx.c	2007-09-10 16:38:41.000000000 +0200
@@ -38,22 +38,6 @@ static void run   (const gchar      *nam
 		   gint             *nreturn_vals,
 		   GimpParam       **return_vals);
 
-#if G_BYTE_ORDER == G_BIG_ENDIAN
-#define qtohl(x) \
-        ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
-                             (((unsigned long int)(x) & 0x0000ff00U) <<  8) | \
-                             (((unsigned long int)(x) & 0x00ff0000U) >>  8) | \
-                             (((unsigned long int)(x) & 0xff000000U) >> 24)))
-#define qtohs(x) \
-        ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
-                              (((unsigned short int)(x) & 0xff00) >> 8)))
-#else
-#define qtohl(x) (x)
-#define qtohs(x) (x)
-#endif
-#define htoql(x) qtohl(x)
-#define htoqs(x) qtohs(x)
-
 GimpPlugInInfo PLUG_IN_INFO =
 {
   NULL,  /* init_proc  */
@@ -129,22 +113,22 @@ static void   load_1     (FILE   *fp,
 			  gint    width,
 			  gint    height,
 			  guchar *buffer,
-			  gint    bytes);
+			  guint16 bytes);
 static void   load_4     (FILE   *fp,
 			  gint    width,
 			  gint    height,
 			  guchar *buffer,
-			  gint    bytes);
+			  guint16 bytes);
 static void   load_8     (FILE   *fp,
 			  gint    width,
 			  gint    height,
 			  guchar *buffer,
-			  gint    bytes);
+			  guint16 bytes);
 static void   load_24    (FILE   *fp,
 			  gint    width,
 			  gint    height,
 			  guchar *buffer,
-			  gint    bytes);
+			  guint16 bytes);
 static void   readline   (FILE   *fp,
 			  guchar *buffer,
 			  gint    bytes);
@@ -273,18 +257,69 @@ static struct
   guint8 version;
   guint8 compression;
   guint8 bpp;
-  gint16 x1, y1;
-  gint16 x2, y2;
-  gint16 hdpi;
-  gint16 vdpi;
+  guint16 x1, y1;
+  guint16 x2, y2;
+  guint16 hdpi;
+  guint16 vdpi;
   guint8 colormap[48];
   guint8 reserved;
   guint8 planes;
-  gint16 bytesperline;
-  gint16 color;
+  guint16 bytesperline;
+  guint16 color;
   guint8 filler[58];
 } pcx_header;
 
+static struct {
+  size_t   size;
+  gpointer address;
+} pcx_header_buf_xlate[] = {
+  { 1,  &pcx_header.manufacturer },
+  { 1,  &pcx_header.version },
+  { 1,  &pcx_header.compression },
+  { 1,  &pcx_header.bpp },
+  { 2,  &pcx_header.x1 },
+  { 2,  &pcx_header.y1 },
+  { 2,  &pcx_header.x2 },
+  { 2,  &pcx_header.y2 },
+  { 2,  &pcx_header.hdpi },
+  { 2,  &pcx_header.vdpi },
+  { 48, &pcx_header.colormap },
+  { 1,  &pcx_header.reserved },
+  { 1,  &pcx_header.planes },
+  { 2,  &pcx_header.bytesperline },
+  { 2,  &pcx_header.color },
+  { 58, &pcx_header.filler },
+  { 0,  NULL }
+};
+
+static void
+pcx_header_from_buffer (const gpointer buf)
+{
+  gint i;
+  gint buf_offset = 0;
+
+  for (i = 0; pcx_header_buf_xlate[i].size != 0; i++)
+    {
+      g_memmove (pcx_header_buf_xlate[i].address, buf + buf_offset,
+                 pcx_header_buf_xlate[i].size);
+      buf_offset += pcx_header_buf_xlate[i].size;
+    }
+}
+
+static void
+pcx_header_to_buffer (const gpointer buf)
+{
+  gint i;
+  gint buf_offset = 0;
+
+  for (i = 0; pcx_header_buf_xlate[i].size != 0; i++)
+    {
+      g_memmove (buf + buf_offset, pcx_header_buf_xlate[i].address,
+                 pcx_header_buf_xlate[i].size);
+      buf_offset += pcx_header_buf_xlate[i].size;
+    }
+}
+
 static gint32
 load_image (const gchar *filename)
 {
@@ -292,9 +327,11 @@ load_image (const gchar *filename)
   GimpDrawable *drawable;
   GimpPixelRgn pixel_rgn;
   gchar *message;
-  gint offset_x, offset_y, height, width;
+  guint16 offset_x, offset_y;
+  gint32 height, width;
   gint32 image, layer;
   guchar *dest, cmap[768];
+  guint8 header_buf[128];
 
   fd = fopen (filename, "rb");
   if (!fd)
@@ -309,13 +346,15 @@ load_image (const gchar *filename)
   gimp_progress_init (message);
   g_free (message);
 
-  if (fread (&pcx_header, 128, 1, fd) == 0)
+  if (fread (header_buf, 128, 1, fd) == 0)
     {
       g_message (_("Could not read header from '%s'"),
                  gimp_filename_to_utf8 (filename));
       return -1;
     }
 
+  pcx_header_from_buffer (header_buf);
+
   if (pcx_header.manufacturer != 10)
     {
       g_message (_("'%s' is not a PCX file"),
@@ -323,10 +362,10 @@ load_image (const gchar *filename)
       return -1;
     }
 
-  offset_x = qtohs (pcx_header.x1);
-  offset_y = qtohs (pcx_header.y1);
-  width = qtohs (pcx_header.x2) - offset_x + 1;
-  height = qtohs (pcx_header.y2) - offset_y + 1;
+  offset_x = GUINT16_FROM_LE (pcx_header.x1);
+  offset_y = GUINT16_FROM_LE (pcx_header.y1);
+  width = GUINT16_FROM_LE (pcx_header.x2) - offset_x + 1;
+  height = GUINT16_FROM_LE (pcx_header.y2) - offset_y + 1;
 
   if ((width < 0) || (width > GIMP_MAX_IMAGE_SIZE))
     {
@@ -338,12 +377,6 @@ load_image (const gchar *filename)
       g_message (_("Unsupported or invalid image height: %d"), height);
       return -1;
     }
-  if (qtohs (pcx_header.bytesperline) <= 0)
-    {
-      g_message (_("Invalid number of bytes per line: %hd"),
-                 qtohs (pcx_header.bytesperline));
-      return -1;
-    }
 
   if (pcx_header.planes == 3 && pcx_header.bpp == 8)
     {
@@ -365,27 +398,31 @@ load_image (const gchar *filename)
   if (pcx_header.planes == 1 && pcx_header.bpp == 1)
     {
       dest = (guchar *) g_malloc (width * height);
-      load_1 (fd, width, height, dest, qtohs (pcx_header.bytesperline));
+      load_1 (fd, width, height, dest,
+              GUINT16_FROM_LE (pcx_header.bytesperline));
       gimp_image_set_colormap (image, mono, 2);
     }
   else if (pcx_header.planes == 4 && pcx_header.bpp == 1)
     {
       dest = (guchar *) g_malloc (width * height);
-      load_4(fd, width, height, dest, qtohs (pcx_header.bytesperline));
+      load_4 (fd, width, height, dest,
+              GUINT16_FROM_LE (pcx_header.bytesperline));
       gimp_image_set_colormap (image, pcx_header.colormap, 16);
     }
   else if (pcx_header.planes == 1 && pcx_header.bpp == 8)
     {
       dest = (guchar *) g_malloc (width * height);
-      load_8(fd, width, height, dest, qtohs (pcx_header.bytesperline));
-      fseek(fd, -768L, SEEK_END);
-      fread(cmap, 768, 1, fd);
+      load_8 (fd, width, height, dest,
+              GUINT16_FROM_LE (pcx_header.bytesperline));
+      fseek (fd, -768L, SEEK_END);
+      fread (cmap, 768, 1, fd);
       gimp_image_set_colormap (image, cmap, 256);
     }
   else if (pcx_header.planes == 3 && pcx_header.bpp == 8)
     {
       dest = (guchar *) g_malloc (width * height * 3);
-      load_24(fd, width, height, dest, qtohs (pcx_header.bytesperline));
+      load_24 (fd, width, height, dest,
+               GUINT16_FROM_LE (pcx_header.bytesperline));
     }
   else
     {
@@ -405,14 +442,14 @@ load_image (const gchar *filename)
 }
 
 static void
-load_8 (FILE   *fp,
-	gint    width,
-	gint    height,
-	guchar *buffer,
-	gint    bytes)
+load_8 (FILE    *fp,
+	gint     width,
+	gint     height,
+	guchar  *buffer,
+	guint16  bytes)
 {
   gint    row;
-  guchar *line= g_new (guchar, bytes);
+  guchar *line = g_new (guchar, bytes);
 
   for (row = 0; row < height; buffer += width, ++row)
     {
@@ -425,14 +462,14 @@ load_8 (FILE   *fp,
 }
 
 static void
-load_24 (FILE   *fp,
-	 gint    width,
-	 gint    height,
-	 guchar *buffer,
-	 gint    bytes)
+load_24 (FILE    *fp,
+	 gint     width,
+	 gint     height,
+	 guchar  *buffer,
+	 guint16  bytes)
 {
   gint    x, y, c;
-  guchar *line= g_new (guchar, bytes);
+  guchar *line = g_new (guchar, bytes);
 
   for (y = 0; y < height; buffer += width * 3, ++y)
     {
@@ -451,11 +488,11 @@ load_24 (FILE   *fp,
 }
 
 static void
-load_1 (FILE   *fp,
-	gint    width,
-	gint    height,
-	guchar *buffer,
-	gint    bytes)
+load_1 (FILE    *fp,
+	gint     width,
+	gint     height,
+	guchar  *buffer,
+	guint16  bytes)
 {
   gint    x, y;
   guchar *line = g_new (guchar, bytes);
@@ -477,18 +514,19 @@ load_1 (FILE   *fp,
 }
 
 static void
-load_4 (FILE   *fp,
-	gint    width,
-	gint    height,
-	guchar *buffer,
-	gint    bytes)
+load_4 (FILE    *fp,
+	gint     width,
+	gint     height,
+	guchar  *buffer,
+	guint16  bytes)
 {
   gint    x, y, c;
-  guchar *line= g_new (guchar, bytes);
+  guchar *line = g_new (guchar, bytes);
 
   for (y = 0; y < height; buffer += width, ++y)
     {
-      for (x = 0; x < width; ++x) buffer[x] = 0;
+      for (x = 0; x < width; ++x)
+        buffer[x] = 0;
       for (c = 0; c < 4; ++c)
 	{
 	  readline(fp, line, bytes);
@@ -548,9 +586,11 @@ save_image (const gchar *filename,
   GimpDrawable *drawable;
   GimpImageType drawable_type;
   guchar *cmap= NULL, *pixels;
-  gint offset_x, offset_y, width, height;
+  gint offset_x, offset_y;
+  guint width, height;
   gchar *message;
   int colors, i;
+  guint8 header_buf[128];
 
   drawable = gimp_drawable_get (layer);
   drawable_type = gimp_drawable_type (layer);
@@ -573,23 +613,23 @@ save_image (const gchar *filename,
     case GIMP_INDEXED_IMAGE:
       cmap = gimp_image_get_colormap (image, &colors);
       pcx_header.bpp = 8;
-      pcx_header.bytesperline = htoqs (width);
+      pcx_header.bytesperline = GUINT16_TO_LE (width);
       pcx_header.planes = 1;
-      pcx_header.color = htoqs (1);
+      pcx_header.color = GUINT16_TO_LE (1);
       break;
 
     case GIMP_RGB_IMAGE:
       pcx_header.bpp = 8;
       pcx_header.planes = 3;
-      pcx_header.color = htoqs (1);
-      pcx_header.bytesperline = htoqs (width);
+      pcx_header.color = GUINT16_TO_LE (1);
+      pcx_header.bytesperline = GUINT16_TO_LE (width);
       break;
 
     case GIMP_GRAY_IMAGE:
       pcx_header.bpp = 8;
       pcx_header.planes = 1;
-      pcx_header.color = htoqs (2);
-      pcx_header.bytesperline = htoqs (width);
+      pcx_header.color = GUINT16_TO_LE (2);
+      pcx_header.bytesperline = GUINT16_TO_LE (width);
       break;
 
     default:
@@ -607,16 +647,44 @@ save_image (const gchar *filename,
   pixels = (guchar *) g_malloc (width * height * pcx_header.planes);
   gimp_pixel_rgn_get_rect (&pixel_rgn, pixels, 0, 0, width, height);
 
-  pcx_header.x1 = htoqs (offset_x);
-  pcx_header.y1 = htoqs (offset_y);
-  pcx_header.x2 = htoqs (offset_x + width - 1);
-  pcx_header.y2 = htoqs (offset_y + height - 1);
+  if ((offset_x < 0) || (offset_x > (1<<16)))
+    {
+      g_message (_("Invalid X offset: %d"), offset_x);
+      return FALSE;
+    }
+
+  if ((offset_y < 0) || (offset_y > (1<<16)))
+    {
+      g_message (_("Invalid Y offset: %d"), offset_y);
+      return FALSE;
+    }
+
+  if (offset_x + width - 1 > (1<<16))
+    {
+      g_message (_("Right border out of bounds (must be < %d): %d"), (1<<16),
+                 offset_x + width - 1);
+      return FALSE;
+    }
+
+  if (offset_y + height - 1 > (1<<16))
+    {
+      g_message (_("Bottom border out of bounds (must be < %d): %d"), (1<<16),
+                 offset_y + height - 1);
+      return FALSE;
+    }
+
+  pcx_header.x1 = GUINT16_TO_LE ((guint16)offset_x);
+  pcx_header.y1 = GUINT16_TO_LE ((guint16)offset_y);
+  pcx_header.x2 = GUINT16_TO_LE ((guint16)(offset_x + width - 1));
+  pcx_header.y2 = GUINT16_TO_LE ((guint16)(offset_y + height - 1));
 
-  pcx_header.hdpi = htoqs (300);
-  pcx_header.vdpi = htoqs (300);
+  pcx_header.hdpi = GUINT16_TO_LE (300);
+  pcx_header.vdpi = GUINT16_TO_LE (300);
   pcx_header.reserved = 0;
 
-  fwrite (&pcx_header, 128, 1, fp);
+  pcx_header_to_buffer (header_buf);
+
+  fwrite (header_buf, 128, 1, fp);
 
   switch (drawable_type)
     {
@@ -626,7 +694,9 @@ save_image (const gchar *filename,
       fwrite (cmap, colors, 3, fp);
       for (i = colors; i < 256; i++)
 	{
-	  fputc (0, fp); fputc (0, fp); fputc (0, fp);
+	  fputc (0, fp);
+          fputc (0, fp);
+          fputc (0, fp);
 	}
       break;
 
@@ -639,7 +709,9 @@ save_image (const gchar *filename,
       fputc (0x0c, fp);
       for (i = 0; i < 256; i++)
 	{
-	  fputc ((guchar) i, fp); fputc ((guchar) i, fp); fputc ((guchar) i, fp);
+	  fputc ((guchar) i, fp);
+          fputc ((guchar) i, fp);
+          fputc ((guchar) i, fp);
 	}
       break;
 
@@ -650,7 +722,12 @@ save_image (const gchar *filename,
   gimp_drawable_detach (drawable);
   g_free (pixels);
 
-  fclose (fp);
+  if (fclose (fp) != 0)
+    {
+      g_message (_("Writing to file '%s' failed: %s"),
+                 gimp_filename_to_utf8 (filename), g_strerror (errno));
+      return FALSE;
+    }
   return TRUE;
 }
 
@@ -676,8 +753,9 @@ save_24 (FILE   *fp,
 	 gint    height,
 	 guchar *buffer)
 {
-  int x, y, c;
+  int     x, y, c;
   guchar *line;
+
   line = (guchar *) g_malloc (width);
 
   for (y = 0; y < height; ++y)
@@ -691,7 +769,7 @@ save_24 (FILE   *fp,
 	  writeline (fp, line, width);
 	}
       buffer += width * 3;
-    gimp_progress_update ((double) y / (double) height);
+      gimp_progress_update ((double) y / (double) height);
     }
   g_free (line);
 }
@@ -701,8 +779,8 @@ writeline (FILE   *fp,
 	   guchar *buffer,
 	   gint    bytes)
 {
-  guchar value, count;
-  guchar *finish = buffer+ bytes;
+  guchar  value, count;
+  guchar *finish = buffer + bytes;
 
   while (buffer < finish)
     {