]> granicus.if.org Git - imagemagick/blobdiff - coders/ps3.c
Accommodate background color index in PLTE chunk
[imagemagick] / coders / ps3.c
index bd720f8d6f9ed32e3794be52b02590607df2c36c..c80881b31761f22a0b50938e34f827a689949159 100644 (file)
@@ -18,7 +18,7 @@
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2010 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/color.h"
-#include "magick/color-private.h"
-#include "magick/compress.h"
-#include "magick/constitute.h"
-#include "magick/draw.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/geometry.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/option.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/resource_.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
-#include "magick/token.h"
-#include "magick/utility.h"
-#include "magick/module.h"
+#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/color.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/compress.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/draw.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/geometry.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/option.h"
+#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/token.h"
+#include "MagickCore/utility.h"
+#include "MagickCore/module.h"
 \f
 /*
   Define declarations.
@@ -96,7 +99,7 @@
   Forward declarations.
 */
 static MagickBooleanType
-  WritePS3Image(const ImageInfo *,Image *);
+  WritePS3Image(const ImageInfo *,Image *,ExceptionInfo *);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -129,11 +132,13 @@ ModuleExport size_t RegisterPS3Image(void)
   entry->encoder=(EncodeImageHandler *) WritePS3Image;
   entry->description=ConstantString("Level III Encapsulated PostScript");
   entry->module=ConstantString("PS3");
+  entry->seekable_stream=MagickTrue;
   (void) RegisterMagickInfo(entry);
   entry=SetMagickInfo("PS3");
   entry->encoder=(EncodeImageHandler *) WritePS3Image;
   entry->description=ConstantString("Level III PostScript");
   entry->module=ConstantString("PS3");
+  entry->seekable_stream=MagickTrue;
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
 }
@@ -181,7 +186,8 @@ ModuleExport void UnregisterPS3Image(void)
 %
 %  The format of the WritePS3Image method is:
 %
-%      MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
+%      MagickBooleanType WritePS3Image(const ImageInfo *image_info,
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -189,10 +195,12 @@ ModuleExport void UnregisterPS3Image(void)
 %
 %    o image: the image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 
 static MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info,
-  Image *image,Image *inject_image)
+  Image *image,Image *inject_image,ExceptionInfo *exception)
 {
   Image
     *group4_image;
@@ -213,11 +221,11 @@ static MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info,
   write_info=CloneImageInfo(image_info);
   (void) CopyMagickString(write_info->filename,"GROUP4:",MaxTextExtent);
   (void) CopyMagickString(write_info->magick,"GROUP4",MaxTextExtent);
-  group4_image=CloneImage(inject_image,0,0,MagickTrue,&image->exception);
+  group4_image=CloneImage(inject_image,0,0,MagickTrue,exception);
   if (group4_image == (Image *) NULL)
     return(MagickFalse);
   group4=(unsigned char *) ImageToBlob(write_info,group4_image,&length,
-    &image->exception);
+    exception);
   group4_image=DestroyImage(group4_image);
   if (group4 == (unsigned char *) NULL)
     return(MagickFalse);
@@ -228,20 +236,13 @@ static MagickBooleanType Huffman2DEncodeImage(const ImageInfo *image_info,
   return(status);
 }
 
-
 static MagickBooleanType SerializeImage(const ImageInfo *image_info,
-  Image *image,unsigned char **pixels,size_t *length)
+  Image *image,unsigned char **pixels,size_t *length,ExceptionInfo *exception)
 {
-  ssize_t
-    y;
-
   MagickBooleanType
     status;
 
-  register const IndexPacket
-    *indexes;
-
-  register const PixelPacket
+  register const Quantum
     *p;
 
   register ssize_t
@@ -250,44 +251,46 @@ static MagickBooleanType SerializeImage(const ImageInfo *image_info,
   register unsigned char
     *q;
 
+  ssize_t
+    y;
+
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   status=MagickTrue;
-  *length=(image->colorspace == CMYKColorspace ? 4 : 3)*
-    (size_t) image->columns*image->rows;
+  *length=(image->colorspace == CMYKColorspace ? 4 : 3)*(size_t)
+    image->columns*image->rows;
   *pixels=(unsigned char *) AcquireQuantumMemory(*length,sizeof(**pixels));
   if (*pixels == (unsigned char *) NULL)
     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   q=(*pixels);
   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;
-    indexes=GetVirtualIndexQueue(image);
     if (image->colorspace != CMYKColorspace)
       for (x=0; x < (ssize_t) image->columns; x++)
       {
-        *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
-        *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
-        *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
-        p++;
+        *q++=ScaleQuantumToChar(GetPixelRed(image,p));
+        *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
+        *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
+        p+=GetPixelChannels(image);
       }
     else
       for (x=0; x < (ssize_t) image->columns; x++)
       {
-        *q++=ScaleQuantumToChar(GetRedPixelComponent(p));
-        *q++=ScaleQuantumToChar(GetGreenPixelComponent(p));
-        *q++=ScaleQuantumToChar(GetBluePixelComponent(p));
-        *q++=ScaleQuantumToChar(indexes[x]);
-        p++;
+        *q++=ScaleQuantumToChar(GetPixelRed(image,p));
+        *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
+        *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
+        *q++=ScaleQuantumToChar(GetPixelBlack(image,p));
+        p+=GetPixelChannels(image);
       }
     if (image->previous == (Image *) NULL)
       {
         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
-                image->rows);
+          image->rows);
         if (status == MagickFalse)
           break;
       }
@@ -298,15 +301,12 @@ static MagickBooleanType SerializeImage(const ImageInfo *image_info,
 }
 
 static MagickBooleanType SerializeImageChannel(const ImageInfo *image_info,
-  Image *image,unsigned char **pixels,size_t *length)
+  Image *image,unsigned char **pixels,size_t *length,ExceptionInfo *exception)
 {
-  ssize_t
-    y;
-
   MagickBooleanType
     status;
 
-  register const PixelPacket
+  register const Quantum
     *p;
 
   register ssize_t
@@ -315,20 +315,23 @@ static MagickBooleanType SerializeImageChannel(const ImageInfo *image_info,
   register unsigned char
     *q;
 
-  unsigned char
-    code,
-    bit;
-
   size_t
     pack,
     padded_columns;
 
+  ssize_t
+    y;
+
+  unsigned char
+    code,
+    bit;
+
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   status=MagickTrue;
-  pack=IsMonochromeImage(image,&image->exception) == MagickFalse ? 1UL : 8UL;
+  pack=IsImageMonochrome(image,exception) == MagickFalse ? 1UL : 8UL;
   padded_columns=((image->columns+pack-1)/pack)*pack;
   *length=(size_t) padded_columns*image->rows/pack;
   *pixels=(unsigned char *) AcquireQuantumMemory(*length,sizeof(**pixels));
@@ -337,14 +340,14 @@ static MagickBooleanType SerializeImageChannel(const ImageInfo *image_info,
   q=(*pixels);
   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 (pack == 1)
       for (x=0; x < (ssize_t) image->columns; x++)
       {
-        *q++=ScaleQuantumToChar(PixelIntensityToQuantum(p));
-        p++;
+        *q++=ScaleQuantumToChar(GetPixelIntensity(image,p));
+        p+=GetPixelChannels(image);
       }
     else
       {
@@ -353,19 +356,19 @@ static MagickBooleanType SerializeImageChannel(const ImageInfo *image_info,
         {
           bit=(unsigned char) 0x00;
           if (x < (ssize_t) image->columns)
-            bit=(unsigned char) (PixelIntensityToQuantum(p) ==
-              (Quantum) TransparentOpacity ? 0x01 : 0x00);
+            bit=(unsigned char) (GetPixelIntensity(image,p) == (Quantum)
+              TransparentAlpha ? 0x01 : 0x00);
           code=(code << 1)+bit;
           if (((x+1) % pack) == 0)
             {
               *q++=code;
               code='\0';
             }
-          p++;
+          p+=GetPixelChannels(image);
         }
       }
     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
-                image->rows);
+      image->rows);
     if (status == MagickFalse)
       break;
   }
@@ -375,18 +378,12 @@ static MagickBooleanType SerializeImageChannel(const ImageInfo *image_info,
 }
 
 static MagickBooleanType SerializeImageIndexes(const ImageInfo *image_info,
-  Image *image,unsigned char **pixels,size_t *length)
+  Image *image,unsigned char **pixels,size_t *length,ExceptionInfo *exception)
 {
-  ssize_t
-    y;
-
   MagickBooleanType
     status;
 
-  register const IndexPacket
-    *indexes;
-
-  register const PixelPacket
+  register const Quantum
     *p;
 
   register ssize_t
@@ -395,6 +392,9 @@ static MagickBooleanType SerializeImageIndexes(const ImageInfo *image_info,
   register unsigned char
     *q;
 
+  ssize_t
+    y;
+
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
@@ -407,16 +407,18 @@ static MagickBooleanType SerializeImageIndexes(const ImageInfo *image_info,
   q=(*pixels);
   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;
-    indexes=GetVirtualIndexQueue(image);
     for (x=0; x < (ssize_t) image->columns; x++)
-      *q++=(unsigned char) indexes[x];
+    {
+      *q++=(unsigned char) GetPixelIndex(image,p);
+      p+=GetPixelChannels(image);
+    }
     if (image->previous == (Image *) NULL)
       {
         status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
-                image->rows);
+          image->rows);
         if (status == MagickFalse)
           break;
       }
@@ -427,7 +429,7 @@ static MagickBooleanType SerializeImageIndexes(const ImageInfo *image_info,
 }
 
 static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
-  Image *image,const CompressionType compression)
+  Image *image,const CompressionType compression,ExceptionInfo *exception)
 {
   char
     buffer[MaxTextExtent];
@@ -464,9 +466,9 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
     Note BeginData DSC comment for update later.
   */
   start=TellBlob(image);
-  (void) FormatMagickString(buffer,MaxTextExtent,
-    "%%%%BeginData:%13ld %s Bytes\n",0L,
-    compression == NoCompression ? "ASCII" : "BINARY");
+  (void) FormatLocaleString(buffer,MaxTextExtent,
+    "%%%%BeginData:%13ld %s Bytes\n",0L,compression == NoCompression ?
+    "ASCII" : "BINARY");
   (void) WriteBlobString(image,buffer);
   stop=TellBlob(image);
   /*
@@ -477,54 +479,48 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
     case NoCompression:
     default:
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
-        "currentfile %lu %lu "PS3_NoCompression" ByteStreamDecodeFilter\n",
-        (unsigned long) image->columns,(unsigned long) image->rows);
+      (void) FormatLocaleString(buffer,MaxTextExtent,
+        "currentfile %.20g %.20g "PS3_NoCompression" ByteStreamDecodeFilter\n",
+        (double) image->columns,(double) image->rows);
       break;
     }
     case FaxCompression:
     case Group4Compression:
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
-        "currentfile %lu %lu "PS3_FaxCompression" ByteStreamDecodeFilter\n",
-        (unsigned long) image->columns,(unsigned long) image->rows);
+      (void) FormatLocaleString(buffer,MaxTextExtent,
+        "currentfile %.20g %.20g "PS3_FaxCompression" ByteStreamDecodeFilter\n",
+        (double) image->columns,(double) image->rows);
       break;
     }
     case LZWCompression:
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
-        "currentfile %lu %lu "PS3_LZWCompression" ByteStreamDecodeFilter\n",
-        (unsigned long) image->columns,(unsigned long) image->rows);
+      (void) FormatLocaleString(buffer,MaxTextExtent,
+        "currentfile %.20g %.20g "PS3_LZWCompression" ByteStreamDecodeFilter\n",
+        (double) image->columns,(double) image->rows);
       break;
     }
     case RLECompression:
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
-        "currentfile %lu %lu "PS3_RLECompression" ByteStreamDecodeFilter\n",
-        (unsigned long) image->columns,(unsigned long) image->rows);
+      (void) FormatLocaleString(buffer,MaxTextExtent,
+        "currentfile %.20g %.20g "PS3_RLECompression" ByteStreamDecodeFilter\n",
+        (double) image->columns,(double) image->rows);
       break;
     }
     case ZipCompression:
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
-        "currentfile %lu %lu "PS3_ZipCompression" ByteStreamDecodeFilter\n",
-        (unsigned long) image->columns,(unsigned long) image->rows);
+      (void) FormatLocaleString(buffer,MaxTextExtent,
+        "currentfile %.20g %.20g "PS3_ZipCompression" ByteStreamDecodeFilter\n",
+        (double) image->columns,(double) image->rows);
       break;
     }
   }
   (void) WriteBlobString(image,buffer);
   (void) WriteBlobString(image,"/ReusableStreamDecode filter\n");
-  mask_image=CloneImage(image,0,0,MagickTrue,&image->exception);
+  mask_image=SeparateImage(image,AlphaChannel,exception);
   if (mask_image == (Image *) NULL)
-    ThrowWriterException(CoderError,image->exception.reason);
-  status=SeparateImageChannel(mask_image,OpacityChannel);
-  if (status == MagickFalse)
-    {
-      mask_image=DestroyImage(mask_image);
-      return(MagickFalse);
-    }
-  (void) SetImageType(mask_image,BilevelType);
-  (void) SetImageType(mask_image,PaletteType);
+    ThrowWriterException(CoderError,exception->reason);
+  (void) SetImageType(mask_image,BilevelType,exception);
+  (void) SetImageType(mask_image,PaletteType,exception);
   mask_image->matte=MagickFalse;
   pixels=(unsigned char *) NULL;
   length=0;
@@ -533,7 +529,8 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
     case NoCompression:
     default:
     {
-      status=SerializeImageChannel(image_info,mask_image,&pixels,&length);
+      status=SerializeImageChannel(image_info,mask_image,&pixels,&length,
+        exception);
       if (status == MagickFalse)
         break;
       Ascii85Initialize(image);
@@ -548,35 +545,38 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
     {
       if ((compression == FaxCompression) ||
           (LocaleCompare(CCITTParam,"0") == 0))
-        status=HuffmanEncodeImage(image_info,image,mask_image);
+        status=HuffmanEncodeImage(image_info,image,mask_image,exception);
       else
-        status=Huffman2DEncodeImage(image_info,image,mask_image);
+        status=Huffman2DEncodeImage(image_info,image,mask_image,exception);
       break;
     }
     case LZWCompression:
     {
-      status=SerializeImageChannel(image_info,mask_image,&pixels,&length);
+      status=SerializeImageChannel(image_info,mask_image,&pixels,&length,
+        exception);
       if (status == MagickFalse)
         break;
-      status=LZWEncodeImage(image,length,pixels);
+      status=LZWEncodeImage(image,length,pixels,exception);
       pixels=(unsigned char *) RelinquishMagickMemory(pixels);
       break;
     }
     case RLECompression:
     {
-      status=SerializeImageChannel(image_info,mask_image,&pixels,&length);
+      status=SerializeImageChannel(image_info,mask_image,&pixels,&length,
+        exception);
       if (status == MagickFalse)
         break;
-      status=PackbitsEncodeImage(image,length,pixels);
+      status=PackbitsEncodeImage(image,length,pixels,exception);
       pixels=(unsigned char *) RelinquishMagickMemory(pixels);
       break;
     }
     case ZipCompression:
     {
-      status=SerializeImageChannel(image_info,mask_image,&pixels,&length);
+      status=SerializeImageChannel(image_info,mask_image,&pixels,&length,
+        exception);
       if (status == MagickFalse)
         break;
-      status=ZLIBEncodeImage(image,length,pixels);
+      status=ZLIBEncodeImage(image,length,pixels,exception);
       pixels=(unsigned char *) RelinquishMagickMemory(pixels);
       break;
     }
@@ -588,7 +588,7 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
   offset=SeekBlob(image,start,SEEK_SET);
   if (offset < 0)
     ThrowWriterException(CorruptImageError,"ImproperImageHeader");
-  (void) FormatMagickString(buffer,MaxTextExtent,
+  (void) FormatLocaleString(buffer,MaxTextExtent,
     "%%%%BeginData:%13ld %s Bytes\n",(long) length,
     compression == NoCompression ? "ASCII" : "BINARY");
   (void) WriteBlobString(image,buffer);
@@ -600,7 +600,8 @@ static MagickBooleanType WritePS3MaskImage(const ImageInfo *image_info,
   return(status);
 }
 
-static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
   static const char
     *PostscriptProlog[]=
@@ -812,9 +813,6 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
   GeometryInfo
     geometry_info;
 
-  ssize_t
-    j;
-
   MagickBooleanType
     status;
 
@@ -844,7 +842,13 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     bounds;
 
   size_t
-    length;
+    length,
+    page,
+    pixel,
+    text_size;
+
+  ssize_t
+    j;
 
   time_t
     timer;
@@ -852,11 +856,6 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
   unsigned char
     *pixels;
 
-  size_t
-    page,
-    pixel,
-    text_size;
-
   /*
     Open output image file.
   */
@@ -866,7 +865,9 @@ static MagickBooleanType WritePS3Image(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(MagickFalse);
   compression=image->compression;
@@ -877,7 +878,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     case FaxCompression:
     case Group4Compression:
     { 
-      if ((IsMonochromeImage(image,&image->exception) == MagickFalse) ||
+      if ((IsImageMonochrome(image,exception) == MagickFalse) ||
           (image->matte != MagickFalse))
         compression=RLECompression;
       break;
@@ -886,7 +887,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     case JPEGCompression:
     {
       compression=RLECompression;
-      (void) ThrowMagickException(&image->exception,GetMagickModule(),
+      (void) ThrowMagickException(exception,GetMagickModule(),
         MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (JPEG)",
         image->filename);
       break;
@@ -896,7 +897,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     case ZipCompression:
     {
       compression=RLECompression;
-      (void) ThrowMagickException(&image->exception,GetMagickModule(),
+      (void) ThrowMagickException(exception,GetMagickModule(),
         MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (ZLIB)",
         image->filename);
       break;
@@ -915,8 +916,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     */
     delta.x=DefaultResolution;
     delta.y=DefaultResolution;
-    resolution.x=image->x_resolution;
-    resolution.y=image->y_resolution;
+    resolution.x=image->resolution.x;
+    resolution.y=image->resolution.y;
     if ((resolution.x == 0.0) || (resolution.y == 0.0))
       {
         flags=ParseGeometry(PSDensityGeometry,&geometry_info);
@@ -939,15 +940,15 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
         resolution.y=(size_t) (100.0*2.54*resolution.y+0.5)/100.0;
       }
     SetGeometry(image,&geometry);
-    (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu",
-      (unsigned long) image->columns,(unsigned long) image->rows);
+    (void) FormatLocaleString(page_geometry,MaxTextExtent,"%.20gx%.20g",
+      (double) image->columns,(double) image->rows);
     if (image_info->page != (char *) NULL)
       (void) CopyMagickString(page_geometry,image_info->page,MaxTextExtent);
     else
       if ((image->page.width != 0) && (image->page.height != 0))
-        (void) FormatMagickString(page_geometry,MaxTextExtent,"%lux%lu%+ld%+ld",
-          (unsigned long) image->page.width,(unsigned long) image->page.height,
-          (long) image->page.x,(long) image->page.y);
+        (void) FormatLocaleString(page_geometry,MaxTextExtent,
+          "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,(double)
+          image->page.height,(double) image->page.x,(double) image->page.y);
       else
         if ((image->gravity != UndefinedGravity) &&
             (LocaleCompare(image_info->magick,"PS") == 0))
@@ -960,8 +961,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     scale.y=(double) (geometry.height*delta.y)/resolution.y;
     geometry.height=(size_t) floor(scale.y+0.5);
     (void) ParseAbsoluteGeometry(page_geometry,&media_info);
-    (void) ParseGravityGeometry(image,page_geometry,&page_info,
-      &image->exception);
+    (void) ParseGravityGeometry(image,page_geometry,&page_info,exception);
     if (image->gravity != UndefinedGravity)
       {
         geometry.x=(-page_info.x);
@@ -971,7 +971,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     if (image_info->pointsize != 0.0)
       pointsize=image_info->pointsize;
     text_size=0;
-    value=GetImageProperty(image,"label");
+    value=GetImageProperty(image,"label",exception);
     if (value != (const char *) NULL)
       text_size=(size_t) (MultilineCensus(value)*pointsize+12);
     page++;
@@ -986,15 +986,15 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
           (void) CopyMagickString(buffer,"%!PS-Adobe-3.0 EPSF-3.0\n",
             MaxTextExtent);
         (void) WriteBlobString(image,buffer);
-        (void) FormatMagickString(buffer,MaxTextExtent,
+        (void) FormatLocaleString(buffer,MaxTextExtent,
           "%%%%Creator: ImageMagick %s\n",MagickLibVersionText);
         (void) WriteBlobString(image,buffer);
-        (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Title: %s\n",
+        (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Title: %s\n",
           image->filename);
         (void) WriteBlobString(image,buffer);
         timer=time((time_t *) NULL);
         (void) FormatMagickTime(timer,MaxTextExtent,date);
-        (void) FormatMagickString(buffer,MaxTextExtent,
+        (void) FormatLocaleString(buffer,MaxTextExtent,
           "%%%%CreationDate: %s\n",date);
         (void) WriteBlobString(image,buffer);
         bounds.x1=(double) geometry.x;
@@ -1009,11 +1009,11 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
           }
         else
           {
-            (void) FormatMagickString(buffer,MaxTextExtent,
+            (void) FormatLocaleString(buffer,MaxTextExtent,
               "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5),
               floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5));
             (void) WriteBlobString(image,buffer);
-            (void) FormatMagickString(buffer,MaxTextExtent,
+            (void) FormatLocaleString(buffer,MaxTextExtent,
               "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,
               bounds.y1,bounds.x2,bounds.y2);
             (void) WriteBlobString(image,buffer);
@@ -1021,14 +1021,14 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
               (void) WriteBlobString(image,
                 "%%DocumentProcessColors: Cyan Magenta Yellow Black\n");
             else
-              if (IsGrayImage(image,&image->exception) != MagickFalse)
+              if (IsImageGray(image,exception) != MagickFalse)
                 (void) WriteBlobString(image,
                   "%%DocumentProcessColors: Black\n");
           }
         /*
           Font resources
         */
-        value=GetImageProperty(image,"label");
+        value=GetImageProperty(image,"label",exception);
         if (value != (const char *) NULL)
           (void) WriteBlobString(image,
             "%%DocumentNeededResources: font Helvetica\n");
@@ -1045,8 +1045,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
             if (image_info->adjoin == MagickFalse)
               (void) CopyMagickString(buffer,"%%Pages: 1\n",MaxTextExtent);
             else
-              (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Pages: %lu\n",
-                (unsigned long) GetImageListLength(image));
+              (void) FormatLocaleString(buffer,MaxTextExtent,
+                "%%%%Pages: %.20g\n",(double) GetImageListLength(image));
             (void) WriteBlobString(image,buffer);
           }
         (void) WriteBlobString(image,"%%EndComments\n");
@@ -1062,7 +1062,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
         /*
           One label line for each line in label string.
         */
-        value=GetImageProperty(image,"label");
+        value=GetImageProperty(image,"label",exception);
         if (value != (const char *) NULL)
           {
               (void) WriteBlobString(image,"\n  %% Labels.\n  /Helvetica "
@@ -1071,7 +1071,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
             {
               (void) WriteBlobString(image,
                 "  currentfile buffer readline pop token pop\n");
-              (void) FormatMagickString(buffer,MaxTextExtent,
+              (void) FormatLocaleString(buffer,MaxTextExtent,
                 "  0 y %g add moveto show pop\n",i*pointsize+12);
               (void) WriteBlobString(image,buffer);
             }
@@ -1086,16 +1086,16 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
         }
         (void)WriteBlobString(image,"%%EndProlog\n");
       }
-    (void) FormatMagickString(buffer,MaxTextExtent,"%%%%Page: 1 %lu\n",
-      (unsigned long) page);
+    (void) FormatLocaleString(buffer,MaxTextExtent,"%%%%Page: 1 %.20g\n",
+      (double) page);
     (void) WriteBlobString(image,buffer);
     /*
       Page bounding box.
     */
-    (void) FormatMagickString(buffer,MaxTextExtent,
-      "%%%%PageBoundingBox: %ld %ld %ld %ld\n",(long) geometry.x,(long)
-       geometry.y,geometry.x+(long) geometry.width,geometry.y+(long)
-       (geometry.height+text_size));
+    (void) FormatLocaleString(buffer,MaxTextExtent,
+      "%%%%PageBoundingBox: %.20g %.20g %.20g %.20g\n",(double) geometry.x,
+       (double) geometry.y,geometry.x+(double) geometry.width,geometry.y+
+       (double) (geometry.height+text_size));
     (void) WriteBlobString(image,buffer);
     /*
       Page process colors if not RGB.
@@ -1104,7 +1104,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
       (void) WriteBlobString(image,
         "%%PageProcessColors: Cyan Magenta Yellow Black\n");
     else
-      if (IsGrayImage(image,&image->exception) != MagickFalse)
+      if (IsImageGray(image,exception) != MagickFalse)
         (void) WriteBlobString(image,"%%PageProcessColors: Black\n");
     /*
       Adjust document bounding box to bound page bounding box.
@@ -1120,21 +1120,21 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     /*
       Page font resource if there's a label.
     */
-    value=GetImageProperty(image,"label");
+    value=GetImageProperty(image,"label",exception);
     if (value != (const char *) NULL)
       (void) WriteBlobString(image,"%%PageResources: font Helvetica\n");
     /*
       PS clipping path from Photoshop clipping path.
     */
-    if ((image->clip_mask == (Image *) NULL) ||
-        (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) != 0))
+    if ((image->mask != MagickFalse) ||
+        (LocaleNCompare("8BIM:",image->magick_filename,5) != 0))
       (void) WriteBlobString(image,"/ClipImage {} def\n");
     else
       {
         const char
           *value;
 
-        value=GetImageProperty(image,image->clip_mask->magick_filename);
+        value=GetImageProperty(image,image->magick_filename,exception);
         if (value == (const char *) NULL)
           return(MagickFalse);
         (void) WriteBlobString(image,value);
@@ -1149,7 +1149,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
       Image mask.
     */
     if ((image->matte != MagickFalse) &&
-        (WritePS3MaskImage(image_info,image,compression) == MagickFalse))
+        (WritePS3MaskImage(image_info,image,compression,exception) == MagickFalse))
       {
         (void) CloseBlob(image);
         return(MagickFalse);
@@ -1158,7 +1158,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
       Remember position of BeginData comment so we can update it.
     */
     start=TellBlob(image);
-    (void) FormatMagickString(buffer,MaxTextExtent,
+    (void) FormatLocaleString(buffer,MaxTextExtent,
       "%%%%BeginData:%13ld %s Bytes\n",0L,
       compression == NoCompression ? "ASCII" : "BINARY");
     (void) WriteBlobString(image,buffer);
@@ -1167,14 +1167,14 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     /*
       Translate, scale, and font point size.
     */
-    (void) FormatMagickString(buffer,MaxTextExtent,"%ld %ld\n%g %g\n%g\n",
-      (long) geometry.x,(long) geometry.y,scale.x,scale.y,pointsize);
+    (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n%g %g\n%g\n",
+      (double) geometry.x,(double) geometry.y,scale.x,scale.y,pointsize);
     (void) WriteBlobString(image,buffer);
     /*
       Output labels.
     */
     labels=(char **) NULL;
-    value=GetImageProperty(image,"label");
+    value=GetImageProperty(image,"label",exception);
     if (value != (const char *) NULL)
       labels=StringToList(value);
     if (labels != (char **) NULL)
@@ -1202,8 +1202,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     /*
       Photoshop clipping path active?
     */
-    if ((image->clip_mask != (Image *) NULL) &&
-        (LocaleNCompare("8BIM:",image->clip_mask->magick_filename,5) == 0))
+    if ((image->mask != MagickFalse) &&
+        (LocaleNCompare("8BIM:",image->magick_filename,5) == 0))
         (void) WriteBlobString(image,"true\n");
       else
         (void) WriteBlobString(image,"false\n");
@@ -1215,10 +1215,9 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     /*
       Image columns, rows, and color space.
     */
-    (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n%s\n",
-      (unsigned long) image->columns,(unsigned long) image->rows,
-      image->colorspace == CMYKColorspace ? PS3_CMYKColorspace :
-      PS3_RGBColorspace);
+    (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g %.20g\n%s\n",
+      (double) image->columns,(double) image->rows,image->colorspace ==
+      CMYKColorspace ? PS3_CMYKColorspace : PS3_RGBColorspace);
     (void) WriteBlobString(image,buffer);
     /*
       Masked image?
@@ -1230,7 +1229,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     */
     option=GetImageOption(image_info,"ps3:imagemask");
     (void) WriteBlobString(image,((option != (const char *) NULL) &&
-      (IsMonochromeImage(image,&image->exception) != MagickFalse)) ?
+      (IsImageMonochrome(image,exception) != MagickFalse)) ?
       "true\n" : "false\n");
     /*
       Output pixel data.
@@ -1242,8 +1241,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
         (image_info->type != ColorSeparationType) &&
         (image_info->type != ColorSeparationMatteType) &&
         (image->colorspace != CMYKColorspace) &&
-        ((IsGrayImage(image,&image->exception) != MagickFalse) ||
-         (IsMonochromeImage(image,&image->exception) != MagickFalse)))
+        ((IsImageGray(image,exception) != MagickFalse) ||
+         (IsImageMonochrome(image,exception) != MagickFalse)))
       {
         /*
           Gray images.
@@ -1291,27 +1290,27 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
         /*
           1 bit or 8 bit components?
         */
-        (void) FormatMagickString(buffer,MaxTextExtent,"%d\n",
-          IsMonochromeImage(image,&image->exception) != MagickFalse ? 1 : 8);
+        (void) FormatLocaleString(buffer,MaxTextExtent,"%d\n",
+          IsImageMonochrome(image,exception) != MagickFalse ? 1 : 8);
         (void) WriteBlobString(image,buffer);
         /*
           Image data.
         */
         if (compression == JPEGCompression)
-          status=InjectImageBlob(image_info,image,image,"jpeg",
-            &image->exception);
+          status=InjectImageBlob(image_info,image,image,"jpeg",exception);
         else
           if ((compression == FaxCompression) ||
               (compression == Group4Compression))
             {
               if (LocaleCompare(CCITTParam,"0") == 0)
-                status=HuffmanEncodeImage(image_info,image,image);
+                status=HuffmanEncodeImage(image_info,image,image,exception);
               else
-                status=Huffman2DEncodeImage(image_info,image,image);
+                status=Huffman2DEncodeImage(image_info,image,image,exception);
             }
           else
             {
-              status=SerializeImageChannel(image_info,image,&pixels,&length);
+              status=SerializeImageChannel(image_info,image,&pixels,&length,
+                exception);
               if (status == MagickFalse)
                 {
                   (void) CloseBlob(image);
@@ -1331,17 +1330,17 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
                 }
                 case LZWCompression:
                 {
-                  status=LZWEncodeImage(image,length,pixels);
+                  status=LZWEncodeImage(image,length,pixels,exception);
                   break;
                 }
                 case RLECompression:
                 {
-                  status=PackbitsEncodeImage(image,length,pixels);
+                  status=PackbitsEncodeImage(image,length,pixels,exception);
                   break;
                 }
                 case ZipCompression:
                 {
-                  status=ZLIBEncodeImage(image,length,pixels);
+                  status=ZLIBEncodeImage(image,length,pixels,exception);
                   break;
                 }
               }
@@ -1389,14 +1388,13 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
             Image data.
           */
           if (compression == JPEGCompression)
-            status=InjectImageBlob(image_info,image,image,"jpeg",
-              &image->exception);
+            status=InjectImageBlob(image_info,image,image,"jpeg",exception);
           else
             {
               /*
                 Stream based compressions.
               */
-              status=SerializeImage(image_info,image,&pixels,&length);
+              status=SerializeImage(image_info,image,&pixels,&length,exception);
               if (status == MagickFalse)
                 {
                   (void) CloseBlob(image);
@@ -1416,17 +1414,17 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
                 }
                 case RLECompression:
                 {
-                  status=PackbitsEncodeImage(image,length,pixels);
+                  status=PackbitsEncodeImage(image,length,pixels,exception);
                   break;
                 }
                 case LZWCompression:
                 {
-                  status=LZWEncodeImage(image,length,pixels);
+                  status=LZWEncodeImage(image,length,pixels,exception);
                   break;
                 }
                 case ZipCompression:
                 {
-                  status=ZLIBEncodeImage(image,length,pixels);
+                  status=ZLIBEncodeImage(image,length,pixels,exception);
                   break;
                 }
               }
@@ -1471,8 +1469,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
             /*
               Number of colors in color map.
             */
-            (void) FormatMagickString(buffer,MaxTextExtent,"%lu\n",
-              (unsigned long) image->colors);
+            (void) FormatLocaleString(buffer,MaxTextExtent,"%.20g\n",
+              (double) image->colors);
             (void) WriteBlobString(image,buffer);
             /*
               Color map - uncompressed.
@@ -1504,7 +1502,8 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
                 }
                 Ascii85Flush(image);
               }
-            status=SerializeImageIndexes(image_info,image,&pixels,&length);
+            status=SerializeImageIndexes(image_info,image,&pixels,&length,
+              exception);
             if (status == MagickFalse)
               {
                 (void) CloseBlob(image);
@@ -1524,23 +1523,22 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
               }
               case JPEGCompression:
               {
-                status=InjectImageBlob(image_info,image,image,"jpeg",
-                  &image->exception);
+                status=InjectImageBlob(image_info,image,image,"jpeg",exception);
                 break;
               }
               case RLECompression:
               {
-                status=PackbitsEncodeImage(image,length,pixels);
+                status=PackbitsEncodeImage(image,length,pixels,exception);
                 break;
               }
               case LZWCompression:
               {
-                status=LZWEncodeImage(image,length,pixels);
+                status=LZWEncodeImage(image,length,pixels,exception);
                 break;
               }
               case ZipCompression:
               {
-                status=ZLIBEncodeImage(image,length,pixels);
+                status=ZLIBEncodeImage(image,length,pixels,exception);
                 break;
               }
             }
@@ -1560,7 +1558,7 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
     offset=SeekBlob(image,start,SEEK_SET);
     if (offset < 0)
       ThrowWriterException(CorruptImageError,"ImproperImageHeader");
-    (void) FormatMagickString(buffer,MaxTextExtent,
+    (void) FormatLocaleString(buffer,MaxTextExtent,
       "%%%%BeginData:%13ld %s Bytes\n",(long) length,
       compression == NoCompression ? "ASCII" : "BINARY");
     (void) WriteBlobString(image,buffer);
@@ -1583,11 +1581,11 @@ static MagickBooleanType WritePS3Image(const ImageInfo *image_info,Image *image)
   (void) WriteBlobString(image,"%%Trailer\n");
   if (page > 1)
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,
+      (void) FormatLocaleString(buffer,MaxTextExtent,
         "%%%%BoundingBox: %g %g %g %g\n",floor(bounds.x1+0.5),
         floor(bounds.y1+0.5),ceil(bounds.x2-0.5),ceil(bounds.y2-0.5));
       (void) WriteBlobString(image,buffer);
-      (void) FormatMagickString(buffer,MaxTextExtent,
+      (void) FormatLocaleString(buffer,MaxTextExtent,
         "%%%%HiResBoundingBox: %g %g %g %g\n",bounds.x1,bounds.y1,
         bounds.x2,bounds.y2);
       (void) WriteBlobString(image,buffer);