From b2d2441f20fb0c735b86df0c9aa65dfe62a52157 Mon Sep 17 00:00:00 2001 From: Cristy Date: Fri, 9 Mar 2018 19:41:19 -0500 Subject: [PATCH] Support GRAYA image format --- MagickCore/coder.c | 1 + MagickCore/quantum-private.h | 8 +- coders/gray.c | 1109 +++++++++++++++++++++++++++++++--- coders/rgb.c | 4 +- 4 files changed, 1020 insertions(+), 102 deletions(-) diff --git a/MagickCore/coder.c b/MagickCore/coder.c index 48c37115f..c54497849 100644 --- a/MagickCore/coder.c +++ b/MagickCore/coder.c @@ -136,6 +136,7 @@ static const CoderMapInfo { "GIF87", "GIF" }, { "G", "RAW" }, { "GRANITE", "MAGICK" }, + { "GRAYA", "GRAY" }, { "GROUP4", "TIFF" }, { "GV", "DOT" }, { "HTM", "HTML" }, diff --git a/MagickCore/quantum-private.h b/MagickCore/quantum-private.h index be8dc6e10..888b581f0 100644 --- a/MagickCore/quantum-private.h +++ b/MagickCore/quantum-private.h @@ -94,9 +94,11 @@ extern MagickPrivate void static inline MagickSizeType GetQuantumRange(const size_t depth) { MagickSizeType - max_depth, one; + size_t + max_depth; + if (depth == 0) return(0); one=1; @@ -312,10 +314,10 @@ static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum, return(QuantumRange); #if !defined(MAGICKCORE_HDRI_SUPPORT) return((Quantum) (((double) QuantumRange*quantum)* - PerceptibleReciprocal(range)+0.5)); + PerceptibleReciprocal((double) range)+0.5)); #else return((Quantum) (((double) QuantumRange*quantum)* - PerceptibleReciprocal(range))); + PerceptibleReciprocal((double) range))); #endif } diff --git a/coders/gray.c b/coders/gray.c index 48f3745c4..6cf906c77 100644 --- a/coders/gray.c +++ b/coders/gray.c @@ -10,7 +10,7 @@ % GGG R R A A Y % % % % % -% Read/Write RAW Gray Image Format % +% Read/Write Raw GRAY Image Format % % % % Software Design % % Cristy % @@ -40,10 +40,10 @@ Include declarations. */ #include "MagickCore/studio.h" -#include "MagickCore/attribute.h" #include "MagickCore/blob.h" #include "MagickCore/blob-private.h" #include "MagickCore/cache.h" +#include "MagickCore/channel.h" #include "MagickCore/colorspace.h" #include "MagickCore/colorspace-private.h" #include "MagickCore/constitute.h" @@ -56,13 +56,13 @@ #include "MagickCore/memory_.h" #include "MagickCore/monitor.h" #include "MagickCore/monitor-private.h" -#include "MagickCore/pixel.h" #include "MagickCore/pixel-accessor.h" #include "MagickCore/quantum-private.h" #include "MagickCore/static.h" #include "MagickCore/statistic.h" #include "MagickCore/string_.h" #include "MagickCore/module.h" +#include "MagickCore/utility.h" /* Forward declarations. @@ -81,9 +81,9 @@ static MagickBooleanType % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% ReadGRAYImage() reads an image of raw grayscale samples and returns -% it. It allocates the memory necessary for the new Image structure and -% returns a pointer to the new image. +% ReadGRAYImage() reads an image of raw GRAY samples 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 ReadGRAYImage method is: % @@ -119,6 +119,9 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, QuantumType quantum_type; + register ssize_t + i; + size_t length; @@ -139,30 +142,38 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, image=AcquireImage(image_info,exception); if ((image->columns == 0) || (image->rows == 0)) ThrowReaderException(OptionError,"MustSpecifyImageSize"); - status=SetImageExtent(image,image->columns,image->rows,exception); - if (status == MagickFalse) - return(DestroyImageList(image)); - status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); - if (status == MagickFalse) + image->colorspace=GRAYColorspace; + if (image_info->interlace != PartitionInterlace) { - image=DestroyImageList(image); - return((Image *) NULL); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + image=DestroyImageList(image); + return((Image *) NULL); + } + if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", + image->filename); } - if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) - ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", - image->filename); /* - Create virtual canvas to support cropping (i.e. image.gray[100x100+10+20]). + Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]). */ - (void) SetImageColorspace(image,GRAYColorspace,exception); canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse, exception); + if(canvas_image == (Image *) NULL) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod, exception); - quantum_type=GrayQuantum; quantum_info=AcquireQuantumInfo(image_info,canvas_image); if (quantum_info == (QuantumInfo *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + quantum_type=GrayQuantum; + if (LocaleCompare(image_info->magick,"GRAYA") == 0) + { + quantum_type=GrayAlphaQuantum; + image->alpha_trait=BlendPixelTrait; + canvas_image->alpha_trait=BlendPixelTrait; + } pixels=(const unsigned char *) NULL; if (image_info->number_scenes != 0) while (image->scene < image_info->scene) @@ -180,10 +191,9 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, break; } } - scene=0; count=0; length=0; - status=MagickTrue; + scene=0; do { /* @@ -194,71 +204,785 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, break; status=SetImageExtent(image,image->columns,image->rows,exception); if (status == MagickFalse) - break; - if (SetImageColorspace(image,GRAYColorspace,exception) == MagickFalse) - break; - if (scene == 0) - { - length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); - pixels=(const unsigned char *) ReadBlobStream(image,length, - GetQuantumPixels(quantum_info),&count); - if (count != (ssize_t) length) - break; - } - for (y=0; y < (ssize_t) image->extract_info.height; y++) + return(DestroyImageList(image)); + switch (image_info->interlace) { - register const Quantum - *magick_restrict p; + case NoInterlace: + default: + { + /* + No interlacing: GRAYGRAYGRAYGRAYGRAYGRAY... + */ + if (scene == 0) + { + length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; - register ssize_t - x; + register Quantum + *magick_restrict q; - register Quantum - *magick_restrict q; + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,quantum_type,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=QueueAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelRed(image,GetPixelRed(canvas_image,p),q); + SetPixelGreen(image,GetPixelGreen(canvas_image,p),q); + SetPixelBlue(image,GetPixelBlue(canvas_image,p),q); + SetPixelAlpha(image,OpaqueAlpha,q); + if (image->alpha_trait != UndefinedPixelTrait) + SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + break; + } + case LineInterlace: + { + static QuantumType + quantum_types[4] = + { + RedQuantum, + GreenQuantum, + BlueQuantum, + AlphaQuantum + }; - if (count != (ssize_t) length) + /* + Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB... + */ + if (LocaleCompare(image_info->magick,"GRAYO") == 0) + quantum_types[3]=OpacityQuantum; + if (scene == 0) + { + length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + for (y=0; y < (ssize_t) image->extract_info.height; y++) { - status=MagickFalse; - ThrowFileException(exception,CorruptImageError, - "UnexpectedEndOfFile",image->filename); - break; + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++) + { + quantum_type=quantum_types[i]; + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,quantum_type,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x, + 0,canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + switch (quantum_type) + { + case RedQuantum: + { + SetPixelRed(image,GetPixelRed(canvas_image,p),q); + break; + } + case GreenQuantum: + { + SetPixelGreen(image,GetPixelGreen(canvas_image,p),q); + break; + } + case BlueQuantum: + { + SetPixelBlue(image,GetPixelBlue(canvas_image,p),q); + break; + } + case OpacityQuantum: + { + SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q); + break; + } + case AlphaQuantum: + { + SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q); + break; + } + default: + break; + } + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; + } } - q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,exception); - if (q == (Quantum *) NULL) break; - length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,quantum_info, - quantum_type,pixels,exception); - if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + } + case PlaneInterlace: + { + /* + Plane interlacing: RRRRRR...GGGGGG...BBBBBB... + */ + if (scene == 0) + { + length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,RedQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelRed(image,GetPixelRed(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,1,6); + if (status == MagickFalse) + break; + } + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,GreenQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelGreen(image,GetPixelGreen(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,2,6); + if (status == MagickFalse) + break; + } + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,BlueQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelBlue(image,GetPixelBlue(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,3,6); + if (status == MagickFalse) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,4,6); + if (status == MagickFalse) + break; + } + if (image->alpha_trait != UndefinedPixelTrait) + { + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,AlphaQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image, + canvas_image->extract_info.x,0,canvas_image->columns,1, + exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,5,6); + if (status == MagickFalse) + break; + } + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,6,6); + if (status == MagickFalse) + break; + } break; - if (((y-image->extract_info.y) >= 0) && - ((y-image->extract_info.y) < (ssize_t) image->rows)) + } + case PartitionInterlace: + { + /* + Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB... + */ + AppendImageFormat("R",image->filename); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + canvas_image=DestroyImageList(canvas_image); + image=DestroyImageList(image); + return((Image *) NULL); + } + if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) + ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", + image->filename); + length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); + for (i=0; i < (ssize_t) scene; i++) + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + for (y=0; y < (ssize_t) image->extract_info.height; y++) { - p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, - image->columns,1,exception); - q=QueueAuthenticPixels(image,0,y-image->extract_info.y,image->columns, - 1,exception); - if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,RedQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - for (x=0; x < (ssize_t) image->columns; x++) + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelRed(image,GetPixelRed(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,1,5); + if (status == MagickFalse) + break; + } + (void) CloseBlob(image); + AppendImageFormat("G",image->filename); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + canvas_image=DestroyImageList(canvas_image); + image=DestroyImageList(image); + return((Image *) NULL); + } + length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum); + for (i=0; i < (ssize_t) scene; i++) + for (y=0; y < (ssize_t) image->extract_info.height; y++) { - SetPixelGray(image,GetPixelGray(canvas_image,p),q); - p+=GetPixelChannels(canvas_image); - q+=GetPixelChannels(image); + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } } - if (SyncAuthenticPixels(image,exception) == MagickFalse) + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,GreenQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelGreen(image,GetPixelGreen(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) break; } - if (image->previous == (Image *) NULL) + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,2,5); + if (status == MagickFalse) + break; + } + (void) CloseBlob(image); + AppendImageFormat("B",image->filename); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + canvas_image=DestroyImageList(canvas_image); + image=DestroyImageList(image); + return((Image *) NULL); + } + length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum); + for (i=0; i < (ssize_t) scene; i++) + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + for (y=0; y < (ssize_t) image->extract_info.height; y++) { - status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,BlueQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0, + canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelBlue(image,GetPixelBlue(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) break; } - pixels=(const unsigned char *) ReadBlobStream(image,length, - GetQuantumPixels(quantum_info),&count); - if (count != (ssize_t) length) + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,3,5); + if (status == MagickFalse) + break; + } + if (image->alpha_trait != UndefinedPixelTrait) + { + (void) CloseBlob(image); + AppendImageFormat("A",image->filename); + status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); + if (status == MagickFalse) + { + canvas_image=DestroyImageList(canvas_image); + image=DestroyImageList(image); + return((Image *) NULL); + } + length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum); + for (i=0; i < (ssize_t) scene; i++) + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + for (y=0; y < (ssize_t) image->extract_info.height; y++) + { + register const Quantum + *magick_restrict p; + + register Quantum + *magick_restrict q; + + register ssize_t + x; + + if (count != (ssize_t) length) + { + ThrowFileException(exception,CorruptImageError, + "UnexpectedEndOfFile",image->filename); + break; + } + q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1, + exception); + if (q == (Quantum *) NULL) + break; + length=ImportQuantumPixels(canvas_image,(CacheView *) NULL, + quantum_info,BlueQuantum,pixels,exception); + if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) + break; + if (((y-image->extract_info.y) >= 0) && + ((y-image->extract_info.y) < (ssize_t) image->rows)) + { + p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x, + 0,canvas_image->columns,1,exception); + q=GetAuthenticPixels(image,0,y-image->extract_info.y, + image->columns,1,exception); + if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL)) + break; + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q); + p+=GetPixelChannels(canvas_image); + q+=GetPixelChannels(image); + } + if (SyncAuthenticPixels(image,exception) == MagickFalse) + break; + } + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,4,5); + if (status == MagickFalse) + break; + } + } + (void) CloseBlob(image); + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,LoadImageTag,5,5); + if (status == MagickFalse) + break; + } break; + } } SetQuantumImageType(image,quantum_type); /* @@ -289,8 +1013,6 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, quantum_info=DestroyQuantumInfo(quantum_info); canvas_image=DestroyImage(canvas_image); (void) CloseBlob(image); - if (status == MagickFalse) - return(DestroyImageList(image)); return(GetFirstImageInList(image)); } @@ -299,7 +1021,7 @@ static Image *ReadGRAYImage(const ImageInfo *image_info, % % % % % % -% R e g i s t e r G R A Y I m a g e % +% R e g i s t e r G R A Y I m a g e % % % % % % % @@ -328,6 +1050,12 @@ ModuleExport size_t RegisterGRAYImage(void) entry->flags|=CoderRawSupportFlag; entry->flags|=CoderEndianSupportFlag; (void) RegisterMagickInfo(entry); + entry=AcquireMagickInfo("GRAY","GRAYA","Raw gray and alpha samples"); + entry->decoder=(DecodeImageHandler *) ReadGRAYImage; + entry->encoder=(EncodeImageHandler *) WriteGRAYImage; + entry->flags|=CoderRawSupportFlag; + entry->flags|=CoderEndianSupportFlag; + (void) RegisterMagickInfo(entry); return(MagickImageCoderSignature); } @@ -342,8 +1070,8 @@ ModuleExport size_t RegisterGRAYImage(void) % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% UnregisterGRAYImage() removes format registrations made by the -% GRAY module from the list of supported formats. +% UnregisterGRAYImage() removes format registrations made by the GRAY module +% from the list of supported formats. % % The format of the UnregisterGRAYImage method is: % @@ -352,6 +1080,7 @@ ModuleExport size_t RegisterGRAYImage(void) */ ModuleExport void UnregisterGRAYImage(void) { + (void) UnregisterMagickInfo("GRAYA"); (void) UnregisterMagickInfo("GRAY"); } @@ -366,8 +1095,8 @@ ModuleExport void UnregisterGRAYImage(void) % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% WriteGRAYImage() writes an image to a file as gray scale intensity -% values. +% WriteGRAYImage() writes an image to a file in the GRAY, GRAYAlpha, or GRAYO +% rasterfile format. % % The format of the WriteGRAYImage method is: % @@ -409,7 +1138,7 @@ static MagickBooleanType WriteGRAYImage(const ImageInfo *image_info, *pixels; /* - Open output image file. + Allocate memory for pixels. */ assert(image_info != (const ImageInfo *) NULL); assert(image_info->signature == MagickCoreSignature); @@ -417,43 +1146,229 @@ static MagickBooleanType WriteGRAYImage(const ImageInfo *image_info, assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); - assert(exception != (ExceptionInfo *) NULL); - assert(exception->signature == MagickCoreSignature); - status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); - if (status == MagickFalse) - return(status); + if (image_info->interlace != PartitionInterlace) + { + /* + Open output image file. + */ + status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); + if (status == MagickFalse) + return(status); + } + quantum_type=GrayQuantum; + if (LocaleCompare(image_info->magick,"GRAYA") == 0) + quantum_type=GrayAlphaQuantum; scene=0; do { /* - Write grayscale pixels. + Convert MIFF to GRAY raster pixels. */ - (void) TransformImageColorspace(image,sRGBColorspace,exception); - quantum_type=GrayQuantum; + (void) TransformImageColorspace(image,GRAYColorspace,exception); + if ((LocaleCompare(image_info->magick,"GRAYA") == 0) && + (image->alpha_trait == UndefinedPixelTrait)) + (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); quantum_info=AcquireQuantumInfo(image_info,image); if (quantum_info == (QuantumInfo *) NULL) ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); pixels=(unsigned char *) GetQuantumPixels(quantum_info); - for (y=0; y < (ssize_t) image->rows; y++) + switch (image_info->interlace) { - register const Quantum - *magick_restrict p; + case NoInterlace: + default: + { + /* + No interlacing: GGG... + */ + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *magick_restrict p; - p=GetVirtualPixels(image,0,y,image->columns,1,exception); - if (p == (const Quantum *) NULL) + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; + } + } break; - length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, - quantum_type,pixels,exception); - count=WriteBlob(image,length,pixels); - if (count != (ssize_t) length) + } + case LineInterlace: + { + /* + Line interlacing: GGG... + */ + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *magick_restrict p; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + GrayQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + if (quantum_type == GrayAlphaQuantum) + { + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + AlphaQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, + image->rows); + if (status == MagickFalse) + break; + } + } break; - if (image->previous == (Image *) NULL) + } + case PlaneInterlace: + { + /* + Plane interlacing: GGG... + */ + for (y=0; y < (ssize_t) image->rows; y++) { - status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, - image->rows); - if (status == MagickFalse) + register const Quantum + *magick_restrict p; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + GrayQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) break; } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,1,6); + if (status == MagickFalse) + break; + } + if (quantum_type == GrayAlphaQuantum) + { + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *magick_restrict p; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + AlphaQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,5,6); + if (status == MagickFalse) + break; + } + } + if (image_info->interlace == PartitionInterlace) + (void) CopyMagickString(image->filename,image_info->filename, + MagickPathExtent); + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,6,6); + if (status == MagickFalse) + break; + } + break; + } + case PartitionInterlace: + { + /* + Partition interlacing: GGG... + */ + AppendImageFormat("G",image->filename); + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) + return(status); + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *magick_restrict p; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + RedQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,1,6); + if (status == MagickFalse) + break; + } + (void) CloseBlob(image); + if (quantum_type == GrayAlphaQuantum) + { + (void) CloseBlob(image); + AppendImageFormat("A",image->filename); + status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode : + AppendBinaryBlobMode,exception); + if (status == MagickFalse) + return(status); + for (y=0; y < (ssize_t) image->rows; y++) + { + register const Quantum + *magick_restrict p; + + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) + break; + length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + AlphaQuantum,pixels,exception); + count=WriteBlob(image,length,pixels); + if (count != (ssize_t) length) + break; + } + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,5,6); + if (status == MagickFalse) + break; + } + } + (void) CloseBlob(image); + (void) CopyMagickString(image->filename,image_info->filename, + MagickPathExtent); + if (image->previous == (Image *) NULL) + { + status=SetImageProgress(image,SaveImageTag,6,6); + if (status == MagickFalse) + break; + } + break; + } } quantum_info=DestroyQuantumInfo(quantum_info); if (GetNextImageInList(image) == (Image *) NULL) diff --git a/coders/rgb.c b/coders/rgb.c index e77284102..e8455a828 100644 --- a/coders/rgb.c +++ b/coders/rgb.c @@ -149,7 +149,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) image=DestroyImageList(image); return((Image *) NULL); } - if (DiscardBlobBytes(image,image->offset) == MagickFalse) + if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); } @@ -661,7 +661,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) image=DestroyImageList(image); return((Image *) NULL); } - if (DiscardBlobBytes(image,image->offset) == MagickFalse) + if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse) ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", image->filename); length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum); -- 2.40.0