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) {