GraphicsMagick: SUN: Sense of monochrome images was inverted. F...

GraphicsMagick Commits <[email protected]>
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.37554.1672418567.1459.graphicsmagick-commit@lists.sourceforge.net>
changeset d336319f317c in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=d336319f317c
summary: SUN: Sense of monochrome images was inverted.  Fix scanline size calculation.

diffstat:

 ChangeLog                              |    6 +
 PerlMagick/t/read.t                    |    2 +-
 PerlMagick/t/write.t                   |    2 +-
 VisualMagick/installer/inc/version.isx |    4 +-
 coders/sun.c                           |  417 +++++++++++++++++---------------
 magick/version.h                       |    4 +-
 www/Changelog.html                     |    8 +
 7 files changed, 244 insertions(+), 199 deletions(-)

diffs (truncated from 663 to 500 lines):

diff -r aed8f9cb12c1 -r d336319f317c ChangeLog
--- a/ChangeLog	Thu Dec 29 15:02:42 2022 -0600
+++ b/ChangeLog	Fri Dec 30 10:42:37 2022 -0600
@@ -1,3 +1,9 @@
+2022-12-30  Bob Friesenhahn  <[email protected]>
+
+	* coders/sun.c (ReadSUNImage): Sense of monochrome images was
+	inverted.  Fix scanline size calculation.
+	(WriteSUNImage): Sense of monochrome images was inverted.
+
 2022-12-29  Bob Friesenhahn  <[email protected]>
 
 	* coders/pcx.c (WritePCXImage): Fix heap overflow when writing
diff -r aed8f9cb12c1 -r d336319f317c PerlMagick/t/read.t
--- a/PerlMagick/t/read.t	Thu Dec 29 15:02:42 2022 -0600
+++ b/PerlMagick/t/read.t	Fri Dec 30 10:42:37 2022 -0600
@@ -288,7 +288,7 @@
 print("SUN 1-bit Rasterfile ...\n");
 ++$test;
 testRead('input.im1', q//,
-         '615fa1d8bae486118b3733c1dba4e2a225fc1f4f8ff9441bcb7c3293753e4da1');
+         '86cf46ab9d620aa85eba722d777cc97e30df51916b2380df3cbc2685614d1222');
 
 print("SUN 8-bit Rasterfile ...\n");
 ++$test;
diff -r aed8f9cb12c1 -r d336319f317c PerlMagick/t/write.t
--- a/PerlMagick/t/write.t	Thu Dec 29 15:02:42 2022 -0600
+++ b/PerlMagick/t/write.t	Fri Dec 30 10:42:37 2022 -0600
@@ -179,7 +179,7 @@
 testReadWrite( 'SUN:input.im1',
   'SUN:output.im1',
   q//,
-  '615fa1d8bae486118b3733c1dba4e2a225fc1f4f8ff9441bcb7c3293753e4da1');
+  '86cf46ab9d620aa85eba722d777cc97e30df51916b2380df3cbc2685614d1222');
 
 print("SUN 8-bit Rasterfile ...\n");
 ++$test;
diff -r aed8f9cb12c1 -r d336319f317c VisualMagick/installer/inc/version.isx
--- a/VisualMagick/installer/inc/version.isx	Thu Dec 29 15:02:42 2022 -0600
+++ b/VisualMagick/installer/inc/version.isx	Fri Dec 30 10:42:37 2022 -0600
@@ -10,5 +10,5 @@
 
 #define public MagickPackageName "GraphicsMagick"
 #define public MagickPackageVersion "1.4"
-#define public MagickPackageVersionAddendum ".020221229"
-#define public MagickPackageReleaseDate "snapshot-20221229"
+#define public MagickPackageVersionAddendum ".020221230"
+#define public MagickPackageReleaseDate "snapshot-20221230"
diff -r aed8f9cb12c1 -r d336319f317c coders/sun.c
--- a/coders/sun.c	Thu Dec 29 15:02:42 2022 -0600
+++ b/coders/sun.c	Fri Dec 30 10:42:37 2022 -0600
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2003-2020 GraphicsMagick Group
+% Copyright (C) 2003-2022 GraphicsMagick Group
 % Copyright (C) 2002 ImageMagick Studio
 % Copyright 1991-1999 E. I. du Pont de Nemours and Company
 %
@@ -318,6 +318,9 @@
   unsigned int
     status;
 
+  MagickBool
+    logging;
+
   /*
     Open image file.
   */
@@ -326,6 +329,7 @@
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
   image=AllocateImage(image_info);
+  logging=image->logging;
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == False)
     ThrowReaderException(FileOpenError,UnableToOpenFile,image);
@@ -348,10 +352,18 @@
     sun_info.type=ReadBlobMSBLong(image);
     sun_info.maptype=ReadBlobMSBLong(image);
     sun_info.maplength=ReadBlobMSBLong(image);
-    LogSUNInfo(&sun_info);
+    if (logging)
+      LogSUNInfo(&sun_info);
     if (EOFBlob(image))
       ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
     /*
+      Verify that width, height, depth, and length are not zero
+    */
+    if ((sun_info.width == 0) || (sun_info.height == 0) ||
+        (sun_info.depth == 0) || (sun_info.length == 0))
+      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+
+    /*
       Verify that header values are in positive numeric range of a
       32-bit 'int' even though we store them in an unsigned value.
     */
@@ -397,9 +409,9 @@
       {
         image->colors=sun_info.maplength;
         if (sun_info.maptype == RMT_NONE)
-          image->colors=1 << sun_info.depth;
+          image->colors=1U << sun_info.depth;
         if (sun_info.maptype == RMT_EQUAL_RGB)
-          image->colors=sun_info.maplength/3;
+          image->colors=sun_info.maplength/3U;
       }
 
     switch (sun_info.maptype)
@@ -510,23 +522,18 @@
 
       "The width of a scan line is always 16-bits, padded when necessary."
     */
-    bytes_per_line=MagickArraySize(sun_info.width,sun_info.depth)/8;
-    if ((bytes_per_line != 0) && (sun_info.depth == 1))
-      bytes_per_line += sun_info.width % 8 ? 1 : 0;
-    if (bytes_per_line != 0)
-      bytes_per_line=RoundUpToAlignment(bytes_per_line,2);
-
-    bytes_per_image=MagickArraySize(sun_info.height,bytes_per_line);
-
+    bytes_per_line=MagickArraySize(sun_info.width,sun_info.depth);
     if (bytes_per_line == 0)
       ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
 
-    if (bytes_per_image == 0)
+    bytes_per_line += sun_info.depth == 1 ? 15U : 7U; /* Pad */
+    bytes_per_line /= 8U;
+    if (bytes_per_line == 0)
       ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
 
-    if ((sun_info.type == RT_STANDARD) || (sun_info.type == RT_FORMAT_RGB))
-      if (bytes_per_image > sun_info.length)
-        ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
+    bytes_per_image=MagickArraySize(sun_info.height,bytes_per_line);
+    if (bytes_per_image == 0)
+      ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
 
     if (sun_info.type == RT_ENCODED)
       sun_data_length=(size_t) sun_info.length;
@@ -539,9 +546,7 @@
     if (sun_info.type == RT_ENCODED)
       {
         if (sun_data_length < bytes_per_image/255U)
-          {
-            ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
-          }
+          ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
       }
     if (BlobIsSeekable(image))
       {
@@ -553,18 +558,21 @@
         {
           const magick_off_t remaining = file_size-current_offset;
 
-          if ((remaining == 0) || (remaining < (magick_off_t) sun_data_length))
+          if ((remaining == 0) || (remaining < (magick_off_t) sun_info.length))
             {
               ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image);
             }
         }
       }
 
-    sun_data=MagickAllocateResourceLimitedMemory(unsigned char *,sun_data_length);
+    /*
+      Read raster data into allocated buffer.
+    */
+    sun_data=MagickAllocateResourceLimitedMemory(unsigned char *,sun_info.length);
     if (sun_data == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image);
-    if ((count=ReadBlob(image,sun_data_length,(char *) sun_data))
-        != sun_data_length)
+    if ((count=ReadBlob(image,sun_info.length,(char *) sun_data))
+        != sun_info.length)
       {
         MagickFreeResourceLimitedMemory(sun_data);
         ThrowReaderException(CorruptImageError,UnableToReadImageData,image);
@@ -608,7 +616,7 @@
         {
           for (bit=7; bit >= 0; bit--)
             {
-              index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+              index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
               VerifyColormapIndex(image,index);
               indexes[x+7-bit]=index;
               q[x+7-bit]=image->colormap[index];
@@ -619,7 +627,7 @@
           {
             for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
               {
-                index=((*p) & (0x01 << bit) ? 0x01 : 0x00);
+                index=((*p) & (0x01 << bit) ? 0x00 : 0x01);
                 VerifyColormapIndex(image,index);
                 indexes[x+7-bit]=index;
                 q[x+7-bit]=image->colormap[index];
@@ -862,6 +870,9 @@
   register const IndexPacket
     *indexes;
 
+  size_t
+    number_pixels;
+
   register long
     x;
 
@@ -875,12 +886,14 @@
     status;
 
   unsigned long
-    number_pixels,
     scene;
 
   size_t
     image_list_length;
 
+  MagickBool
+    logging;
+
   /*
     Open output image file.
   */
@@ -889,50 +902,42 @@
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   image_list_length=GetImageListLength(image);
+  logging=image->logging;
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
   if (status == False)
     ThrowWriterException(FileOpenError,UnableToOpenFile,image);
   scene=0;
   do
-  {
-    ImageCharacteristics
-      characteristics;
+    {
+      ImageCharacteristics
+        characteristics;
 
-    /*
-      Ensure that image is in an RGB space.
-    */
-    (void) TransformColorspace(image,RGBColorspace);
-    /*
-      Analyze image to be written.
-    */
-    if (!GetImageCharacteristics(image,&characteristics,
-                                 (OptimizeType == image_info->type),
-                                 &image->exception))
-      {
-        CloseBlob(image);
-        return MagickFail;
-      }
-    /*
-      Initialize SUN raster file header.
-    */
-    sun_info.magic=0x59a66a95;
-    sun_info.width=image->columns;
-    sun_info.height=image->rows;
-    sun_info.type=
-      (image->storage_class == DirectClass ? RT_FORMAT_RGB : RT_STANDARD);
-    sun_info.maptype=RMT_NONE;
-    sun_info.maplength=0;
-    number_pixels=image->columns*image->rows;
-    if (image->storage_class == DirectClass)
-      {
-        /*
-          Full color SUN raster.
-        */
-        sun_info.depth=(image->matte ? 32U : 24U);
-        sun_info.length=(image->matte ? 4U : 3U)*number_pixels;
-        sun_info.length+=image->columns & 0x01U ? image->rows : 0U;
-      }
-    else
+      /*
+        Ensure that image is in an RGB space.
+      */
+      (void) TransformColorspace(image,RGBColorspace);
+      /*
+        Analyze image to be written.
+      */
+      if (!GetImageCharacteristics(image,&characteristics,
+                                   (OptimizeType == image_info->type),
+                                   &image->exception))
+        {
+          CloseBlob(image);
+          return MagickFail;
+        }
+      /*
+        Initialize SUN raster file header.
+      */
+      sun_info.magic=0x59a66a95;
+      sun_info.width=image->columns;
+      sun_info.height=image->rows;
+      sun_info.type=
+        (image->storage_class == DirectClass ? RT_FORMAT_RGB : RT_STANDARD);
+      sun_info.maptype=RMT_NONE;
+      sun_info.maplength=0;
+      number_pixels=MagickArraySize(image->columns,image->rows);
+
       if (characteristics.monochrome)
         {
           /*
@@ -943,7 +948,7 @@
           sun_info.length+=((image->columns/8U)+(image->columns % 8U ? 1U : 0U)) %
             2U ? image->rows : 0U;
         }
-      else
+      else if (characteristics.palette)
         {
           /*
             Colormapped SUN raster.
@@ -954,79 +959,38 @@
           sun_info.maptype=RMT_EQUAL_RGB;
           sun_info.maplength=image->colors*3;
         }
-    /*
-      Write SUN header.
-    */
-    LogSUNInfo(&sun_info);
-    (void) WriteBlobMSBLong(image,sun_info.magic);
-    (void) WriteBlobMSBLong(image,sun_info.width);
-    (void) WriteBlobMSBLong(image,sun_info.height);
-    (void) WriteBlobMSBLong(image,sun_info.depth);
-    (void) WriteBlobMSBLong(image,sun_info.length);
-    (void) WriteBlobMSBLong(image,sun_info.type);
-    (void) WriteBlobMSBLong(image,sun_info.maptype);
-    (void) WriteBlobMSBLong(image,sun_info.maplength);
-    /*
-      Convert MIFF to SUN raster pixels.
-    */
-    x=0;
-    y=0;
-    if (image->storage_class == DirectClass)
-      {
-        register unsigned char
-          *q;
-
-        size_t
-          length,
-          pad;
-
-        unsigned char
-          *pixels;
-
-        /*
-          Allocate memory for pixels.
+      else
+        {
+          /*
+            Full color SUN raster.
+          */
+          sun_info.depth=(image->matte ? 32U : 24U);
+          sun_info.length=(image->matte ? 4U : 3U)*number_pixels;
+          sun_info.length+=image->columns & 0x01U ? image->rows : 0U;
+        }
 
-          Scanlines are padded to 16-bit boundary so account for padding.
-        */
-        pad=(image->columns & 0x01 ? 1 : 0);
-        length=(image->columns + pad) *sizeof(PixelPacket);
-        pixels=MagickAllocateResourceLimitedMemory(unsigned char *,length);
-        if (pixels == (unsigned char *) NULL)
-          ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,
-            image);
-        /*
-          Convert DirectClass packet to SUN RGB pixel.
-        */
-        for (y=0; y < (long) image->rows; y++)
-        {
-          p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
-          if (p == (const PixelPacket *) NULL)
-            break;
-          q=pixels;
-          for (x=0; x < (long) image->columns; x++)
-          {
-            if (image->matte)
-              *q++=ScaleQuantumToChar(MaxRGB-p->opacity);
-            *q++=ScaleQuantumToChar(p->red);
-            *q++=ScaleQuantumToChar(p->green);
-            *q++=ScaleQuantumToChar(p->blue);
-            p++;
-          }
-          if (image->columns & 0x01)
-            *q++=0;  /* pad scanline */
-          (void) WriteBlob(image,q-pixels,(char *) pixels);
-          if (image->previous == (Image *) NULL)
-            if (QuantumTick(y,image->rows))
-              if (!MagickMonitorFormatted(y,image->rows,&image->exception,
-                                          SaveImageText,image->filename,
-                                          image->columns,image->rows))
-                break;
-        }
-        MagickFreeResourceLimitedMemory(pixels);
-      }
-    else
+      /*
+        Write SUN header.
+      */
+      LogSUNInfo(&sun_info);
+      (void) WriteBlobMSBLong(image,sun_info.magic);
+      (void) WriteBlobMSBLong(image,sun_info.width);
+      (void) WriteBlobMSBLong(image,sun_info.height);
+      (void) WriteBlobMSBLong(image,sun_info.depth);
+      (void) WriteBlobMSBLong(image,sun_info.length);
+      (void) WriteBlobMSBLong(image,sun_info.type);
+      (void) WriteBlobMSBLong(image,sun_info.maptype);
+      (void) WriteBlobMSBLong(image,sun_info.maplength);
+      /*
+        Convert MIFF to SUN raster pixels.
+      */
+      x=0;
+      y=0;
       if (characteristics.monochrome)
         {
+          /*
+            Monochrome SUN raster.
+          */
           register unsigned char
             bit,
             byte,
@@ -1035,51 +999,58 @@
           /*
             Convert PseudoClass image to a SUN monochrome image.
           */
+          if (logging)
+            (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                                  "Writing SUN monochrome frame %lu...",image->scene);
           (void) SetImageType(image,BilevelType);
-          polarity=PixelIntensityToQuantum(&image->colormap[0]) < (MaxRGB/2);
+          polarity=PixelIntensityToQuantum(&image->colormap[0]) > (MaxRGB/2);
           if (image->colors == 2)
-            polarity=PixelIntensityToQuantum(&image->colormap[0]) <
+            polarity=PixelIntensityToQuantum(&image->colormap[0]) >
               PixelIntensityToQuantum(&image->colormap[1]);
           for (y=0; y < (long) image->rows; y++)
-          {
-            p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
-            if (p == (const PixelPacket *) NULL)
-              break;
-            indexes=AccessImmutableIndexes(image);
-            bit=0;
-            byte=0;
-            for (x=0; x < (long) image->columns; x++)
             {
-              byte<<=1;
-              if (indexes[x] == polarity)
-                byte|=0x01;
-              bit++;
-              if (bit == 8)
+              p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
+              if (p == (const PixelPacket *) NULL)
+                break;
+              indexes=AccessImmutableIndexes(image);
+              bit=0;
+              byte=0;
+              for (x=0; x < (long) image->columns; x++)
                 {
-                  (void) WriteBlobByte(image,byte);
-                  bit=0;
-                  byte=0;
+                  byte<<=1;
+                  if (indexes[x] == polarity)
+                    byte|=0x01;
+                  bit++;
+                  if (bit == 8)
+                    {
+                      (void) WriteBlobByte(image,byte);
+                      bit=0;
+                      byte=0;
+                    }
+                  p++;
                 }
-              p++;
+              if (bit != 0)
+                (void) WriteBlobByte(image,byte << (8-bit));
+              if ((((image->columns/8)+
+                    (image->columns % 8 ? 1 : 0)) % 2) != 0)
+                (void) WriteBlobByte(image,0);  /* pad scanline */
+              if (image->previous == (Image *) NULL)
+                if (QuantumTick(y,image->rows))
+                  if (!MagickMonitorFormatted(y,image->rows,&image->exception,
+                                              SaveImageText,image->filename,
+                                              image->columns,image->rows))
+                    break;
             }
-            if (bit != 0)
-              (void) WriteBlobByte(image,byte << (8-bit));
-            if ((((image->columns/8)+
-                (image->columns % 8 ? 1 : 0)) % 2) != 0)
-              (void) WriteBlobByte(image,0);  /* pad scanline */
-            if (image->previous == (Image *) NULL)
-              if (QuantumTick(y,image->rows))
-                if (!MagickMonitorFormatted(y,image->rows,&image->exception,
-                                            SaveImageText,image->filename,
-                                            image->columns,image->rows))
-                  break;
-          }
         }
-      else
+      else if (characteristics.palette)
         {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.