From 747a7343025b9aa9293b9e8e5dd412bfd47d13f0 Mon Sep 17 00:00:00 2001 From: Cristy Date: Mon, 3 Jun 2019 21:01:22 -0400 Subject: [PATCH] https://imagemagick.org/discourse-server/viewtopic.php?f=2&t=360 --- ChangeLog | 7 ++ coders/rgb.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++++--- coders/rgb.h | 5 +- 3 files changed, 262 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 00a05513b..963934f7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2019-07-01 7.0.8-49 Cristy + * Release ImageMagick version 7.0.8-49, GIT revision 15... + +2019-06-03 7.0.8-49 Cristy + * Add support for RGB565 image format (reference + https://imagemagick.org/discourse-server/viewtopic.php?f=2&t=36078). + 2019-06-01 7.0.8-48 Cristy * Release ImageMagick version 7.0.8-48, GIT revision 15689:061a3bb82:20190601 diff --git a/coders/rgb.c b/coders/rgb.c index 15759f916..b25773636 100644 --- a/coders/rgb.c +++ b/coders/rgb.c @@ -253,7 +253,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -339,7 +339,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,quantum_type,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -436,7 +436,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -489,7 +489,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -542,7 +542,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -597,7 +597,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,AlphaQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + if (((y-image->extract_info.y) >= 0) && ((y-image->extract_info.y) < (ssize_t) image->rows)) { p=GetVirtualPixels(canvas_image, @@ -691,7 +691,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,RedQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -764,7 +764,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,GreenQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -800,7 +800,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) 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) @@ -837,7 +837,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -912,7 +912,7 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) quantum_info,BlueQuantum,pixels,exception); if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse) break; - if (((y-image->extract_info.y) >= 0) && + 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, @@ -991,6 +991,241 @@ static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception) % % % % % % +% R e a d R G B 5 6 5 I m a g e % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% ReadGRAYImage() reads an image of raw RGB 5-6-5 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: +% +% Image *ReadGRAYImage(const ImageInfo *image_info, +% ExceptionInfo *exception) +% +% A description of each parameter follows: +% +% o image_info: the image info. +% +% o exception: return any errors or warnings in this structure. +% +*/ +static Image *ReadRGB565Image(const ImageInfo *image_info, + ExceptionInfo *exception) +{ + const unsigned char + *pixels; + + Image + *canvas_image, + *image; + + MagickBooleanType + status; + + MagickOffsetType + scene; + + QuantumInfo + *quantum_info; + + QuantumType + quantum_type; + + size_t + length; + + ssize_t + count, + y; + + /* + Open image file. + */ + assert(image_info != (const ImageInfo *) NULL); + assert(image_info->signature == MagickCoreSignature); + if (image_info->debug != MagickFalse) + (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", + image_info->filename); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickCoreSignature); + image=AcquireImage(image_info,exception); + if ((image->columns == 0) || (image->rows == 0)) + ThrowReaderException(OptionError,"MustSpecifyImageSize"); + image->depth=16; + if (image_info->interlace != PartitionInterlace) + { + 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); + } + /* + Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]). + */ + 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_info=AcquireQuantumInfo(image_info,canvas_image); + if (quantum_info == (QuantumInfo *) NULL) + { + canvas_image=DestroyImage(canvas_image); + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } + quantum_type=GrayQuantum; + pixels=(const unsigned char *) NULL; + if (image_info->number_scenes != 0) + while (image->scene < image_info->scene) + { + /* + Skip to next image. + */ + image->scene++; + length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); + for (y=0; y < (ssize_t) image->rows; y++) + { + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + if (count != (ssize_t) length) + break; + } + } + count=0; + length=0; + scene=0; + status=MagickTrue; + do + { + /* + Read pixels to virtual canvas image then push to image. + */ + if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) + if (image->scene >= (image_info->scene+image_info->number_scenes-1)) + break; + status=SetImageExtent(image,image->columns,image->rows,exception); + if (status == MagickFalse) + break; + /* + No interlacing: GGG... + */ + if (scene == 0) + { + length=GetQuantumExtent(canvas_image,quantum_info,quantum_type); + pixels=(const unsigned char *) ReadBlobStream(image,length, + GetQuantumPixels(quantum_info),&count); + } + 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) + { + status=MagickFalse; + 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++) + { + unsigned short + pixel; + + pixel=(unsigned short) ScaleQuantumToShort(GetPixelGray( + canvas_image,p)); + SetPixelRed(image,(Quantum) (((pixel >> 11) & 0x1f) << 11),q); + SetPixelGreen(image,(Quantum) (((pixel >> 5) & 0x3f) << 10),q); + SetPixelBlue(image,(Quantum) ((pixel & 0x1f) << 11),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 (status == MagickFalse) + break; + SetQuantumImageType(image,quantum_type); + /* + Proceed to next image. + */ + if (image_info->number_scenes != 0) + if (image->scene >= (image_info->scene+image_info->number_scenes-1)) + break; + if (count == (ssize_t) length) + { + /* + Allocate next image structure. + */ + AcquireNextImage(image_info,image,exception); + if (GetNextImageInList(image) == (Image *) NULL) + { + status=MagickFalse; + break; + } + image=SyncNextImageInList(image); + status=SetImageProgress(image,LoadImagesTag,TellBlob(image), + GetBlobSize(image)); + if (status == MagickFalse) + break; + } + scene++; + } while (count == (ssize_t) length); + quantum_info=DestroyQuantumInfo(quantum_info); + canvas_image=DestroyImage(canvas_image); + (void) CloseBlob(image); + if (status == MagickFalse) + return(DestroyImageList(image)); + return(GetFirstImageInList(image)); +} + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % % R e g i s t e r R G B I m a g e % % % % % @@ -1035,6 +1270,12 @@ ModuleExport size_t RegisterRGBImage(void) entry->flags|=CoderRawSupportFlag; entry->flags|=CoderEndianSupportFlag; (void) RegisterMagickInfo(entry); + entry=AcquireMagickInfo("RGB","RGB565", + "Raw red, green, blue, and opacity samples in 565 format"); + entry->decoder=(DecodeImageHandler *) ReadRGB565Image; + entry->flags|=CoderRawSupportFlag; + entry->flags|=CoderEndianSupportFlag; + (void) RegisterMagickInfo(entry); return(MagickImageCoderSignature); } diff --git a/coders/rgb.h b/coders/rgb.h index 04ac30a6a..d235c2838 100644 --- a/coders/rgb.h +++ b/coders/rgb.h @@ -20,7 +20,8 @@ #define MagickRGBAliases \ MagickCoderAlias("RGB", "RGBA") \ - MagickCoderAlias("RGB", "RGBO") + MagickCoderAlias("RGB", "RGBO") \ + MagickCoderAlias("RGB", "RGB565") #if defined(__cplusplus) || defined(c_plusplus) extern "C" { @@ -30,4 +31,4 @@ MagickCoderExports(RGB) #if defined(__cplusplus) || defined(c_plusplus) } -#endif \ No newline at end of file +#endif -- 2.40.0