]> granicus.if.org Git - imagemagick/blobdiff - MagickCore/animate.c
(no commit message)
[imagemagick] / MagickCore / animate.c
index 7d42366898d851ab085cc2b31a7707d500ce1100..03ce235ad1557654fa97eba185ddfade31c14e90 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 "MagickCore/studio.h"
 #include "MagickCore/animate.h"
 #include "MagickCore/animate-private.h"
+#include "MagickCore/attribute.h"
 #include "MagickCore/client.h"
 #include "MagickCore/color.h"
 #include "MagickCore/color-private.h"
 #include "MagickCore/colorspace.h"
+#include "MagickCore/colorspace-private.h"
 #include "MagickCore/constitute.h"
 #include "MagickCore/delegate.h"
 #include "MagickCore/exception.h"
 #include "MagickCore/string-private.h"
 #include "MagickCore/transform.h"
 #include "MagickCore/utility.h"
+#include "MagickCore/utility-private.h"
 #include "MagickCore/version.h"
 #include "MagickCore/widget.h"
+#include "MagickCore/widget-private.h"
+#include "MagickCore/xwindow.h"
 #include "MagickCore/xwindow-private.h"
 \f
 #if defined(MAGICKCORE_X11_DELEGATE)
@@ -238,10 +243,10 @@ typedef enum
 */
 static Image
   *XMagickCommand(Display *,XResourceInfo *,XWindows *,const CommandType,
-    Image **,MagickStatusType *);
+    Image **,MagickStatusType *,ExceptionInfo *);
 
 static MagickBooleanType
-  XSaveImage(Display *,XResourceInfo *,XWindows *,Image *);
+  XSaveImage(Display *,XResourceInfo *,XWindows *,Image *,ExceptionInfo *);
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -261,7 +266,7 @@ static MagickBooleanType
 %  The format of the AnimateImages method is:
 %
 %      MagickBooleanType AnimateImages(const ImageInfo *image_info,
-%        Image *images)
+%        Image *images,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -269,9 +274,11 @@ static MagickBooleanType
 %
 %    o image: the image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
-  Image *images)
+  Image *images,ExceptionInfo *exception)
 {
   char
     *argv[1];
@@ -297,13 +304,12 @@ MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
   display=XOpenDisplay(image_info->server_name);
   if (display == (Display *) NULL)
     {
-      (void) ThrowMagickException(&images->exception,GetMagickModule(),
-        XServerError,"UnableToOpenXServer","`%s'",XDisplayName(
-        image_info->server_name));
+      (void) ThrowMagickException(exception,GetMagickModule(),XServerError,
+        "UnableToOpenXServer","'%s'",XDisplayName(image_info->server_name));
       return(MagickFalse);
     }
-  if (images->exception.severity != UndefinedException)
-    CatchException(&images->exception);
+  if (exception->severity != UndefinedException)
+    CatchException(exception);
   (void) XSetErrorHandler(XError);
   resource_database=XGetResourceDatabase(display,GetClientName());
   (void) ResetMagickMemory(&resource_info,0,sizeof(XResourceInfo));
@@ -312,12 +318,13 @@ MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
     resource_info.image_geometry=AcquireString(image_info->page);
   resource_info.immutable=MagickTrue;
   argv[0]=AcquireString(GetClientName());
-  (void) XAnimateImages(display,&resource_info,argv,1,images);
+  (void) XAnimateImages(display,&resource_info,argv,1,images,exception);
+  (void) SetErrorHandler((ErrorHandler) NULL);
+  (void) SetWarningHandler((WarningHandler) NULL);
   argv[0]=DestroyString(argv[0]);
   (void) XCloseDisplay(display);
   XDestroyResourceInfo(&resource_info);
-  status=images->exception.severity == UndefinedException ?
-    MagickTrue : MagickFalse;
+  status=exception->severity == UndefinedException ? MagickTrue : MagickFalse;
   return(status != 0 ? MagickTrue : MagickFalse);
 }
 \f
@@ -339,7 +346,7 @@ MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
 %
 %      Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
 %        XWindows *windows,const CommandType command_type,Image **image,
-%        MagickStatusType *state)
+%        MagickStatusType *state,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -356,11 +363,13 @@ MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
 %    o state: Specifies a MagickStatusType;  XMagickCommand may return a
 %      modified state.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 %
 */
 static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
   XWindows *windows,const CommandType command_type,Image **image,
-  MagickStatusType *state)
+  MagickStatusType *state,ExceptionInfo *exception)
 {
   Image
     *nexus;
@@ -385,9 +394,6 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
       char
         **filelist;
 
-      ExceptionInfo
-        *exception;
-
       Image
         *images,
         *next;
@@ -437,7 +443,6 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
           return((Image *) NULL);
         }
       read_info=CloneImageInfo(resource_info->image_info);
-      exception=AcquireExceptionInfo();
       images=NewImageList();
       XSetCursorState(display,windows,MagickTrue);
       XCheckRefreshWindows(display,windows);
@@ -458,7 +463,6 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
           break;
       }
       filelist=(char **) RelinquishMagickMemory(filelist);
-      exception=DestroyExceptionInfo(exception);
       read_info=DestroyImageInfo(read_info);
       if (images == (Image *) NULL)
         {
@@ -492,7 +496,7 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
             *title;
 
           title=InterpretImageProperties(resource_info->image_info,*image,
-            resource_info->title);
+            resource_info->title,exception);
           (void) CopyMagickString(windows->image.name,title,MaxTextExtent);
           title=DestroyString(title);
         }
@@ -536,11 +540,17 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
       /*
         Save image.
       */
-      status=XSaveImage(display,resource_info,windows,*image);
+      status=XSaveImage(display,resource_info,windows,*image,exception);
       if (status == MagickFalse)
         {
-          XNoticeWidget(display,windows,"Unable to write X image:",
-            (*image)->filename);
+          char
+            message[MaxTextExtent];
+
+          (void) FormatLocaleString(message,MaxTextExtent,"%s:%s",
+            exception->reason != (char *) NULL ? exception->reason : "",
+            exception->description != (char *) NULL ? exception->description :
+            "");
+          XNoticeWidget(display,windows,"Unable to save file:",message);
           break;
         }
       break;
@@ -571,7 +581,8 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
     }
     case InfoCommand:
     {
-      XDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image);
+      XDisplayImageInfo(display,resource_info,windows,(Image *) NULL,*image,
+        exception);
       break;
     }
     case HelpCommand:
@@ -621,7 +632,7 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
       XSetCursorState(display,windows,MagickTrue);
       XCheckRefreshWindows(display,windows);
       status=InvokeDelegate(resource_info->image_info,*image,"browse",
-        (char *) NULL,&(*image)->exception);
+        (char *) NULL,exception);
       if (status == MagickFalse)
         XNoticeWidget(display,windows,"Unable to browse documentation",
           (char *) NULL);
@@ -682,7 +693,7 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
 %  The format of the XAnimateBackgroundImage method is:
 %
 %      void XAnimateBackgroundImage(Display *display,
-%        XResourceInfo *resource_info,Image *images)
+%        XResourceInfo *resource_info,Image *images,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -693,6 +704,8 @@ static Image *XMagickCommand(Display *display,XResourceInfo *resource_info,
 %
 %    o images: the image list.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 
 static inline ssize_t MagickMax(const ssize_t x,const ssize_t y)
@@ -722,7 +735,7 @@ static int SceneCompare(const void *x,const void *y)
 #endif
 
 MagickExport void XAnimateBackgroundImage(Display *display,
-  XResourceInfo *resource_info,Image *images)
+  XResourceInfo *resource_info,Image *images,ExceptionInfo *exception)
 {
   char
     geometry[MaxTextExtent],
@@ -853,7 +866,7 @@ MagickExport void XAnimateBackgroundImage(Display *display,
   */
   if (window_info.id == root_window)
     XDestroyWindowColors(display,root_window);
-  coalesce_image=CoalesceImages(images,&images->exception);
+  coalesce_image=CoalesceImages(images,exception);
   if (coalesce_image == (Image *) NULL)
     ThrowXWindowFatalException(ResourceLimitError,"MemoryAllocationFailed",
       images->filename);
@@ -870,26 +883,27 @@ MagickExport void XAnimateBackgroundImage(Display *display,
         */
         for (next=images; next != (Image *) NULL; )
         {
-          next->matte=MagickFalse;
+          next->alpha_trait=UndefinedPixelTrait;
           if ((next->storage_class == DirectClass) ||
               (next->colors != images->colors) ||
               (next->colors > (size_t) visual_info->colormap_size))
             break;
           for (i=0; i < (ssize_t) images->colors; i++)
-            if (IsPixelPacketEquivalent(next->colormap+i,images->colormap+i) == MagickFalse)
+            if (IsPixelInfoEquivalent(next->colormap+i,images->colormap+i) == MagickFalse)
               break;
           if (i < (ssize_t) images->colors)
             break;
           next=GetNextImageInList(next);
         }
         if (next != (Image *) NULL)
-          (void) RemapImages(resources.quantize_info,images,(Image *) NULL);
+          (void) RemapImages(resources.quantize_info,images,(Image *) NULL,
+            exception);
       }
   /*
     Sort images by increasing scene number.
   */
   number_scenes=GetImageListLength(images);
-  image_list=ImageListToArray(images,&images->exception);
+  image_list=ImageListToArray(images,exception);
   if (image_list == (Image **) NULL)
     ThrowXWindowFatalException(ResourceLimitFatalError,
       "MemoryAllocationFailed",images->filename);
@@ -908,18 +922,18 @@ MagickExport void XAnimateBackgroundImage(Display *display,
     if ((resource_info->map_type != (char *) NULL) ||
         (visual_info->klass == TrueColor) ||
         (visual_info->klass == DirectColor))
-      (void) SetImageType(image_list[scene],image_list[scene]->matte ==
-        MagickFalse ? TrueColorType : TrueColorMatteType);
+      (void) SetImageType(image_list[scene],image_list[scene]->alpha_trait ==
+        BlendPixelTrait ? TrueColorType : TrueColorMatteType,exception);
     if ((display_image->columns < image_list[scene]->columns) &&
         (display_image->rows < image_list[scene]->rows))
       display_image=image_list[scene];
   }
   if ((resource_info->map_type != (char *) NULL) ||
       (visual_info->klass == TrueColor) || (visual_info->klass == DirectColor))
-    (void) SetImageType(display_image,display_image->matte == MagickFalse ?
-      TrueColorType : TrueColorMatteType);
+    (void) SetImageType(display_image,display_image->alpha_trait !=
+      BlendPixelTrait ? TrueColorType : TrueColorMatteType,exception);
   XMakeStandardColormap(display,visual_info,&resources,display_image,map_info,
-    &pixel);
+    &pixel,exception);
   /*
     Graphic context superclass.
   */
@@ -957,7 +971,7 @@ MagickExport void XAnimateBackgroundImage(Display *display,
   window_info.x=(int) geometry_info.x;
   window_info.y=(int) geometry_info.y;
   status=XMakeImage(display,&resources,&window_info,image_list[0],
-    window_info.width,window_info.height);
+    window_info.width,window_info.height,exception);
   if (status == MagickFalse)
     ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
       images->filename);
@@ -1082,7 +1096,7 @@ MagickExport void XAnimateBackgroundImage(Display *display,
       ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
         image_list[scene]->filename);
     status=XMakeImage(display,&resources,&window_info,image_list[scene],
-      columns,rows);
+      columns,rows,exception);
     if (status == MagickFalse)
       ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
         images->filename);
@@ -1119,7 +1133,7 @@ MagickExport void XAnimateBackgroundImage(Display *display,
     (void) XClearWindow(display,window_info.id);
     window_info.pixmaps[scene]=window_info.pixmap;
     window_info.matte_pixmaps[scene]=window_info.matte_pixmap;
-    if (image_list[scene]->matte)
+    if (image_list[scene]->alpha_trait)
       (void) XClearWindow(display,window_info.id);
     delay=1000*image_list[scene]->delay/MagickMax(
       image_list[scene]->ticks_per_second,1L);
@@ -1173,7 +1187,7 @@ MagickExport void XAnimateBackgroundImage(Display *display,
 %  The format of the XAnimateImages method is:
 %
 %      Image *XAnimateImages(Display *display,XResourceInfo *resource_info,
-%        char **argv,const int argc,Image *images)
+%        char **argv,const int argc,Image *images,ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -1188,9 +1202,12 @@ MagickExport void XAnimateBackgroundImage(Display *display,
 %
 %    o images: the image list.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 MagickExport Image *XAnimateImages(Display *display,
-  XResourceInfo *resource_info,char **argv,const int argc,Image *images)
+  XResourceInfo *resource_info,char **argv,const int argc,Image *images,
+  ExceptionInfo *exception)
 {
 #define MagickMenus  4
 #define MaXWindows  8
@@ -1405,8 +1422,8 @@ MagickExport Image *XAnimateImages(Display *display,
 
       status=chdir(working_directory);
       if (status == -1)
-        (void) ThrowMagickException(&images->exception,GetMagickModule(),
-          FileOpenError,"UnableToOpenFile","%s",working_directory);
+        (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
+          "UnableToOpenFile","%s",working_directory);
       warning_handler=resource_info->display_warnings ?
         SetErrorHandler(XWarning) : SetErrorHandler((ErrorHandler) NULL);
       warning_handler=resource_info->display_warnings ?
@@ -1471,7 +1488,7 @@ MagickExport Image *XAnimateImages(Display *display,
   class_hints=windows->class_hints;
   manager_hints=windows->manager_hints;
   root_window=XRootWindow(display,visual_info->screen);
-  coalesce_image=CoalesceImages(images,&images->exception);
+  coalesce_image=CoalesceImages(images,exception);
   if (coalesce_image == (Image *) NULL)
     ThrowXWindowFatalException(XServerFatalError,"MemoryAllocationFailed",
       images->filename);
@@ -1488,13 +1505,13 @@ MagickExport Image *XAnimateImages(Display *display,
         */
         for (next=images; next != (Image *) NULL; )
         {
-          next->matte=MagickFalse;
+          next->alpha_trait=UndefinedPixelTrait;
           if ((next->storage_class == DirectClass) ||
               (next->colors != images->colors) ||
               (next->colors > (size_t) visual_info->colormap_size))
             break;
           for (i=0; i < (ssize_t) images->colors; i++)
-            if (IsPixelPacketEquivalent(next->colormap+i,images->colormap+i) == MagickFalse)
+            if (IsPixelInfoEquivalent(next->colormap+i,images->colormap+i) == MagickFalse)
               break;
           if (i < (ssize_t) images->colors)
             break;
@@ -1502,13 +1519,13 @@ MagickExport Image *XAnimateImages(Display *display,
         }
         if (next != (Image *) NULL)
           (void) RemapImages(resource_info->quantize_info,images,
-            (Image *) NULL);
+            (Image *) NULL,exception);
       }
   /*
     Sort images by increasing scene number.
   */
   number_scenes=GetImageListLength(images);
-  image_list=ImageListToArray(images,&images->exception);
+  image_list=ImageListToArray(images,exception);
   if (image_list == (Image **) NULL)
     ThrowXWindowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
       images->filename);
@@ -1527,8 +1544,8 @@ MagickExport Image *XAnimateImages(Display *display,
     if ((resource_info->map_type != (char *) NULL) ||
         (visual_info->klass == TrueColor) ||
         (visual_info->klass == DirectColor))
-      (void) SetImageType(image_list[scene],image_list[scene]->matte ==
-        MagickFalse ? TrueColorType : TrueColorMatteType);
+      (void) SetImageType(image_list[scene],image_list[scene]->alpha_trait ==
+        BlendPixelTrait ? TrueColorType : TrueColorMatteType,exception);
     if ((display_image->columns < image_list[scene]->columns) &&
         (display_image->rows < image_list[scene]->rows))
       display_image=image_list[scene];
@@ -1546,7 +1563,7 @@ MagickExport Image *XAnimateImages(Display *display,
         display_image->magick);
     }
   XMakeStandardColormap(display,visual_info,resource_info,display_image,
-    map_info,pixel);
+    map_info,pixel,exception);
   /*
     Initialize graphic context.
   */
@@ -1642,7 +1659,7 @@ MagickExport Image *XAnimateImages(Display *display,
         *title;
 
       title=InterpretImageProperties(resource_info->image_info,display_image,
-        resource_info->title);
+        resource_info->title,exception);
       (void) CopyMagickString(windows->image.name,title,MaxTextExtent);
       (void) CopyMagickString(windows->image.icon_name,title,MaxTextExtent);
       title=DestroyString(title);
@@ -1913,7 +1930,6 @@ MagickExport Image *XAnimateImages(Display *display,
     /*
       Create X image.
     */
-    (void) TransformImageColorspace(image_list[scene],RGBColorspace);
     windows->image.pixmap=(Pixmap) NULL;
     windows->image.matte_pixmap=(Pixmap) NULL;
     if ((resource_info->map_type != (char *) NULL) ||
@@ -1929,7 +1945,7 @@ MagickExport Image *XAnimateImages(Display *display,
       ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
         image_list[scene]->filename);
     status=XMakeImage(display,resource_info,&windows->image,image_list[scene],
-      columns,rows);
+      columns,rows,exception);
     if (status == MagickFalse)
       ThrowXWindowFatalException(XServerFatalError,"UnableToCreateXImage",
         images->filename);
@@ -1953,7 +1969,7 @@ MagickExport Image *XAnimateImages(Display *display,
           *title;
 
         title=InterpretImageProperties(resource_info->image_info,
-          image_list[scene],resource_info->title);
+          image_list[scene],resource_info->title,exception);
         (void) CopyMagickString(windows->image.name,title,MaxTextExtent);
         title=DestroyString(title);
       }
@@ -1998,7 +2014,7 @@ MagickExport Image *XAnimateImages(Display *display,
   image=image_list[0];
   state=(MagickStatusType) (ForwardAnimationState | RepeatAnimationState);
   (void) XMagickCommand(display,resource_info,windows,PlayCommand,&images,
-    &state);
+    &state,exception);
   do
   {
     if (XEventsQueued(display,QueuedAfterFlush) == 0)
@@ -2091,7 +2107,7 @@ MagickExport Image *XAnimateImages(Display *display,
                     *title;
 
                   title=InterpretImageProperties(resource_info->image_info,
-                    image,resource_info->title);
+                    image,resource_info->title,exception);
                   (void) CopyMagickString(windows->image.name,title,
                     MaxTextExtent);
                   title=DestroyString(title);
@@ -2188,7 +2204,7 @@ MagickExport Image *XAnimateImages(Display *display,
           }
         if (command_type != NullCommand)
           nexus=XMagickCommand(display,resource_info,windows,
-            command_type,&image,&state);
+            command_type,&image,&state,exception);
         continue;
       }
     switch (event.type)
@@ -2344,8 +2360,8 @@ MagickExport Image *XAnimateImages(Display *display,
                 (void) CopyMagickString(resource_info->image_info->filename,
                   ((char *) data)+5,MaxTextExtent);
               }
-            nexus=ReadImage(resource_info->image_info,&image->exception);
-            CatchException(&image->exception);
+            nexus=ReadImage(resource_info->image_info,exception);
+            CatchException(exception);
             if (nexus != (Image *) NULL)
               state|=ExitState;
             (void) XFree((void *) data);
@@ -2556,7 +2572,7 @@ MagickExport Image *XAnimateImages(Display *display,
         }
         if (command_type != NullCommand)
           nexus=XMagickCommand(display,resource_info,windows,
-            command_type,&image,&state);
+            command_type,&image,&state,exception);
         break;
       }
       case KeyRelease:
@@ -2601,7 +2617,7 @@ MagickExport Image *XAnimateImages(Display *display,
               {
                 if (LocaleCompare(display_image->filename,"LOGO") == 0)
                   nexus=XMagickCommand(display,resource_info,windows,
-                    OpenCommand,&image,&state);
+                    OpenCommand,&image,&state,exception);
                 else
                   state|=ExitState;
               }
@@ -2619,9 +2635,10 @@ MagickExport Image *XAnimateImages(Display *display,
               Create an icon image.
             */
             XMakeStandardColormap(display,icon_visual,icon_resources,
-              display_image,icon_map,icon_pixel);
+              display_image,icon_map,icon_pixel,exception);
             (void) XMakeImage(display,icon_resources,&windows->icon,
-              display_image,windows->icon.width,windows->icon.height);
+              display_image,windows->icon.width,windows->icon.height,
+              exception);
             (void) XSetWindowBackgroundPixmap(display,windows->icon.id,
               windows->icon.pixmap);
             (void) XClearWindow(display,windows->icon.id);
@@ -2687,8 +2704,8 @@ MagickExport Image *XAnimateImages(Display *display,
           break;
         (void) CopyMagickString(resource_info->image_info->filename,
           (char *) data,MaxTextExtent);
-        nexus=ReadImage(resource_info->image_info,&image->exception);
-        CatchException(&image->exception);
+        nexus=ReadImage(resource_info->image_info,exception);
+        CatchException(exception);
         if (nexus != (Image *) NULL)
           state|=ExitState;
         (void) XFree((void *) data);
@@ -2726,7 +2743,7 @@ MagickExport Image *XAnimateImages(Display *display,
           {
             if (map_info->colormap == icon_map->colormap)
               XConfigureImageColormap(display,resource_info,windows,
-                display_image);
+                display_image,exception);
             (void) XFreeStandardColormap(display,icon_visual,icon_map,
               icon_pixel);
             windows->icon.mapped=MagickFalse;
@@ -2832,8 +2849,8 @@ MagickExport Image *XAnimateImages(Display *display,
   (void) directory;
   status=chdir(resource_info->home_directory);
   if (status == -1)
-    (void) ThrowMagickException(&images->exception,GetMagickModule(),
-      FileOpenError,"UnableToOpenFile","%s",resource_info->home_directory);
+    (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
+      "UnableToOpenFile","%s",resource_info->home_directory);
   return(nexus);
 }
 \f
@@ -2853,7 +2870,8 @@ MagickExport Image *XAnimateImages(Display *display,
 %  The format of the XSaveImage method is:
 %
 %      MagickBooleanType XSaveImage(Display *display,
-%        XResourceInfo *resource_info,XWindows *windows,Image *image)
+%        XResourceInfo *resource_info,XWindows *windows,Image *image,
+%        ExceptionInfo *exception)
 %
 %  A description of each parameter follows:
 %
@@ -2872,7 +2890,8 @@ MagickExport Image *XAnimateImages(Display *display,
 %
 */
 static MagickBooleanType XSaveImage(Display *display,
-  XResourceInfo *resource_info,XWindows *windows,Image *image)
+  XResourceInfo *resource_info,XWindows *windows,Image *image,
+  ExceptionInfo *exception)
 {
   char
     filename[MaxTextExtent];
@@ -2901,8 +2920,8 @@ static MagickBooleanType XSaveImage(Display *display,
       GetPathComponent(image->filename,TailPath,filename);
       status=chdir(path);
       if (status == -1)
-        (void) ThrowMagickException(&image->exception,GetMagickModule(),
-          FileOpenError,"UnableToOpenFile","%s",path);
+        (void) ThrowMagickException(exception,GetMagickModule(),FileOpenError,
+          "UnableToOpenFile","%s",path);
     }
   XFileBrowserWidget(display,windows,"Save",filename);
   if (*filename == '\0')
@@ -2921,7 +2940,7 @@ static MagickBooleanType XSaveImage(Display *display,
     }
   image_info=CloneImageInfo(resource_info->image_info);
   (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
-  (void) SetImageInfo(image_info,1,&image->exception);
+  (void) SetImageInfo(image_info,1,exception);
   if ((LocaleCompare(image_info->magick,"JPEG") == 0) ||
       (LocaleCompare(image_info->magick,"JPG") == 0))
     {
@@ -2969,7 +2988,7 @@ static MagickBooleanType XSaveImage(Display *display,
     Write image.
   */
   image=GetFirstImageInList(image);
-  status=WriteImages(image_info,image,filename,&image->exception);
+  status=WriteImages(image_info,image,filename,exception);
   if (status != MagickFalse)
     image->taint=MagickFalse;
   image_info=DestroyImageInfo(image_info);
@@ -3004,9 +3023,11 @@ static MagickBooleanType XSaveImage(Display *display,
 %
 %    o image: the image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
-  Image *image)
+  Image *image,ExceptionInfo *exception)
 {
   assert(image_info != (const ImageInfo *) NULL);
   assert(image_info->signature == MagickSignature);
@@ -3014,9 +3035,8 @@ MagickExport MagickBooleanType AnimateImages(const ImageInfo *image_info,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  (void) ThrowMagickException(&image->exception,GetMagickModule(),
-    MissingDelegateError,"DelegateLibrarySupportNotBuiltIn","`%s' (X11)",
-    image->filename);
+  (void) ThrowMagickException(exception,GetMagickModule(),MissingDelegateError,
+    "DelegateLibrarySupportNotBuiltIn","'%s' (X11)",image->filename);
   return(MagickFalse);
 }
 #endif