]> granicus.if.org Git - imagemagick/blobdiff - coders/pcx.c
(no commit message)
[imagemagick] / coders / pcx.c
index e8d9851153b826a67ddd4f7e3c3fb9071c5e7a2c..f8f8356bb5a8b7f22de6240b3637e457e5f6181f 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
@@ -45,6 +45,7 @@
 #include "magick/cache.h"
 #include "magick/color.h"
 #include "magick/color-private.h"
+#include "magick/colormap.h"
 #include "magick/colorspace.h"
 #include "magick/exception.h"
 #include "magick/exception-private.h"
@@ -196,7 +197,7 @@ static MagickBooleanType IsPCX(const unsigned char *magick,const size_t length)
 %
 */
 
-static inline long MagickAbsoluteValue(const long x)
+static inline ssize_t MagickAbsoluteValue(const ssize_t x)
 {
   if (x < 0)
     return(-x);
@@ -227,7 +228,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     id,
     mask;
 
-  long
+  ssize_t
     y;
 
   MagickBooleanType
@@ -243,13 +244,13 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
   register IndexPacket
     *indexes;
 
-  register long
+  register ssize_t
     x;
 
   register PixelPacket
     *q;
 
-  register long
+  register ssize_t
     i;
 
   register unsigned char
@@ -265,7 +266,8 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     *pcx_pixels,
     *scanline;
 
-  unsigned long
+  size_t
+    one,
     pcx_packets;
 
   /*
@@ -291,7 +293,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
   page_table=(MagickOffsetType *) NULL;
   if (LocaleCompare(image_info->magick,"DCX") == 0)
     {
-      unsigned long
+      size_t
         magic;
 
       /*
@@ -338,9 +340,9 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     /*
       Read PCX raster colormap.
     */
-    image->columns=(unsigned long) MagickAbsoluteValue((long) pcx_info.right-
+    image->columns=(size_t) MagickAbsoluteValue((ssize_t) pcx_info.right-
       pcx_info.left)+1UL;
-    image->rows=(unsigned long) MagickAbsoluteValue((long) pcx_info.bottom-
+    image->rows=(size_t) MagickAbsoluteValue((ssize_t) pcx_info.bottom-
       pcx_info.top)+1UL;
     if ((image->columns == 0) || (image->rows == 0) ||
         (pcx_info.bits_per_pixel == 0))
@@ -357,17 +359,18 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     count=ReadBlob(image,3*image->colors,pcx_colormap);
     pcx_info.reserved=(unsigned char) ReadBlobByte(image);
     pcx_info.planes=(unsigned char) ReadBlobByte(image);
+    one=1;
     if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1))
       if ((pcx_info.version == 3) || (pcx_info.version == 5) ||
           ((pcx_info.bits_per_pixel*pcx_info.planes) == 1))
-        image->colors=(unsigned long) MagickMin(1UL << (1UL*
+        image->colors=(size_t) MagickMin(one << (1UL*
           (pcx_info.bits_per_pixel*pcx_info.planes)),256UL);
     if (AcquireImageColormap(image,image->colors) == MagickFalse)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1))
       image->storage_class=DirectClass;
     p=pcx_colormap;
-    for (i=0; i < (long) image->colors; i++)
+    for (i=0; i < (ssize_t) image->colors; i++)
     {
       image->colormap[i].red=ScaleCharToQuantum(*p++);
       image->colormap[i].green=ScaleCharToQuantum(*p++);
@@ -383,7 +386,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     /*
       Read image data.
     */
-    pcx_packets=(unsigned long) image->rows*pcx_info.bytes_per_line*
+    pcx_packets=(size_t) image->rows*pcx_info.bytes_per_line*
       pcx_info.planes;
     pcx_pixels=(unsigned char *) AcquireQuantumMemory(pcx_packets,
       sizeof(*pcx_pixels));
@@ -461,7 +464,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 pcx_info.colormap_signature=(unsigned char) ReadBlobByte(image);
                 count=ReadBlob(image,3*image->colors,pcx_colormap);
                 p=pcx_colormap;
-                for (i=0; i < (long) image->colors; i++)
+                for (i=0; i < (ssize_t) image->colors; i++)
                 {
                   image->colormap[i].red=ScaleCharToQuantum(*p++);
                   image->colormap[i].green=ScaleCharToQuantum(*p++);
@@ -473,7 +476,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
     /*
       Convert PCX raster image to pixel packets.
     */
-    for (y=0; y < (long) image->rows; y++)
+    for (y=0; y < (ssize_t) image->rows; y++)
     {
       p=pcx_pixels+(y*pcx_info.bytes_per_line*pcx_info.planes);
       q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
@@ -485,7 +488,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
         for (i=0; i < pcx_info.planes; i++)
         {
           r=scanline+i;
-          for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+          for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++)
           {
             switch (i)
             {
@@ -517,12 +520,12 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
       else
         if (pcx_info.planes > 1)
           {
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
               *r++=0;
             for (i=0; i < pcx_info.planes; i++)
             {
               r=scanline;
-              for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+              for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++)
               {
                  bits=(*p++);
                  for (mask=0x80; mask != 0; mask>>=1)
@@ -539,10 +542,10 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
           {
             case 1:
             {
-              register long
+              register ssize_t
                 bit;
 
-              for (x=0; x < ((long) image->columns-7); x+=8)
+              for (x=0; x < ((ssize_t) image->columns-7); x+=8)
               {
                 for (bit=7; bit >= 0; bit--)
                   *r++=(unsigned char) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
@@ -550,7 +553,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
               }
               if ((image->columns % 8) != 0)
                 {
-                  for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
+                  for (bit=7; bit >= (ssize_t) (8-(image->columns % 8)); bit--)
                     *r++=(unsigned char) ((*p) & (0x01 << bit) ? 0x01 : 0x00);
                   p++;
                 }
@@ -558,7 +561,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
             }
             case 2:
             {
-              for (x=0; x < ((long) image->columns-3); x+=4)
+              for (x=0; x < ((ssize_t) image->columns-3); x+=4)
               {
                 *r++=(*p >> 6) & 0x3;
                 *r++=(*p >> 4) & 0x3;
@@ -568,7 +571,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
               }
               if ((image->columns % 4) != 0)
                 {
-                  for (i=3; i >= (long) (4-(image->columns % 4)); i--)
+                  for (i=3; i >= (ssize_t) (4-(image->columns % 4)); i--)
                     *r++=(unsigned char) ((*p >> (i*2)) & 0x03);
                   p++;
                 }
@@ -576,7 +579,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
             }
             case 4:
             {
-              for (x=0; x < ((long) image->columns-1); x+=2)
+              for (x=0; x < ((ssize_t) image->columns-1); x+=2)
               {
                 *r++=(*p >> 4) & 0xf;
                 *r++=(*p) & 0xf;
@@ -598,7 +601,7 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
         Transfer image scanline.
       */
       r=scanline;
-      for (x=0; x < (long) image->columns; x++)
+      for (x=0; x < (ssize_t) image->columns; x++)
       {
         if (image->storage_class == PseudoClass)
           indexes[x]=(IndexPacket) (*r++);
@@ -616,7 +619,8 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
         break;
       if (image->previous == (Image *) NULL)
         {
-          status=SetImageProgress(image,LoadImageTag,y,image->rows);
+          status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
+                image->rows);
           if (status == MagickFalse)
             break;
         }
@@ -691,10 +695,10 @@ static Image *ReadPCXImage(const ImageInfo *image_info,ExceptionInfo *exception)
 %
 %  The format of the RegisterPCXImage method is:
 %
-%      unsigned long RegisterPCXImage(void)
+%      size_t RegisterPCXImage(void)
 %
 */
-ModuleExport unsigned long RegisterPCXImage(void)
+ModuleExport size_t RegisterPCXImage(void)
 {
   MagickInfo
     *entry;
@@ -776,7 +780,7 @@ static MagickBooleanType PCXWritePixels(PCXInfo *pcx_info,
   register const unsigned char
     *q;
 
-  register long
+  register ssize_t
     i,
     x;
 
@@ -788,40 +792,48 @@ static MagickBooleanType PCXWritePixels(PCXInfo *pcx_info,
     previous;
 
   q=pixels;
-  for (i=0; i < (long) pcx_info->planes; i++)
+  for (i=0; i < (ssize_t) pcx_info->planes; i++)
   {
-    previous=(*q++);
-    count=1;
-    for (x=0; x < (long) (pcx_info->bytes_per_line-1); x++)
-    {
-      packet=(*q++);
-      if ((packet == previous) && (count < 63))
-        {
-          count++;
-          continue;
-        }
-      if ((count > 1) || ((previous & 0xc0) == 0xc0))
+    if (pcx_info->encoding == 0)
+      {
+        for (x=0; x < (ssize_t) pcx_info->bytes_per_line; x++)
+          (void) WriteBlobByte(image,(unsigned char) (*q++));
+      }
+    else
+      {
+        previous=(*q++);
+        count=1;
+        for (x=0; x < (ssize_t) (pcx_info->bytes_per_line-1); x++)
         {
-          count|=0xc0;
-          (void) WriteBlobByte(image,(unsigned char) count);
+          packet=(*q++);
+          if ((packet == previous) && (count < 63))
+            {
+              count++;
+              continue;
+            }
+          if ((count > 1) || ((previous & 0xc0) == 0xc0))
+            {
+              count|=0xc0;
+              (void) WriteBlobByte(image,(unsigned char) count);
+            }
+          (void) WriteBlobByte(image,previous);
+          previous=packet;
+          count=1;
         }
-      (void) WriteBlobByte(image,previous);
-      previous=packet;
-      count=1;
-    }
-    if ((count > 1) || ((previous & 0xc0) == 0xc0))
-      {
-        count|=0xc0;
-        (void) WriteBlobByte(image,(unsigned char) count);
+        if ((count > 1) || ((previous & 0xc0) == 0xc0))
+          {
+            count|=0xc0;
+            (void) WriteBlobByte(image,(unsigned char) count);
+          }
+        (void) WriteBlobByte(image,previous);
       }
-    (void) WriteBlobByte(image,previous);
   }
   return (MagickTrue);
 }
 
 static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
 {
-  long
+  ssize_t
     y;
 
   MagickBooleanType
@@ -841,7 +853,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
   register const PixelPacket
     *p;
 
-  register long
+  register ssize_t
     i,
     x;
 
@@ -895,7 +907,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
     */
     pcx_info.identifier=0x0a;
     pcx_info.version=5;
-    pcx_info.encoding=1;
+    pcx_info.encoding=image_info->compression == NoCompression ? 0 : 1;
     pcx_info.bits_per_pixel=8;
     if ((image->storage_class == PseudoClass) &&
         (IsMonochromeImage(image,&image->exception) != MagickFalse))
@@ -931,7 +943,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
         if (image->matte != MagickFalse)
           pcx_info.planes++;
       }
-    pcx_info.bytes_per_line=(unsigned short) (((unsigned long) image->columns*
+    pcx_info.bytes_per_line=(unsigned short) (((size_t) image->columns*
       pcx_info.bits_per_pixel+7)/8);
     pcx_info.palette_info=1;
     pcx_info.colormap_signature=0x0c;
@@ -958,7 +970,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
     (void) memset(pcx_colormap,0,3*256*sizeof(*pcx_colormap));
     q=pcx_colormap;
     if ((image->storage_class == PseudoClass) && (image->colors <= 256))
-      for (i=0; i < (long) image->colors; i++)
+      for (i=0; i < (ssize_t) image->colors; i++)
       {
         *q++=ScaleQuantumToChar(image->colormap[i].red);
         *q++=ScaleQuantumToChar(image->colormap[i].green);
@@ -972,8 +984,8 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
     for (i=0; i < 58; i++)
       (void) WriteBlobByte(image,'\0');
     length=(size_t) pcx_info.bytes_per_line;
-    pcx_pixels=(unsigned char *) AcquireQuantumMemory(length,
-      pcx_info.planes*sizeof(*pcx_pixels));
+    pcx_pixels=(unsigned char *) AcquireQuantumMemory(length,pcx_info.planes*
+      sizeof(*pcx_pixels));
     if (pcx_pixels == (unsigned char *) NULL)
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
     q=pcx_pixels;
@@ -985,7 +997,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
         /*
           Convert DirectClass image to PCX raster pixels.
         */
-        for (y=0; y < (long) image->rows; y++)
+        for (y=0; y < (ssize_t) image->rows; y++)
         {
           pixels=GetVirtualPixels(image,0,y,image->columns,1,
             &image->exception);
@@ -999,7 +1011,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
             {
               case 0:
               {
-                for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+                for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++)
                 {
                   *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
                   p++;
@@ -1008,7 +1020,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
               }
               case 1:
               {
-                for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+                for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++)
                 {
                   *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
                   p++;
@@ -1017,7 +1029,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
               }
               case 2:
               {
-                for (x=0; x < (long) pcx_info.bytes_per_line; x++)
+                for (x=0; x < (ssize_t) pcx_info.bytes_per_line; x++)
                 {
                   *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
                   p++;
@@ -1027,9 +1039,10 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
               case 3:
               default:
               {
-                for (x=(long) pcx_info.bytes_per_line; x != 0; x--)
+                for (x=(ssize_t) pcx_info.bytes_per_line; x != 0; x--)
                 {
-                  *q++=ScaleQuantumToChar((Quantum) (QuantumRange-GetOpacityPixelComponent(p)));
+                  *q++=ScaleQuantumToChar((Quantum)
+                    (GetAlphaPixelComponent(p)));
                   p++;
                 }
                 break;
@@ -1040,7 +1053,8 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
             break;
           if (image->previous == (Image *) NULL)
             {
-              status=SetImageProgress(image,SaveImageTag,y,image->rows);
+              status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+                image->rows);
               if (status == MagickFalse)
                 break;
             }
@@ -1049,20 +1063,21 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
     else
       {
         if (pcx_info.bits_per_pixel > 1)
-          for (y=0; y < (long) image->rows; y++)
+          for (y=0; y < (ssize_t) image->rows; y++)
           {
             p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
             if (p == (const PixelPacket *) NULL)
               break;
             indexes=GetVirtualIndexQueue(image);
             q=pcx_pixels;
-            for (x=0; x < (long) image->columns; x++)
+            for (x=0; x < (ssize_t) image->columns; x++)
               *q++=(unsigned char) indexes[x];
             if (PCXWritePixels(&pcx_info,pcx_pixels,image) == MagickFalse)
               break;
             if (image->previous == (Image *) NULL)
               {
-                status=SetImageProgress(image,SaveImageTag,y,image->rows);
+                status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
+                image->rows);
                 if (status == MagickFalse)
                   break;
               }
@@ -1085,7 +1100,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
               polarity=(IndexPacket) (
                 PixelIntensityToQuantum(&image->colormap[0]) <
                 PixelIntensityToQuantum(&image->colormap[1]) ? 1 : 0);
-            for (y=0; y < (long) image->rows; y++)
+            for (y=0; y < (ssize_t) image->rows; y++)
             {
               p=GetVirtualPixels(image,0,y,image->columns,1,
                 &image->exception);
@@ -1095,7 +1110,7 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
               bit=0;
               byte=0;
               q=pcx_pixels;
-              for (x=0; x < (long) image->columns; x++)
+              for (x=0; x < (ssize_t) image->columns; x++)
               {
                 byte<<=1;
                 if (indexes[x] == polarity)
@@ -1115,7 +1130,8 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
                 break;
               if (image->previous == (Image *) NULL)
                 {
-                  status=SetImageProgress(image,SaveImageTag,y,image->rows);
+                  status=SetImageProgress(image,SaveImageTag,(MagickOffsetType)
+                    y,image->rows);
                   if (status == MagickFalse)
                     break;
                 }
@@ -1126,6 +1142,10 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
       }
     pcx_pixels=(unsigned char *) RelinquishMagickMemory(pcx_pixels);
     pcx_colormap=(unsigned char *) RelinquishMagickMemory(pcx_colormap);
+    if (page_table == (MagickOffsetType *) NULL)
+      break;
+    if (scene >= 1023)
+      break;
     if (GetNextImageInList(image) == (Image *) NULL)
       break;
     image=SyncNextImageInList(image);
@@ -1133,8 +1153,6 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
       GetImageListLength(image));
     if (status == MagickFalse)
       break;
-    if (scene >= 1023)
-      break;
   } while (image_info->adjoin != MagickFalse);
   if (page_table != (MagickOffsetType *) NULL)
     {
@@ -1146,8 +1164,8 @@ static MagickBooleanType WritePCXImage(const ImageInfo *image_info,Image *image)
       if (offset < 0)
         ThrowWriterException(CorruptImageError,"ImproperImageHeader");
       (void) WriteBlobLSBLong(image,0x3ADE68B1L);
-      for (i=0; i <= (long) scene; i++)
-        (void) WriteBlobLSBLong(image,(unsigned long) page_table[i]);
+      for (i=0; i <= (ssize_t) scene; i++)
+        (void) WriteBlobLSBLong(image,(unsigned int) page_table[i]);
       page_table=(MagickOffsetType *) RelinquishMagickMemory(page_table);
     }
   if (status == MagickFalse)