]> granicus.if.org Git - imagemagick/blobdiff - coders/exr.c
(no commit message)
[imagemagick] / coders / exr.c
index 60ef9ed7fbd667b6d9edc46ab52c4b405b848b39..d4af8e1dd2de2b5a8268c1596cc8fc90235a4d7a 100644 (file)
 %            Read/Write High Dynamic-Range (HDR) Image File Format            %
 %                                                                             %
 %                              Software Design                                %
-%                                John Cristy                                  %
+%                                   Cristy                                    %
 %                                 April 2007                                  %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 /*
   Include declarations.
 */
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
-#include "magick/resource_.h"
-#include "magick/utility.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/utility.h"
 #if defined(MAGICKCORE_OPENEXR_DELEGATE)
 #include <ImfCRgbaFile.h>
 \f
@@ -64,7 +65,7 @@
   Forward declarations.
 */
 static MagickBooleanType
-  WriteEXRImage(const ImageInfo *,Image *);
+  WriteEXRImage(const ImageInfo *,Image *,ExceptionInfo *);
 #endif
 \f
 /*
@@ -151,17 +152,17 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
     min_x,
     min_y;
 
-  long
-    y;
+  MagickBooleanType
+    status;
 
-  register long
+  register ssize_t
     x;
 
-  register PixelPacket
+  register Quantum
     *q;
 
-  MagickBooleanType
-    status;
+  ssize_t
+    y;
 
   /*
     Open image.
@@ -173,7 +174,7 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
       image_info->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  image=AcquireImage(image_info);
+  image=AcquireImage(image_info,exception);
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == MagickFalse)
     {
@@ -191,14 +192,18 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
     {
       ThrowFileException(exception,BlobError,"UnableToOpenBlob",
         ImfErrorMessage());
+      if (LocaleCompare(image_info->filename,read_info->filename) != 0)
+        (void) RelinquishUniqueFileResource(read_info->filename);
       read_info=DestroyImageInfo(read_info);
       return((Image *) NULL);
     }
   hdr_info=ImfInputHeader(file);
-  ImfHeaderDataWindow(hdr_info,&min_x,&min_y,&max_x,&max_y);
+  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;
-  image->matte=MagickTrue;
+  image->alpha_trait=BlendPixelTrait;
+  SetImageColorspace(image,RGBColorspace,exception);
+  image->gamma=1.0;
   if (image_info->ping != MagickFalse)
     {
       (void) ImfCloseInputFile(file);
@@ -208,31 +213,38 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
       (void) CloseBlob(image);
       return(GetFirstImageInList(image));
     }
+  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)
     {
       (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 < (long) image->rows; y++)
+  for (y=0; y < (ssize_t) image->rows; y++)
   {
     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
-    if (q == (PixelPacket *) NULL)
+    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);
-    for (x=0; x < (long) image->columns; x++)
+    for (x=0; x < (ssize_t) image->columns; x++)
     {
-      q->red=HDRIClampToQuantum((MagickRealType) QuantumRange*ImfHalfToFloat(
-        scanline[x].r));
-      q->green=HDRIClampToQuantum((MagickRealType) QuantumRange*ImfHalfToFloat(
-        scanline[x].g));
-      q->blue=HDRIClampToQuantum((MagickRealType) QuantumRange*ImfHalfToFloat(
-        scanline[x].b));
-      q->opacity=HDRIClampToQuantum((MagickRealType) QuantumRange-QuantumRange*
-        ImfHalfToFloat(scanline[x].a));
-      q++;
+      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);
+      q+=GetPixelChannels(image);
     }
     if (SyncAuthenticPixels(image,exception) == MagickFalse)
       break;
@@ -267,10 +279,10 @@ static Image *ReadEXRImage(const ImageInfo *image_info,ExceptionInfo *exception)
 %
 %  The format of the RegisterEXRImage method is:
 %
-%      unsigned long RegisterEXRImage(void)
+%      size_t RegisterEXRImage(void)
 %
 */
-ModuleExport unsigned long RegisterEXRImage(void)
+ModuleExport size_t RegisterEXRImage(void)
 {
   MagickInfo
     *entry;
@@ -281,9 +293,9 @@ ModuleExport unsigned long RegisterEXRImage(void)
   entry->encoder=(EncodeImageHandler *) WriteEXRImage;
 #endif
   entry->magick=(IsImageFormatHandler *) IsEXR;
-  entry->adjoin=MagickFalse;
+  entry->flags^=CoderAdjoinFlag;
   entry->description=ConstantString("High Dynamic-range (HDR)");
-  entry->blob_support=MagickFalse;
+  entry->flags^=CoderBlobSupportFlag;
   entry->module=ConstantString("EXR");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
@@ -330,7 +342,8 @@ ModuleExport void UnregisterEXRImage(void)
 %
 %  The format of the WriteEXRImage method is:
 %
-%      MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image)
+%      MagickBooleanType WriteEXRImage(const ImageInfo *image_info,
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
@@ -338,8 +351,11 @@ ModuleExport void UnregisterEXRImage(void)
 %
 %    o image:  The image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
-static MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
   ImageInfo
     *write_info;
@@ -359,18 +375,18 @@ static MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image)
   int
     compression;
 
-  long
-    y;
-
   MagickBooleanType
     status;
 
-  register const PixelPacket
+  register const Quantum
     *p;
 
-  register long
+  register ssize_t
     x;
 
+  ssize_t
+    y;
+
   /*
     Open output image file.
   */
@@ -380,9 +396,12 @@ static MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image)
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickSignature);
+  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(status);
+  (void) SetImageColorspace(image,RGBColorspace,exception);
   write_info=CloneImageInfo(image_info);
   (void) AcquireUniqueFilename(write_info->filename);
   hdr_info=ImfNewHeader();
@@ -413,43 +432,47 @@ static MagickBooleanType WriteEXRImage(const ImageInfo *image_info,Image *image)
   ImfDeleteHeader(hdr_info);
   if (file == (ImfOutputFile *) NULL)
     {
-      ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
-        ImfErrorMessage());
+      (void) RelinquishUniqueFileResource(write_info->filename);
       write_info=DestroyImageInfo(write_info);
+      ThrowFileException(exception,BlobError,"UnableToOpenBlob",
+        ImfErrorMessage());
       return(MagickFalse);
     }
   scanline=(ImfRgba *) AcquireQuantumMemory(image->columns,sizeof(*scanline));
   if (scanline == (ImfRgba *) NULL)
     {
       (void) ImfCloseOutputFile(file);
+      (void) RelinquishUniqueFileResource(write_info->filename);
+      write_info=DestroyImageInfo(write_info);
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
     }
-  for (y=0; y < (long) image->rows; y++)
+  ResetMagickMemory(scanline,0,image->columns*sizeof(*scanline));
+  for (y=0; y < (ssize_t) image->rows; y++)
   {
-    p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
-    if (p == (const PixelPacket *) NULL)
+    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
+    if (p == (const Quantum *) NULL)
       break;
-    for (x=0; x < (long) image->columns; x++)
+    for (x=0; x < (ssize_t) image->columns; x++)
     {
-      ImfFloatToHalf(QuantumScale*p->red,&half_quantum);
+      ImfFloatToHalf(QuantumScale*GetPixelRed(image,p),&half_quantum);
       scanline[x].r=half_quantum;
-      ImfFloatToHalf(QuantumScale*p->green,&half_quantum);
+      ImfFloatToHalf(QuantumScale*GetPixelGreen(image,p),&half_quantum);
       scanline[x].g=half_quantum;
-      ImfFloatToHalf(QuantumScale*p->blue,&half_quantum);
+      ImfFloatToHalf(QuantumScale*GetPixelBlue(image,p),&half_quantum);
       scanline[x].b=half_quantum;
-      if (image->matte == MagickFalse)
+      if (image->alpha_trait == UndefinedPixelTrait)
         ImfFloatToHalf(1.0,&half_quantum);
       else
-        ImfFloatToHalf(1.0-QuantumScale*p->opacity,&half_quantum);
+        ImfFloatToHalf(QuantumScale*GetPixelAlpha(image,p),&half_quantum);
       scanline[x].a=half_quantum;
-      p++;
+      p+=GetPixelChannels(image);
     }
     ImfOutputSetFrameBuffer(file,scanline-(y*image->columns),1,image->columns);
     ImfOutputWritePixels(file,1);
   }
   (void) ImfCloseOutputFile(file);
   scanline=(ImfRgba *) RelinquishMagickMemory(scanline);
-  (void) FileToImage(image,write_info->filename);
+  (void) FileToImage(image,write_info->filename,exception);
   (void) RelinquishUniqueFileResource(write_info->filename);
   write_info=DestroyImageInfo(write_info);
   (void) CloseBlob(image);