]> granicus.if.org Git - imagemagick/blobdiff - coders/mpc.c
Accommodate background color index in PLTE chunk
[imagemagick] / coders / mpc.c
index c46d43abd0fe00a80da63c158dc3b32faa0f114a..429ce79b9d4b1efa714b241a823ec1c199bdae87 100644 (file)
@@ -17,7 +17,7 @@
 %                                 March 2000                                  %
 %                                                                             %
 %                                                                             %
-%  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/artifact.h"
-#include "magick/attribute.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/colormap.h"
-#include "magick/constitute.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/geometry.h"
-#include "magick/hashmap.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/module.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/option.h"
-#include "magick/profile.h"
-#include "magick/property.h"
-#include "magick/quantum-private.h"
-#include "magick/static.h"
-#include "magick/statistic.h"
-#include "magick/string_.h"
-#include "magick/string-private.h"
-#include "magick/utility.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/artifact.h"
+#include "MagickCore/attribute.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/color.h"
+#include "MagickCore/color-private.h"
+#include "MagickCore/colormap.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/geometry.h"
+#include "MagickCore/hashmap.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/module.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/option.h"
+#include "MagickCore/profile.h"
+#include "MagickCore/property.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/static.h"
+#include "MagickCore/statistic.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/string-private.h"
+#include "MagickCore/utility.h"
 \f
 /*
   Forward declarations.
 */
 static MagickBooleanType
-  WriteMPCImage(const ImageInfo *,Image *);
+  WriteMPCImage(const ImageInfo *,Image *,ExceptionInfo *);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -176,7 +176,9 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
     i;
 
   size_t
-    length;
+    depth,
+    length,
+    quantum_depth;
 
   ssize_t
     count;
@@ -184,10 +186,6 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
   StringInfo
     *profile;
 
-  size_t
-    depth,
-    quantum_depth;
-
   /*
     Open image file.
   */
@@ -198,7 +196,7 @@ static Image *ReadMPCImage(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)
     {
@@ -245,8 +243,11 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
           for (p=comment; comment != (char *) NULL; p++)
           {
             c=ReadBlobByte(image);
-            if ((c == EOF) || (c == (int) '}'))
-              break;
+            if (c == (int) '\\')
+              c=ReadBlobByte(image);
+            else
+              if ((c == EOF) || (c == (int) '}'))
+                break;
             if ((size_t) (p-comment+1) >= length)
               {
                 *p='\0';
@@ -262,7 +263,7 @@ static Image *ReadMPCImage(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);
         }
@@ -308,6 +309,15 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       "MemoryAllocationFailed");
                   *p++=(char) c;
                   c=ReadBlobByte(image);
+                  if (c == '\\')
+                    {
+                      c=ReadBlobByte(image);
+                      if (c == (int) '}')
+                        {
+                          *p++=(char) c;
+                          c=ReadBlobByte(image);
+                        }
+                    }
                   if (*options != '{')
                     if (isspace((int) ((unsigned char) c)) != 0)
                       break;
@@ -315,7 +325,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
               }
             *p='\0';
             if (*options == '{')
-              (void) CopyMagickString(options,options+1,MaxTextExtent);
+              (void) strcpy(options,options+1);
             /*
               Assign a value to the specified keyword.
             */
@@ -326,8 +336,8 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
               {
                 if (LocaleCompare(keyword,"background-color") == 0)
                   {
-                    (void) QueryColorDatabase(options,&image->background_color,
-                      exception);
+                    (void) QueryColorCompliance(options,AllCompliance,
+                      &image->background_color,exception);
                     break;
                   }
                 if (LocaleCompare(keyword,"blue-primary") == 0)
@@ -342,11 +352,11 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   }
                 if (LocaleCompare(keyword,"border-color") == 0)
                   {
-                    (void) QueryColorDatabase(options,&image->border_color,
-                      exception);
+                    (void) QueryColorCompliance(options,AllCompliance,
+                      &image->border_color,exception);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'c':
@@ -357,7 +367,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       storage_class;
 
-                    storage_class=ParseMagickOption(MagickClassOptions,
+                    storage_class=ParseCommandOption(MagickClassOptions,
                       MagickFalse,options);
                     if (storage_class < 0)
                       break;
@@ -374,11 +384,11 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       colorspace;
 
-                    colorspace=ParseMagickOption(MagickColorspaceOptions,
+                    colorspace=ParseCommandOption(MagickColorspaceOptions,
                       MagickFalse,options);
                     if (colorspace < 0)
                       break;
-                    image->colorspace=(ColorspaceType) colorspace;
+                    (void) SetImageColorspace(image,(ColorspaceType) colorspace,                      exception);
                     break;
                   }
                 if (LocaleCompare(keyword,"compression") == 0)
@@ -386,7 +396,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       compression;
 
-                    compression=ParseMagickOption(MagickCompressOptions,
+                    compression=ParseCommandOption(MagickCompressOptions,
                       MagickFalse,options);
                     if (compression < 0)
                       break;
@@ -398,7 +408,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     image->columns=StringToUnsignedLong(options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'd':
@@ -419,14 +429,14 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       dispose;
 
-                    dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse,
+                    dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,
                       options);
                     if (dispose < 0)
                       break;
                     image->dispose=(DisposeType) dispose;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'e':
@@ -437,7 +447,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       endian;
 
-                    endian=ParseMagickOption(MagickEndianOptions,MagickFalse,
+                    endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
                       options);
                     if (endian < 0)
                       break;
@@ -446,10 +456,11 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   }
                 if (LocaleCompare(keyword,"error") == 0)
                   {
-                    image->error.mean_error_per_pixel=StringToDouble(options);
+                    image->error.mean_error_per_pixel=StringToDouble(options,
+                      (char **) NULL);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'g':
@@ -457,7 +468,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
               {
                 if (LocaleCompare(keyword,"gamma") == 0)
                   {
-                    image->gamma=StringToDouble(options);
+                    image->gamma=StringToDouble(options,(char **) NULL);
                     break;
                   }
                 if (LocaleCompare(keyword,"green-primary") == 0)
@@ -470,7 +481,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                         image->chromaticity.green_primary.x;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'i':
@@ -486,7 +497,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     image->iterations=StringToUnsignedLong(options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'm':
@@ -497,7 +508,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       matte;
 
-                    matte=ParseMagickOption(MagickBooleanOptions,MagickFalse,
+                    matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
                       options);
                     if (matte < 0)
                       break;
@@ -506,18 +517,20 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                   }
                 if (LocaleCompare(keyword,"matte-color") == 0)
                   {
-                    (void) QueryColorDatabase(options,&image->matte_color,
-                      exception);
+                    (void) QueryColorCompliance(options,AllCompliance,
+                      &image->matte_color,exception);
                     break;
                   }
                 if (LocaleCompare(keyword,"maximum-error") == 0)
                   {
-                    image->error.normalized_maximum_error=StringToDouble(options);
+                    image->error.normalized_maximum_error=StringToDouble(
+                      options,(char **) NULL);
                     break;
                   }
                 if (LocaleCompare(keyword,"mean-error") == 0)
                   {
-                    image->error.normalized_mean_error=StringToDouble(options);
+                    image->error.normalized_mean_error=StringToDouble(options,
+                      (char **) NULL);
                     break;
                   }
                 if (LocaleCompare(keyword,"montage") == 0)
@@ -525,7 +538,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     (void) CloneString(&image->montage,options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'o':
@@ -536,7 +549,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       matte;
 
-                    matte=ParseMagickOption(MagickBooleanOptions,MagickFalse,
+                    matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
                       options);
                     if (matte < 0)
                       break;
@@ -548,14 +561,14 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       orientation;
 
-                    orientation=ParseMagickOption(MagickOrientationOptions,
+                    orientation=ParseCommandOption(MagickOrientationOptions,
                       MagickFalse,options);
                     if (orientation < 0)
                       break;
                     image->orientation=(OrientationType) orientation;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'p':
@@ -578,12 +591,16 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                       profiles=NewLinkedList(0);
                     (void) AppendValueToLinkedList(profiles,
                       AcquireString(keyword+8));
-                    profile=AcquireStringInfo((size_t) StringToLong(options));
-                    (void) SetImageProfile(image,keyword+8,profile);
+                    profile=BlobToStringInfo((const void *) NULL,(size_t)
+                      StringToLong(options));
+                    if (profile == (StringInfo *) NULL)
+                      ThrowReaderException(ResourceLimitError,
+                        "MemoryAllocationFailed");
+                    (void) SetImageProfile(image,keyword+8,profile,exception);
                     profile=DestroyStringInfo(profile);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'q':
@@ -599,7 +616,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     quantum_depth=StringToUnsignedLong(options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'r':
@@ -618,7 +635,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       rendering_intent;
 
-                    rendering_intent=ParseMagickOption(MagickIntentOptions,
+                    rendering_intent=ParseCommandOption(MagickIntentOptions,
                       MagickFalse,options);
                     if (rendering_intent < 0)
                       break;
@@ -628,10 +645,10 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                 if (LocaleCompare(keyword,"resolution") == 0)
                   {
                     flags=ParseGeometry(options,&geometry_info);
-                    image->x_resolution=geometry_info.rho;
-                    image->y_resolution=geometry_info.sigma;
+                    image->resolution.x=geometry_info.rho;
+                    image->resolution.y=geometry_info.sigma;
                     if ((flags & SigmaValue) == 0)
-                      image->y_resolution=image->x_resolution;
+                      image->resolution.y=image->resolution.x;
                     break;
                   }
                 if (LocaleCompare(keyword,"rows") == 0)
@@ -639,7 +656,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     image->rows=StringToUnsignedLong(options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 's':
@@ -650,7 +667,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     image->scene=StringToUnsignedLong(options);
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 't':
@@ -675,14 +692,14 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       type;
 
-                    type=ParseMagickOption(MagickTypeOptions,MagickFalse,
+                    type=ParseCommandOption(MagickTypeOptions,MagickFalse,
                       options);
                     if (type < 0)
                       break;
                     image->type=(ImageType) type;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'u':
@@ -693,14 +710,14 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                     ssize_t
                       units;
 
-                    units=ParseMagickOption(MagickResolutionOptions,MagickFalse,
-                      options);
+                    units=ParseCommandOption(MagickResolutionOptions,
+                      MagickFalse,options);
                     if (units < 0)
                       break;
                     image->units=(ResolutionType) units;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               case 'w':
@@ -716,12 +733,12 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
                         image->chromaticity.white_point.x;
                     break;
                   }
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
               default:
               {
-                (void) SetImageProperty(image,keyword,options);
+                (void) SetImageProperty(image,keyword,options,exception);
                 break;
               }
             }
@@ -807,7 +824,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Create image colormap.
         */
-        if (AcquireImageColormap(image,image->colors) == MagickFalse)
+        if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
           ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
         if (image->colors != 0)
           {
@@ -914,7 +931,7 @@ static Image *ReadMPCImage(const ImageInfo *image_info,ExceptionInfo *exception)
         /*
           Allocate next image structure.
         */
-        AcquireNextImage(image_info,image);
+        AcquireNextImage(image_info,image,exception);
         if (GetNextImageInList(image) == (Image *) NULL)
           {
             image=DestroyImageList(image);
@@ -1014,7 +1031,8 @@ ModuleExport void UnregisterMPCImage(void)
 %
 %  The format of the WriteMPCImage method is:
 %
-%      MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
+%      MagickBooleanType WriteMPCImage(const ImageInfo *image_info,
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -1022,8 +1040,11 @@ ModuleExport void UnregisterMPCImage(void)
 %
 %    o image: the image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
-static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
+static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image,
+  ExceptionInfo *exception)
 {
   char
     buffer[MaxTextExtent],
@@ -1056,7 +1077,9 @@ static MagickBooleanType WriteMPCImage(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) CopyMagickString(cache_filename,image->filename,MaxTextExtent);
@@ -1074,58 +1097,58 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
         (image->colors > (one << depth)))
       image->storage_class=DirectClass;
     (void) WriteBlobString(image,"id=MagickCache\n");
-    (void) FormatMagickString(buffer,MaxTextExtent,"quantum-depth=%d\n",
+    (void) FormatLocaleString(buffer,MaxTextExtent,"quantum-depth=%d\n",
       MAGICKCORE_QUANTUM_DEPTH);
     (void) WriteBlobString(image,buffer);
-    (void) FormatMagickString(buffer,MaxTextExtent,
-      "class=%s  colors=%.20g  matte=%s\n",MagickOptionToMnemonic(
+    (void) FormatLocaleString(buffer,MaxTextExtent,
+      "class=%s  colors=%.20g  matte=%s\n",CommandOptionToMnemonic(
       MagickClassOptions,image->storage_class),(double) image->colors,
-      MagickOptionToMnemonic(MagickBooleanOptions,(ssize_t) image->matte));
+      CommandOptionToMnemonic(MagickBooleanOptions,(ssize_t) image->matte));
     (void) WriteBlobString(image,buffer);
-    (void) FormatMagickString(buffer,MaxTextExtent,
+    (void) FormatLocaleString(buffer,MaxTextExtent,
       "columns=%.20g  rows=%.20g depth=%.20g\n",(double) image->columns,
       (double) image->rows,(double) image->depth);
     (void) WriteBlobString(image,buffer);
     if (image->type != UndefinedType)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"type=%s\n",
-          MagickOptionToMnemonic(MagickTypeOptions,image->type));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"type=%s\n",
+          CommandOptionToMnemonic(MagickTypeOptions,image->type));
         (void) WriteBlobString(image,buffer);
       }
     if (image->colorspace != UndefinedColorspace)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"colorspace=%s\n",
-          MagickOptionToMnemonic(MagickColorspaceOptions,image->colorspace));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"colorspace=%s\n",
+          CommandOptionToMnemonic(MagickColorspaceOptions,image->colorspace));
         (void) WriteBlobString(image,buffer);
       }
     if (image->endian != UndefinedEndian)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"endian=%s\n",
-          MagickOptionToMnemonic(MagickEndianOptions,image->endian));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"endian=%s\n",
+          CommandOptionToMnemonic(MagickEndianOptions,image->endian));
         (void) WriteBlobString(image,buffer);
       }
     if (image->compression != UndefinedCompression)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,
-          "compression=%s  quality=%.20g\n",MagickOptionToMnemonic(
+        (void) FormatLocaleString(buffer,MaxTextExtent,
+          "compression=%s  quality=%.20g\n",CommandOptionToMnemonic(
           MagickCompressOptions,image->compression),(double) image->quality);
         (void) WriteBlobString(image,buffer);
       }
     if (image->units != UndefinedResolution)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"units=%s\n",
-          MagickOptionToMnemonic(MagickResolutionOptions,image->units));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"units=%s\n",
+          CommandOptionToMnemonic(MagickResolutionOptions,image->units));
         (void) WriteBlobString(image,buffer);
       }
-    if ((image->x_resolution != 0) || (image->y_resolution != 0))
+    if ((image->resolution.x != 0) || (image->resolution.y != 0))
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,
-          "resolution=%gx%g\n",image->x_resolution,image->y_resolution);
+        (void) FormatLocaleString(buffer,MaxTextExtent,
+          "resolution=%gx%g\n",image->resolution.x,image->resolution.y);
         (void) WriteBlobString(image,buffer);
       }
     if ((image->page.width != 0) || (image->page.height != 0))
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,
+        (void) FormatLocaleString(buffer,MaxTextExtent,
           "page=%.20gx%.20g%+.20g%+.20g\n",(double) image->page.width,(double)
           image->page.height,(double) image->page.x,(double) image->page.y);
         (void) WriteBlobString(image,buffer);
@@ -1133,13 +1156,13 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
     else
       if ((image->page.x != 0) || (image->page.y != 0))
         {
-          (void) FormatMagickString(buffer,MaxTextExtent,"page=%+ld%+ld\n",
+          (void) FormatLocaleString(buffer,MaxTextExtent,"page=%+ld%+ld\n",
             (long) image->page.x,(long) image->page.y);
           (void) WriteBlobString(image,buffer);
         }
     if ((image->page.x != 0) || (image->page.y != 0))
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n",
+        (void) FormatLocaleString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n",
           (long) image->tile_offset.x,(long) image->tile_offset.y);
         (void) WriteBlobString(image,buffer);
       }
@@ -1147,13 +1170,13 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
         (GetPreviousImageInList(image) != (Image *) NULL))
       {
         if (image->scene == 0)
-          (void) FormatMagickString(buffer,MaxTextExtent,
+          (void) FormatLocaleString(buffer,MaxTextExtent,
             "iterations=%.20g  delay=%.20g  ticks-per-second=%.20g\n",(double)
             image->iterations,(double) image->delay,(double)
             image->ticks_per_second);
         else
-          (void) FormatMagickString(buffer,MaxTextExtent,
-            "scene=%.20g  iterations=%.20g  delay=%.20g  ticks-per-second=%.20g\n",
+          (void) FormatLocaleString(buffer,MaxTextExtent,"scene=%.20g  "
+            "iterations=%.20g  delay=%.20g  ticks-per-second=%.20g\n",
             (double) image->scene,(double) image->iterations,(double)
             image->delay,(double) image->ticks_per_second);
         (void) WriteBlobString(image,buffer);
@@ -1162,51 +1185,51 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
       {
         if (image->scene != 0)
           {
-            (void) FormatMagickString(buffer,MaxTextExtent,"scene=%.20g\n",
+            (void) FormatLocaleString(buffer,MaxTextExtent,"scene=%.20g\n",
               (double) image->scene);
             (void) WriteBlobString(image,buffer);
           }
         if (image->iterations != 0)
           {
-            (void) FormatMagickString(buffer,MaxTextExtent,"iterations=%.20g\n",
+            (void) FormatLocaleString(buffer,MaxTextExtent,"iterations=%.20g\n",
               (double) image->iterations);
             (void) WriteBlobString(image,buffer);
           }
         if (image->delay != 0)
           {
-            (void) FormatMagickString(buffer,MaxTextExtent,"delay=%.20g\n",
+            (void) FormatLocaleString(buffer,MaxTextExtent,"delay=%.20g\n",
               (double) image->delay);
             (void) WriteBlobString(image,buffer);
           }
         if (image->ticks_per_second != UndefinedTicksPerSecond)
           {
-            (void) FormatMagickString(buffer,MaxTextExtent,
+            (void) FormatLocaleString(buffer,MaxTextExtent,
               "ticks-per-second=%.20g\n",(double) image->ticks_per_second);
             (void) WriteBlobString(image,buffer);
           }
       }
     if (image->gravity != UndefinedGravity)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"gravity=%s\n",
-          MagickOptionToMnemonic(MagickGravityOptions,image->gravity));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"gravity=%s\n",
+          CommandOptionToMnemonic(MagickGravityOptions,image->gravity));
         (void) WriteBlobString(image,buffer);
       }
     if (image->dispose != UndefinedDispose)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"dispose=%s\n",
-          MagickOptionToMnemonic(MagickDisposeOptions,image->dispose));
+        (void) FormatLocaleString(buffer,MaxTextExtent,"dispose=%s\n",
+          CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
         (void) WriteBlobString(image,buffer);
       }
     if (image->rendering_intent != UndefinedIntent)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,
-          "rendering-intent=%s\n",
-           MagickOptionToMnemonic(MagickIntentOptions,image->rendering_intent));
+        (void) FormatLocaleString(buffer,MaxTextExtent,
+          "rendering-intent=%s\n",CommandOptionToMnemonic(MagickIntentOptions,
+          image->rendering_intent));
         (void) WriteBlobString(image,buffer);
       }
     if (image->gamma != 0.0)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"gamma=%g\n",
+        (void) FormatLocaleString(buffer,MaxTextExtent,"gamma=%g\n",
           image->gamma);
         (void) WriteBlobString(image,buffer);
       }
@@ -1215,7 +1238,7 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
         /*
           Note chomaticity points.
         */
-        (void) FormatMagickString(buffer,MaxTextExtent,"red-primary="
+        (void) FormatLocaleString(buffer,MaxTextExtent,"red-primary="
           "%g,%g  green-primary=%g,%g  blue-primary=%g,%g\n",
           image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
           image->chromaticity.green_primary.x,
@@ -1223,15 +1246,15 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
           image->chromaticity.blue_primary.x,
           image->chromaticity.blue_primary.y);
         (void) WriteBlobString(image,buffer);
-        (void) FormatMagickString(buffer,MaxTextExtent,
+        (void) FormatLocaleString(buffer,MaxTextExtent,
           "white-point=%g,%g\n",image->chromaticity.white_point.x,
           image->chromaticity.white_point.y);
         (void) WriteBlobString(image,buffer);
       }
     if (image->orientation != UndefinedOrientation)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,
-          "orientation=%s\n",MagickOptionToMnemonic(MagickOrientationOptions,
+        (void) FormatLocaleString(buffer,MaxTextExtent,
+          "orientation=%s\n",CommandOptionToMnemonic(MagickOrientationOptions,
           image->orientation));
         (void) WriteBlobString(image,buffer);
       }
@@ -1252,7 +1275,7 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
           profile=GetImageProfile(image,name);
           if (profile != (StringInfo *) NULL)
             {
-              (void) FormatMagickString(buffer,MaxTextExtent,
+              (void) FormatLocaleString(buffer,MaxTextExtent,
                 "profile:%s=%.20g\n",name,(double)
                 GetStringInfoLength(profile));
               (void) WriteBlobString(image,buffer);
@@ -1262,7 +1285,7 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
       }
     if (image->montage != (char *) NULL)
       {
-        (void) FormatMagickString(buffer,MaxTextExtent,"montage=%s\n",
+        (void) FormatLocaleString(buffer,MaxTextExtent,"montage=%s\n",
           image->montage);
         (void) WriteBlobString(image,buffer);
       }
@@ -1270,19 +1293,34 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
     property=GetNextImageProperty(image);
     while (property != (const char *) NULL)
     {
-      (void) FormatMagickString(buffer,MaxTextExtent,"%s=",property);
+      (void) FormatLocaleString(buffer,MaxTextExtent,"%s=",property);
       (void) WriteBlobString(image,buffer);
-      value=GetImageProperty(image,property);
+      value=GetImageProperty(image,property,exception);
       if (value != (const char *) NULL)
         {
-          for (i=0; i < (ssize_t) strlen(value); i++)
+          size_t
+            length;
+
+          length=strlen(value);
+          for (i=0; i < (ssize_t) length; i++)
             if (isspace((int) ((unsigned char) value[i])) != 0)
               break;
-          if (i <= (ssize_t) strlen(value))
-            (void) WriteBlobByte(image,'{');
-          (void) WriteBlob(image,strlen(value),(unsigned char *) value);
-          if (i <= (ssize_t) strlen(value))
-            (void) WriteBlobByte(image,'}');
+          if (i == (ssize_t) length)
+            (void) WriteBlob(image,length,(const unsigned char *) value);
+          else
+            {
+              (void) WriteBlobByte(image,'{');
+              if (strchr(value,'}') == (char *) NULL)
+                (void) WriteBlob(image,length,(const unsigned char *) value);
+              else
+                for (i=0; i < (ssize_t) length; i++)
+                {
+                  if (value[i] == (int) '}')
+                    (void) WriteBlobByte(image,'\\');
+                  (void) WriteBlobByte(image,value[i]);
+                }
+              (void) WriteBlobByte(image,'}');
+            }
         }
       (void) WriteBlobByte(image,'\n');
       property=GetNextImageProperty(image);
@@ -1394,7 +1432,7 @@ static MagickBooleanType WriteMPCImage(const ImageInfo *image_info,Image *image)
       Initialize persistent pixel cache.
     */
     status=PersistPixelCache(image,cache_filename,MagickFalse,&offset,
-      &image->exception);
+      exception);
     if (status == MagickFalse)
       ThrowWriterException(CacheError,"UnableToPersistPixelCache");
     if (GetNextImageInList(image) == (Image *) NULL)