From a84821e84af80bb3d4a9a6f666eea94f1f0e89ea Mon Sep 17 00:00:00 2001 From: dirk Date: Sat, 17 Sep 2016 18:31:07 +0200 Subject: [PATCH] Fixed issue where the display window was used instead of the data window. --- ChangeLog | 3 ++ coders/exr.c | 100 ++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index d4d4113bd..39850a361 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,9 @@ * Added layer RLE compression to the PSD encoder. * Added define 'psd:preserve-opacity-mask' to preserve the opacity mask in a PSD file. + * Fixed issue where the display window was used instead of the data window + when reading EXR files (reference + https://www.imagemagick.org/discourse-server/viewtopic.php?f=3&p=137849). 2016-09-05 7.0.3-0 Cristy * Release ImageMagick version 7.0.3-0, GIT revision 18786:10aa64c:20160905. diff --git a/coders/exr.c b/coders/exr.c index 6e5049b02..eabc48c6c 100644 --- a/coders/exr.c +++ b/coders/exr.c @@ -62,6 +62,18 @@ #if defined(MAGICKCORE_OPENEXR_DELEGATE) #include +/* + Typedef declaractions. +*/ +typedef struct _ExrWindow +{ + int + max_x, + max_y, + min_x, + min_y; +} ExrWindow; + /* Forward declarations. */ @@ -132,6 +144,10 @@ static MagickBooleanType IsEXR(const unsigned char *magick,const size_t length) */ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) { + ExrWindow + data_window, + display_window; + const ImfHeader *hdr_info; @@ -147,12 +163,6 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) ImfRgba *scanline; - int - max_x, - max_y, - min_x, - min_y; - MagickBooleanType status; @@ -163,6 +173,7 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) *q; ssize_t + columns, y; /* @@ -199,9 +210,10 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) return((Image *) NULL); } hdr_info=ImfInputHeader(file); - ImfHeaderDisplayWindow(hdr_info,&min_x,&min_y,&max_x,&max_y); - image->columns=max_x-min_x+1UL; - image->rows=max_y-min_y+1UL; + ImfHeaderDisplayWindow(hdr_info,&display_window.min_x,&display_window.min_y, + &display_window.max_x,&display_window.max_y); + image->columns=display_window.max_x-display_window.min_x+1UL; + image->rows=display_window.max_y-display_window.min_y+1UL; image->alpha_trait=BlendPixelTrait; SetImageColorspace(image,RGBColorspace,exception); image->gamma=1.0; @@ -217,34 +229,66 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception) status=SetImageExtent(image,image->columns,image->rows,exception); if (status == MagickFalse) return(DestroyImageList(image)); - scanline=(ImfRgba *) AcquireQuantumMemory(image->columns,sizeof(*scanline)); - if (scanline == (ImfRgba *) NULL) + ImfHeaderDataWindow(hdr_info,&data_window.min_x,&data_window.min_y, + &data_window.max_x,&data_window.max_y); + columns=(ssize_t) data_window.max_x-data_window.min_x+1UL; + if ((display_window.min_x > data_window.max_x) || + (display_window.min_x+(int) image->columns <= data_window.min_x)) + scanline=(ImfRgba *) NULL; + else { - (void) ImfCloseInputFile(file); - if (LocaleCompare(image_info->filename,read_info->filename) != 0) - (void) RelinquishUniqueFileResource(read_info->filename); - read_info=DestroyImageInfo(read_info); - ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + scanline=(ImfRgba *) AcquireQuantumMemory(columns,sizeof(*scanline)); + if (scanline == (ImfRgba *) NULL) + { + (void) ImfCloseInputFile(file); + if (LocaleCompare(image_info->filename,read_info->filename) != 0) + (void) RelinquishUniqueFileResource(read_info->filename); + read_info=DestroyImageInfo(read_info); + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } } for (y=0; y < (ssize_t) image->rows; y++) { + int + yy; + q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); if (q == (Quantum *) NULL) break; - ResetMagickMemory(scanline,0,image->columns*sizeof(*scanline)); - ImfInputSetFrameBuffer(file,scanline-min_x-image->columns*(min_y+y),1, - image->columns); - ImfInputReadPixels(file,min_y+y,min_y+y); + yy=display_window.min_y+y; + if ((yy < data_window.min_y) || (yy > data_window.max_y) || + (scanline == (ImfRgba *) NULL)) + { + for (x=0; x < (ssize_t) image->columns; x++) + { + SetPixelViaPixelInfo(image,&image->background_color,q); + q+=GetPixelChannels(image); + } + continue; + } + ResetMagickMemory(scanline,0,columns*sizeof(*scanline)); + ImfInputSetFrameBuffer(file,scanline-data_window.min_x-columns*yy,1, + columns); + ImfInputReadPixels(file,yy,yy); for (x=0; x < (ssize_t) image->columns; x++) { - SetPixelRed(image,ClampToQuantum(QuantumRange* - ImfHalfToFloat(scanline[x].r)),q); - SetPixelGreen(image,ClampToQuantum(QuantumRange* - ImfHalfToFloat(scanline[x].g)),q); - SetPixelBlue(image,ClampToQuantum(QuantumRange* - ImfHalfToFloat(scanline[x].b)),q); - SetPixelAlpha(image,ClampToQuantum(QuantumRange* - ImfHalfToFloat(scanline[x].a)),q); + int + xx; + + xx=display_window.min_x+((int) x-data_window.min_x); + if ((xx < 0) || (display_window.min_x+(int) x > data_window.max_x)) + SetPixelViaPixelInfo(image,&image->background_color,q); + else + { + SetPixelRed(image,ClampToQuantum((MagickRealType) QuantumRange* + ImfHalfToFloat(scanline[xx].r)),q); + SetPixelGreen(image,ClampToQuantum((MagickRealType) QuantumRange* + ImfHalfToFloat(scanline[xx].g)),q); + SetPixelBlue(image,ClampToQuantum((MagickRealType) QuantumRange* + ImfHalfToFloat(scanline[xx].b)),q); + SetPixelAlpha(image,ClampToQuantum((MagickRealType) QuantumRange* + ImfHalfToFloat(scanline[xx].a)),q); + } q+=GetPixelChannels(image); } if (SyncAuthenticPixels(image,exception) == MagickFalse) -- 2.40.0