GraphicsMagick: 2 new changesets
GraphicsMagick Commits <[email protected]>
| Newsgroups | gmane.comp.video.graphicsmagick.cvs |
|---|---|
| Message-ID | <mailman.11297.1682785995.1602.graphicsmagick-commit@lists.sourceforge.net> |
changeset 716ae84b9960 in /hg/GraphicsMagick details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=716ae84b9960 summary: coders/topol.c: First attempt to make a writer. changeset 5b54e4cb9eea in /hg/GraphicsMagick details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=5b54e4cb9eea summary: Merge heads diffstat: ChangeLog | 10 +++ coders/mat.c | 10 ++- coders/topol.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++--- magick/blob.c | 23 +++++++ magick/blob.h | 1 + www/Changelog.html | 8 ++ 6 files changed, 211 insertions(+), 12 deletions(-) diffs (384 lines): diff -r ca23f27fe474 -r 5b54e4cb9eea ChangeLog --- a/ChangeLog Sat Apr 29 10:13:35 2023 -0500 +++ b/ChangeLog Sat Apr 29 18:32:33 2023 +0200 @@ -1,5 +1,15 @@ +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]> + * 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". + (InsertComplexFloatRow): If computed f is nan, then use 0.0. + * magick/attribute.c (GenerateEXIFAttribute): Assure that float and double values are suitably alligned. Addresses SourceForge issue #709 "Undefined behavior while loading a value of type float diff -r ca23f27fe474 -r 5b54e4cb9eea coders/mat.c --- a/coders/mat.c Sat Apr 29 10:13:35 2023 -0500 +++ b/coders/mat.c Sat Apr 29 18:32:33 2023 +0200 @@ -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 @@ -171,6 +171,8 @@ if (*p > 0) { f = (*p / MaxVal) * (Quantum)(MaxRGB - q->red); /* first multiplier should be in a range <0;1> */ + if (MAGICK_ISNAN(f)) + f=0.0; /*if(f<0) f=0; */ if (f + q->red >= MaxRGB) q->red = MaxRGB; @@ -185,6 +187,8 @@ if (*p < 0) { f = (*p / MinVal) * (Quantum)(MaxRGB - q->blue); /* first multiplier should be in a range <0;1>; *p<0 and MinVal<0. */ + if (MAGICK_ISNAN(f)) + f=0.0; /*if(f<0) f=0; */ if (f + q->blue >= MaxRGB) q->blue = MaxRGB; @@ -230,6 +234,8 @@ if (*p > 0) { f = (*p / MaxVal) * (Quantum)(MaxRGB - q->red); + if (MAGICK_ISNAN(f)) + f=0.0; /*if(f<0) f=0; //Only for Assert, should be commented out */ if (f + q->red < MaxRGB) q->red += (int)f; @@ -244,6 +250,8 @@ if (*p < 0) { f = (*p / MinVal) * (Quantum)(MaxRGB - q->blue); /* f is positive only <0; inf> */ + if (MAGICK_ISNAN(f)) + f=0.0; /*if(f<0) f=0; //Only for Assert, should be commented out */ if (f + q->blue < MaxRGB) q->blue += (int) f; diff -r ca23f27fe474 -r 5b54e4cb9eea coders/topol.c --- a/coders/topol.c Sat Apr 29 10:13:35 2023 -0500 +++ b/coders/topol.c Sat Apr 29 18:32:33 2023 +0200 @@ -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 ca23f27fe474 -r 5b54e4cb9eea magick/blob.c --- a/magick/blob.c Sat Apr 29 10:13:35 2023 -0500 +++ b/magick/blob.c Sat Apr 29 18:32:33 2023 +0200 @@ -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 ca23f27fe474 -r 5b54e4cb9eea magick/blob.h --- a/magick/blob.h Sat Apr 29 10:13:35 2023 -0500 +++ b/magick/blob.h Sat Apr 29 18:32:33 2023 +0200 @@ -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 ca23f27fe474 -r 5b54e4cb9eea www/Changelog.html --- a/www/Changelog.html Sat Apr 29 10:13:35 2023 -0500 +++ b/www/Changelog.html Sat Apr 29 18:32:33 2023 +0200 @@ -40,6 +40,14 @@ <p>2023-04-29 Bob Friesenhahn <<a class="reference external" href="mailto:bfriesen%40simple.dallas.tx.us">bfriesen<span>@</span>simple<span>.</span>dallas<span>.</span>tx<span>.</span>us</a>></p> <blockquote> <ul class="simple"> +<li><p>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". +(InsertComplexFloatRow): If computed f is nan, then use 0.0.</p></li> +<li><p>magick/attribute.c (GenerateEXIFAttribute): Assure that float +and double values are suitably alligned. Addresses SourceForge +issue #709 "Undefined behavior while loading a value of type float +from an unaligned address".</p></li> <li><p>coders/tiff.c (ReadTIFFImage): Validate that TIFFGetField() did return count and text rather than just relying on its return status. Addresses SourceForge issue #710 "Undefined behavior