]> granicus.if.org Git - imagemagick/blobdiff - coders/hdr.c
(no commit message)
[imagemagick] / coders / hdr.c
index aad4c4bc1fd656315fb4298b9199ec9e7c57496c..a35ebb5dc369b55e60814f1ea89d4446e4ce6d0a 100644 (file)
@@ -17,7 +17,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 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/colorspace.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/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/string-private.h"
-#include "magick/module.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.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/monitor.h"
+#include "MagickCore/monitor-private.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/string-private.h"
+#include "MagickCore/module.h"
 \f
 /*
   Forward declarations.
 */
 static MagickBooleanType
-  WriteHDRImage(const ImageInfo *,Image *);
+  WriteHDRImage(const ImageInfo *,Image *,ExceptionInfo *);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -151,16 +153,16 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
     status,
     value_expected;
 
-  register PixelPacket
+  register Quantum
     *q;
 
-  register unsigned char
-    *p;
-
   register ssize_t
     i,
     x;
 
+  register unsigned char
+    *p;
+
   ssize_t
     count,
     y;
@@ -180,7 +182,7 @@ static Image *ReadHDRImage(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)
     {
@@ -237,7 +239,7 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (comment == (char *) NULL)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         *p='\0';
-        (void) SetImageProperty(image,"comment",comment);
+        (void) SetImageProperty(image,"comment",comment,exception);
         comment=DestroyString(comment);
         c=ReadBlobByte(image);
       }
@@ -292,8 +294,8 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   (void) CopyMagickString(format,value,MaxTextExtent);
                   break;
                 }
-              (void) FormatMagickString(tag,MaxTextExtent,"hdr:%s",keyword);
-              (void) SetImageProperty(image,tag,value);
+              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
+              (void) SetImageProperty(image,tag,value,exception);
               break;
             }
             case 'G':
@@ -301,11 +303,11 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
             {
               if (LocaleCompare(keyword,"gamma") == 0)
                 {
-                  image->gamma=StringToDouble(value);
+                  image->gamma=StringToDouble(value,(char **) NULL);
                   break;
                 }
-              (void) FormatMagickString(tag,MaxTextExtent,"hdr:%s",keyword);
-              (void) SetImageProperty(image,tag,value);
+              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
+              (void) SetImageProperty(image,tag,value,exception);
               break;
             }
             case 'P':
@@ -331,8 +333,8 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   image->chromaticity.white_point.y=white_point[1];
                   break;
                 }
-              (void) FormatMagickString(tag,MaxTextExtent,"hdr:%s",keyword);
-              (void) SetImageProperty(image,tag,value);
+              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
+              (void) SetImageProperty(image,tag,value,exception);
               break;
             }
             case 'Y':
@@ -349,14 +351,14 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   image->rows=(size_t) height;
                   break;
                 }
-              (void) FormatMagickString(tag,MaxTextExtent,"hdr:%s",keyword);
-              (void) SetImageProperty(image,tag,value);
+              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
+              (void) SetImageProperty(image,tag,value,exception);
               break;
             }
             default:
             {
-              (void) FormatMagickString(tag,MaxTextExtent,"hdr:%s",keyword);
-              (void) SetImageProperty(image,tag,value);
+              (void) FormatLocaleString(tag,MaxTextExtent,"hdr:%s",keyword);
+              (void) SetImageProperty(image,tag,value,exception);
               break;
             }
           }
@@ -365,10 +367,15 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
       while (isspace((int) ((unsigned char) c)) != 0)
         c=ReadBlobByte(image);
   }
-  if (LocaleCompare(format,"32-bit_rle_rgbe") != 0)
+  if ((LocaleCompare(format,"32-bit_rle_rgbe") != 0) &&
+      (LocaleCompare(format,"32-bit_rle_xyze") != 0))
     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   if ((image->columns == 0) || (image->rows == 0))
     ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
+  if (LocaleCompare(format,"32-bit_rle_xyze") == 0)
+    SetImageColorspace(image,XYZColorspace,exception);
+  image->compression=(image->columns < 8) || (image->columns > 0x7ffff) ?
+    NoCompression : RLECompression;
   if (image_info->ping != MagickFalse)
     {
       (void) CloseBlob(image);
@@ -383,10 +390,10 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
   for (y=0; y < (ssize_t) image->rows; y++)
   {
-    if ((image->columns < 8) || (image->columns > 0x7ffff))
+    if (image->compression != RLECompression)
       {
-        count=ReadBlob(image,4*image->columns*sizeof(*pixel),pixel);
-        if (count != (ssize_t) (4*image->columns*sizeof(*pixel)))
+        count=ReadBlob(image,4*image->columns*sizeof(*pixels),pixels);
+        if (count != (ssize_t) (4*image->columns*sizeof(*pixels)))
           break;
       }
     else
@@ -395,48 +402,55 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
         if (count != 4)
           break;
         if ((size_t) ((((size_t) pixel[2]) << 8) | pixel[3]) != image->columns)
-          break;
-        p=pixels;
-        for (i=0; i < 4; i++)
-        {
-          end=&pixels[(i+1)*image->columns];
-          while (p < end)
           {
-            count=ReadBlob(image,2*sizeof(*pixel),pixel);
-            if (count < 1)
-              break;
-            if (pixel[0] > 128)
-              {
-                count=(ssize_t) pixel[0]-128;
-                if ((count == 0) || (count > (ssize_t) (end-p)))
-                  break;
-                while (count-- > 0)
-                  *p++=pixel[1];
-              }
-            else
+            (void) memcpy(pixels,pixel,4*sizeof(*pixel));
+            count=ReadBlob(image,4*(image->columns-1)*sizeof(*pixels),pixels+4);
+            image->compression=NoCompression;
+          }
+        else
+          {
+            p=pixels;
+            for (i=0; i < 4; i++)
+            {
+              end=&pixels[(i+1)*image->columns];
+              while (p < end)
               {
-                count=(ssize_t) pixel[0];
-                if ((count == 0) || (count > (ssize_t) (end-p)))
+                count=ReadBlob(image,2*sizeof(*pixel),pixel);
+                if (count < 1)
                   break;
-                *p++=pixel[1];
-                if (--count > 0)
+                if (pixel[0] > 128)
                   {
-                    count=ReadBlob(image,(size_t) count*sizeof(*p),p);
-                    if (count < 1)
+                    count=(ssize_t) pixel[0]-128;
+                    if ((count == 0) || (count > (ssize_t) (end-p)))
                       break;
-                    p+=count;
+                    while (count-- > 0)
+                      *p++=pixel[1];
+                  }
+                else
+                  {
+                    count=(ssize_t) pixel[0];
+                    if ((count == 0) || (count > (ssize_t) (end-p)))
+                      break;
+                    *p++=pixel[1];
+                    if (--count > 0)
+                      {
+                        count=ReadBlob(image,(size_t) count*sizeof(*p),p);
+                        if (count < 1)
+                          break;
+                        p+=count;
+                      }
                   }
               }
+            }
           }
-        }
       }
     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
-    if (q == (PixelPacket *) NULL)
+    if (q == (Quantum *) NULL)
       break;
     i=0;
     for (x=0; x < (ssize_t) image->columns; x++)
     {
-      if ((image->columns >= 8) && (image->columns <= 0x7ffff))
+      if (image->compression == RLECompression)
         {
           pixel[0]=pixels[x];
           pixel[1]=pixels[x+image->columns];
@@ -450,17 +464,17 @@ static Image *ReadHDRImage(const ImageInfo *image_info,ExceptionInfo *exception)
           pixel[2]=pixels[i++];
           pixel[3]=pixels[i++];
         }
-      q->red=0;
-      q->green=0;
-      q->blue=0;
+      SetPixelRed(image,0,q);
+      SetPixelGreen(image,0,q);
+      SetPixelBlue(image,0,q);
       if (pixel[3] != 0)
         {
           gamma=pow(2.0,pixel[3]-(128.0+8.0));
-          q->red=ClampToQuantum(QuantumRange*gamma*pixel[0]);
-          q->green=ClampToQuantum(QuantumRange*gamma*pixel[1]);
-          q->blue=ClampToQuantum(QuantumRange*gamma*pixel[2]);
+          SetPixelRed(image,ClampToQuantum(QuantumRange*gamma*pixel[0]),q);
+          SetPixelGreen(image,ClampToQuantum(QuantumRange*gamma*pixel[1]),q);
+          SetPixelBlue(image,ClampToQuantum(QuantumRange*gamma*pixel[2]),q);
         }
-      q++;
+      q+=GetPixelChannels(image);
     }
     if (SyncAuthenticPixels(image,exception) == MagickFalse)
       break;
@@ -554,7 +568,7 @@ ModuleExport void UnregisterHDRImage(void)
 %  The format of the WriteHDRImage method is:
 %
 %      MagickBooleanType WriteHDRImage(const ImageInfo *image_info,
-%        Image *image)
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
@@ -628,7 +642,8 @@ static size_t HDRWriteRunlengthPixels(Image *image,unsigned char *pixels)
   return(p);
 }
 
-static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
   char
     header[MaxTextExtent];
@@ -639,7 +654,7 @@ static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
   MagickBooleanType
     status;
 
-  register const PixelPacket
+  register const Quantum
     *p;
 
   register ssize_t
@@ -666,37 +681,39 @@ static MagickBooleanType WriteHDRImage(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);
-  if (image->colorspace != RGBColorspace)
-    (void) TransformImageColorspace(image,RGBColorspace);
+  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
+    (void) TransformImageColorspace(image,sRGBColorspace,exception);
   /*
     Write header.
   */
   (void) ResetMagickMemory(header,' ',MaxTextExtent);
   length=CopyMagickString(header,"#?RGBE\n",MaxTextExtent);
   (void) WriteBlob(image,length,(unsigned char *) header);
-  property=GetImageProperty(image,"comment");
+  property=GetImageProperty(image,"comment",exception);
   if ((property != (const char *) NULL) &&
       (strchr(property,'\n') == (char *) NULL))
     {
-      count=FormatMagickString(header,MaxTextExtent,"#%s\n",property);
+      count=FormatLocaleString(header,MaxTextExtent,"#%s\n",property);
       (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
     }
-  property=GetImageProperty(image,"hdr:exposure");
+  property=GetImageProperty(image,"hdr:exposure",exception);
   if (property != (const char *) NULL)
     {
-      count=FormatMagickString(header,MaxTextExtent,"EXPOSURE=%g\n",
+      count=FormatLocaleString(header,MaxTextExtent,"EXPOSURE=%g\n",
         atof(property));
       (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
     }
   if (image->gamma != 0.0)
     {
-      count=FormatMagickString(header,MaxTextExtent,"GAMMA=%g\n",image->gamma);
+      count=FormatLocaleString(header,MaxTextExtent,"GAMMA=%g\n",image->gamma);
       (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
     }
-  count=FormatMagickString(header,MaxTextExtent,
+  count=FormatLocaleString(header,MaxTextExtent,
     "PRIMARIES=%g %g %g %g %g %g %g %g\n",
     image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
     image->chromaticity.green_primary.x,image->chromaticity.green_primary.y,
@@ -705,20 +722,20 @@ static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
   (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
   length=CopyMagickString(header,"FORMAT=32-bit_rle_rgbe\n\n",MaxTextExtent);
   (void) WriteBlob(image,length,(unsigned char *) header);
-  count=FormatMagickString(header,MaxTextExtent,"-Y %.20g +X %.20g\n",
+  count=FormatLocaleString(header,MaxTextExtent,"-Y %.20g +X %.20g\n",
     (double) image->rows,(double) image->columns);
   (void) WriteBlob(image,(size_t) count,(unsigned char *) header);
   /*
     Write HDR pixels.
   */
-  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,
-    4*sizeof(*pixels));
+  pixels=(unsigned char *) AcquireQuantumMemory(image->columns,4*
+    sizeof(*pixels));
   if (pixels == (unsigned char *) NULL)
     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   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;
     if ((image->columns >= 8) && (image->columns <= 0x7ffff))
       {
@@ -740,20 +757,20 @@ static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
       pixel[1]=0;
       pixel[2]=0;
       pixel[3]=0;
-      gamma=QuantumScale*p->red;
-      if ((QuantumScale*p->green) > gamma)
-        gamma=QuantumScale*p->green;
-      if ((QuantumScale*p->blue) > gamma)
-        gamma=QuantumScale*p->blue;
+      gamma=QuantumScale*GetPixelRed(image,p);
+      if ((QuantumScale*GetPixelGreen(image,p)) > gamma)
+        gamma=QuantumScale*GetPixelGreen(image,p);
+      if ((QuantumScale*GetPixelBlue(image,p)) > gamma)
+        gamma=QuantumScale*GetPixelBlue(image,p);
       if (gamma > MagickEpsilon)
         {
           int
             exponent;
 
           gamma=frexp(gamma,&exponent)*256.0/gamma;
-          pixel[0]=(unsigned char) (gamma*QuantumScale*p->red);
-          pixel[1]=(unsigned char) (gamma*QuantumScale*p->green);
-          pixel[2]=(unsigned char) (gamma*QuantumScale*p->blue);
+          pixel[0]=(unsigned char) (gamma*QuantumScale*GetPixelRed(image,p));
+          pixel[1]=(unsigned char) (gamma*QuantumScale*GetPixelGreen(image,p));
+          pixel[2]=(unsigned char) (gamma*QuantumScale*GetPixelBlue(image,p));
           pixel[3]=(unsigned char) (exponent+128);
         }
       if ((image->columns >= 8) && (image->columns <= 0x7ffff))
@@ -770,7 +787,7 @@ static MagickBooleanType WriteHDRImage(const ImageInfo *image_info,Image *image)
           pixels[i++]=pixel[2];
           pixels[i++]=pixel[3];
         }
-      p++;
+      p+=GetPixelChannels(image);
     }
     if ((image->columns >= 8) && (image->columns <= 0x7ffff))
       {