GraphicsMagick: 2 new changesets

GraphicsMagick Commits <[email protected]>
Newsgroups gmane.comp.video.graphicsmagick.cvs
Message-ID <mailman.11300.1682786649.1602.graphicsmagick-commit@lists.sourceforge.net>
changeset 8263ceca7fb3 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=8263ceca7fb3
summary: RoundDoubleToQuantumN(): Version of RoundDoubleToQuantum() which handles NaN.  Use where needed.

changeset 646dd7d9dda2 in /hg/GraphicsMagick
details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=646dd7d9dda2
summary: Merge heads

diffstat:

 ChangeLog          |   17 ++++
 coders/topol.c     |  171 +++++++++++++++++++++++++++++++++++++++++--
 coders/viff.c      |   11 +--
 magick/blob.c      |   23 +++++
 magick/blob.h      |    1 +
 magick/image.h     |    4 +-
 magick/import.c    |  206 +++++++++++++++++++++++++---------------------------
 www/Changelog.html |    9 ++
 8 files changed, 317 insertions(+), 125 deletions(-)

diffs (truncated from 1119 to 500 lines):

diff -r c2a4d0286bcb -r 646dd7d9dda2 ChangeLog
--- a/ChangeLog	Sat Apr 29 10:51:20 2023 -0500
+++ b/ChangeLog	Sat Apr 29 11:43:45 2023 -0500
@@ -1,5 +1,22 @@
+2023-04-29  Fojtik Jaroslav  <[email protected]>
+
+	* coders/topol.c: First attempt to make a writer.
+	* magick/blob.h magick/blob.c: New function WriteBlobLSBDouble.
+
 2023-04-29  Bob Friesenhahn  <[email protected]>
 
+	* magick/image.h (RoundDoubleToQuantumN): New macro to address NaN
+	issues when converting a double to a Quantum.  Use it where
+	needed.
+
+	* magick/import.c (ImportGrayQuantumType): If value is nan, then
+	use 0.0. Addresses SourceForge issue #706 "Integer overflow,
+	floating-point exception, pointer overflow in gm".
+
+	* coders/viff.c (ReadVIFFImage): If value is nan, then use 0.0.
+	Addresses SourceForge issue #706 "Integer overflow, floating-point
+	exception, pointer overflow in gm".
+
 	* coders/mat.c (InsertComplexDoubleRow): If computed f is nan,
 	then use 0.0.  Addresses SourceForge issue #708 "Undefined
 	behavior while converting negative infinity to integer".
diff -r c2a4d0286bcb -r 646dd7d9dda2 coders/topol.c
--- a/coders/topol.c	Sat Apr 29 10:51:20 2023 -0500
+++ b/coders/topol.c	Sat Apr 29 11:43:45 2023 -0500
@@ -20,13 +20,13 @@
 %                                                                             %
 %                              Software Design                                %
 %                              Jaroslav Fojtik                                %
-%                                2003 - 2018                                  %
+%                                2003 - 2023                                  %
 %                                                                             %
 %                                                                             %
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%
+% Note: TopoL GIS is here: http://www.topol.eu/articles/about
 */
 
 /*
@@ -294,17 +294,17 @@
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  Method ReadTOPOLImage reads an TOPOL X image file and returns it.  It
+%  Method ReadTopoLImage reads an TOPOL X image file and returns it.  It
 %  allocates the memory necessary for the new Image structure and returns a
 %  pointer to the new image.
 %
-%  The format of the ReadTOPOLImage method is:
+%  The format of the ReadTopoLImage method is:
 %
-%      Image *ReadTOPOLImage(const ImageInfo *image_info,ExceptionInfo *exception)
+%      Image *ReadTopoLImage(const ImageInfo *image_info,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
-%    o image:  Method ReadTOPOLImage returns a pointer to the image after
+%    o image:  Method ReadTopoLImage returns a pointer to the image after
 %      reading. A null image is returned if there is a memory shortage or if
 %      the image cannot be read.
 %
@@ -325,7 +325,7 @@
   ThrowReaderException(code_,reason_,image_); \
 }
 
-static Image *ReadTOPOLImage(const ImageInfo * image_info, ExceptionInfo * exception)
+static Image *ReadTopoLImage(const ImageInfo * image_info, ExceptionInfo * exception)
 {
   Image
     *image,
@@ -418,7 +418,7 @@
     }
   if (Header.Komprese != 0 || (Header.Version >= 2 && Header.TileCompression != 0))
     ThrowTOPOLReaderException(CorruptImageError, UnrecognizedImageCompression, image);
-  if (((Header.Rows == 0 || Header.Cols == 0)) ||
+  if(Header.Rows == 0 || Header.Cols == 0 ||
       ((Header.Version >= 2) &&
        (Header.TileWidth == 0 ||
         Header.TileHeight == 0 ||
@@ -466,7 +466,7 @@
 
   i = GetBlobSize(image);
   if(i>0)
-    if(((magick_uint64_t)8*Header.Cols*(magick_uint64_t)Header.Rows) / image->depth > (magick_uint64_t)GetBlobSize(image))
+    if(((magick_uint64_t)depth*Header.Cols*(magick_uint64_t)Header.Rows) / 8 > (magick_uint64_t)GetBlobSize(image))
       goto TOPOL_KO;    /* Check for forged image that overflows file size. */
 
   /* If ping is true, then only set image size and colors without reading any image data. */
@@ -743,6 +743,154 @@
   if (logging) (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return");
   return (image);
 }
+
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   W r i t e T o p o L I m a g e                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Function WriteTopoLImage writes an WPG image to a file.
+%
+%  The format of the WriteTopoLImage method is:
+%
+%      unsigned int WriteTopoLImage(const ImageInfo *image_info,Image *image)
+%
+%  A description of each parameter follows.
+%
+%    o status: Function WriteTopoLImage return True if the image is written.
+%      False is returned is there is a memory shortage or if the image file
+%      fails to write.
+%
+%    o image_info: Specifies a pointer to a ImageInfo structure.
+%
+%    o image:  A pointer to an Image structure.
+*/
+static MagickPassFail WriteTopoLImage(const ImageInfo *image_info, Image *image)
+{
+  long y;
+  unsigned int status;
+  int logging;
+  unsigned char *pixels;
+  RasHeader Header;
+  size_t DataSize;
+  QuantumType qt;
+  int bpp;
+
+	/* Open output image file. */
+  assert(image_info != (const ImageInfo *) NULL);
+  assert(image_info->signature == MagickSignature);
+  assert(image != (Image *)NULL);
+  assert(image->signature == MagickSignature);
+  logging = LogMagickEvent(CoderEvent,GetMagickModule(),"enter TopoL");
+
+  DataSize = 0;
+  memset(&Header,0,sizeof(Header));
+  memset(&Header.Name,' ',sizeof(Header.Name));
+  //Header.Version = 0;
+  Header.Cols = image->columns;
+  Header.Rows = image->rows;
+  if(image->colors>=1 && image->colors<=255)
+  {
+    if(image->colors <= 2)
+    {
+      Header.FileType = 0;
+      DataSize = (Header.Cols+7) / 8;
+      qt = GrayQuantum;
+      bpp =1;
+    } else if(image->colors <= 16)
+    {
+      Header.FileType = 4;
+      DataSize = (Header.Cols+1) / 2;
+      qt = IndexQuantum;
+      bpp = 4;
+    }
+    else
+    {
+      Header.FileType = 2;
+      DataSize = Header.Cols;
+      qt = IndexQuantum;
+      bpp = 8;
+    }
+  }
+  else		// RGB
+  {
+    Header.FileType = 5;
+    DataSize = 3*Header.Cols;
+    qt = RGBQuantum;
+    bpp = 8;
+  }
+
+  if(DataSize==0)
+    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+  pixels = MagickAllocateResourceLimitedMemory(unsigned char *,(size_t) (DataSize));
+
+  status = OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+  if(status == MagickFail)
+    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
+
+	/* Write TopoL hader. */
+  WriteBlob(image, 20, Header.Name);
+  WriteBlobLSBShort(image, Header.Rows);
+  WriteBlobLSBShort(image, Header.Cols);
+  WriteBlobLSBShort(image, Header.FileType);
+  WriteBlobLSBLong(image, Header.Zoom);
+  WriteBlobLSBShort(image, Header.Version);
+  WriteBlobLSBShort(image, Header.Komprese);
+  WriteBlobLSBShort(image, Header.Stav);
+
+  WriteBlobLSBDouble(image, Header.xRasMin);
+  WriteBlobLSBDouble(image, Header.yRasMin);
+  WriteBlobLSBDouble(image, Header.xRasMax);
+  WriteBlobLSBDouble(image, Header.yRasMax);
+  WriteBlobLSBDouble(image, Header.Scale);
+	//from release 2
+  WriteBlobLSBShort(image, Header.TileWidth);
+  WriteBlobLSBShort(image, Header.TileHeight);
+  WriteBlobLSBLong(image, Header.TileOffsets);
+  WriteBlobLSBLong(image, Header.TileByteCounts);
+  WriteBlobByte(image, Header.TileCompression);
+
+  WriteBlob(image, 423, Header.Dummy);
+
+	/* Palette */
+
+
+	/* Store image data. */
+  for(y=0; y<(long)image->rows; y++)
+  {
+    if(AcquireImagePixels(image,0,y,image->columns,1,&image->exception)  == (const PixelPacket *)NULL)
+    {
+      status=MagickFail;
+      break;
+    }
+    if(ExportImagePixelArea(image,qt,bpp,pixels,0,0) != MagickPass)
+    {
+      status = MagickFail;
+      break;
+    }
+    if(WriteBlob(image,DataSize,pixels) != DataSize)
+    {
+      status = MagickFail;
+      break;
+    }
+  }
+
+  CloseBlob(image);
+
+  if(logging)
+    (void)LogMagickEvent(CoderEvent,GetMagickModule(),"return TopoL");
+
+  return(status);
+}
+
+
 
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -772,9 +920,10 @@
   MagickInfo * entry;
 
   entry = SetMagickInfo("TOPOL");
-  entry->decoder = (DecoderHandler) ReadTOPOLImage;
+  entry->decoder = (DecoderHandler) ReadTopoLImage;
+  entry->encoder = (EncoderHandler) WriteTopoLImage;
   entry->seekable_stream = True;
-  entry->description = "TOPOL X Image";
+  entry->description = "TopoL X Image";
   entry->module = "TOPOL";
   (void) RegisterMagickInfo(entry);
 }
diff -r c2a4d0286bcb -r 646dd7d9dda2 coders/viff.c
--- a/coders/viff.c	Sat Apr 29 10:51:20 2023 -0500
+++ b/coders/viff.c	Sat Apr 29 11:43:45 2023 -0500
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2003-2020 GraphicsMagick Group
+% Copyright (C) 2003-2023 GraphicsMagick Group
 % Copyright (C) 2002 ImageMagick Studio
 % Copyright 1991-1999 E. I. du Pont de Nemours and Company
 %
@@ -78,7 +78,7 @@
 typedef struct _ViffInfo
 {
   unsigned char
-  identifier,
+    identifier,
     file_type,
     release,
     version,
@@ -735,13 +735,8 @@
       if (viff_info.map_scheme == VFF_MS_NONE)
         {
           value=(value-min_value)*scale_factor;
-          if (value > MaxRGB)
-            value=MaxRGB;
-          else
-            if (value < 0)
-              value=0;
         }
-      *p=(Quantum) value;
+      *p=RoundDoubleToQuantumN(value);
       p++;
     }
     /*
diff -r c2a4d0286bcb -r 646dd7d9dda2 magick/blob.c
--- a/magick/blob.c	Sat Apr 29 10:51:20 2023 -0500
+++ b/magick/blob.c	Sat Apr 29 11:43:45 2023 -0500
@@ -5458,6 +5458,7 @@
 */
 MagickExport size_t WriteBlobLSBLong(Image *image,const magick_uint32_t value)
 {
+#if defined(WORDS_BIGENDIAN)
   unsigned char
     buffer[4];
 
@@ -5468,6 +5469,12 @@
   buffer[2]=(unsigned char) (value >> 16);
   buffer[3]=(unsigned char) (value >> 24);
   return(WriteBlob(image,4,buffer));
+#else
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickSignature);
+  assert(sizeof(value) == 4);
+  return(WriteBlob(image,4,&value));
+#endif
 }
 
 /*
@@ -5602,6 +5609,21 @@
   buffer[1]=(unsigned char) (uvalue.uint16 >> 8);
   return(WriteBlob(image,2,buffer));
 }
+
+
+MagickExport size_t WriteBlobLSBDouble(Image *image, double d)
+{
+  assert(image != (Image *) NULL);
+  assert(image->signature == MagickSignature);
+  assert(sizeof(d) == 8);
+
+#if defined(WORDS_BIGENDIAN)
+  MagickSwabDouble(&d);
+#endif
+  return(WriteBlob(image,8,&d));
+}
+
+
 
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -5654,6 +5676,7 @@
 
   return octets_read;
 }
+
 
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff -r c2a4d0286bcb -r 646dd7d9dda2 magick/blob.h
--- a/magick/blob.h	Sat Apr 29 10:51:20 2023 -0500
+++ b/magick/blob.h	Sat Apr 29 11:43:45 2023 -0500
@@ -398,6 +398,7 @@
                                                     const magick_int32_t value);
 
 
+  extern MagickExport size_t WriteBlobLSBDouble(Image *image, double d);
 
   /*
     Write a 32-bit unsigned "long" value to the file or BLOB in big-endian
diff -r c2a4d0286bcb -r 646dd7d9dda2 magick/image.h
--- a/magick/image.h	Sat Apr 29 10:51:20 2023 -0500
+++ b/magick/image.h	Sat Apr 29 11:43:45 2023 -0500
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003 - 2019 GraphicsMagick Group
+  Copyright (C) 2003 - 2023 GraphicsMagick Group
   Copyright (C) 2002 ImageMagick Studio
   Copyright 1991-1999 E. I. du Pont de Nemours and Company
 
@@ -126,6 +126,8 @@
 #define TransparentOpacity  MaxRGB
 #define RoundDoubleToQuantum(value) ((Quantum) (value < 0.0 ? 0U : \
   (value > MaxRGBDouble) ? MaxRGB : value + 0.5))
+#define RoundDoubleToQuantumN(value) ((Quantum) (MAGICK_ISNAN(value) ? 0U : \
+  (value < 0.0 ? 0U : (value > MaxRGBDouble) ? MaxRGB : value + 0.5)))
 #define RoundFloatToQuantum(value) ((Quantum) (value < 0.0f ? 0U : \
   (value > MaxRGBFloat) ? MaxRGB : value + 0.5f))
 #define ConstrainToRange(min,max,value) (value < min ? min :    \
diff -r c2a4d0286bcb -r 646dd7d9dda2 magick/import.c
--- a/magick/import.c	Sat Apr 29 10:51:20 2023 -0500
+++ b/magick/import.c	Sat Apr 29 11:43:45 2023 -0500
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2003 - 2022 GraphicsMagick Group
+  Copyright (C) 2003 - 2023 GraphicsMagick Group
   Copyright (C) 2002 ImageMagick Studio
 
   This program is covered by multiple licenses, which are described in
@@ -187,8 +187,6 @@
         fu_.c[0]=*p++;                          \
         value=fu_.f;                            \
       }                                         \
-    if (MAGICK_ISNAN(value))                    \
-      value = 0.0;                              \
   }
 #define ImportFloat64Quantum(endian,value,p)    \
   {                                             \
@@ -215,8 +213,6 @@
         du_.c[0]=*p++;                          \
         value=du_.d;                            \
       }                                         \
-    if (MAGICK_ISNAN(value))                \
-      value = 0.0;                              \
   }
 
 /*
@@ -978,7 +974,7 @@
                 ImportFloat16Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -990,7 +986,7 @@
                 ImportFloat24Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1002,7 +998,7 @@
                 ImportFloat32Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1014,7 +1010,7 @@
                 ImportFloat64Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1324,11 +1320,11 @@
                 ImportFloat16Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 ImportFloat16Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1340,11 +1336,11 @@
                 ImportFloat24Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 ImportFloat24Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1356,11 +1352,11 @@
                 ImportFloat32Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 ImportFloat32Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
@@ -1372,11 +1368,11 @@
                 ImportFloat64Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetGraySample(q,RoundDoubleToQuantum(double_value));
+                SetGraySample(q,RoundDoubleToQuantumN(double_value));
                 ImportFloat64Quantum(endian,double_value,p);
                 double_value -= double_minvalue;
                 double_value *= double_scale;
-                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantum(double_value));
+                SetOpacitySample(q,MaxRGB-RoundDoubleToQuantumN(double_value));
                 q++;
               }
             break;
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.