2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write HP PCL Printer Format %
20 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/property.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/cache.h"
47 #include "magick/color.h"
48 #include "magick/color-private.h"
49 #include "magick/colorspace.h"
50 #include "magick/constitute.h"
51 #include "magick/delegate.h"
52 #include "magick/draw.h"
53 #include "magick/exception.h"
54 #include "magick/exception-private.h"
55 #include "magick/geometry.h"
56 #include "magick/image.h"
57 #include "magick/image-private.h"
58 #include "magick/list.h"
59 #include "magick/magick.h"
60 #include "magick/memory_.h"
61 #include "magick/monitor.h"
62 #include "magick/monitor-private.h"
63 #include "magick/profile.h"
64 #include "magick/resource_.h"
65 #include "magick/quantum-private.h"
66 #include "magick/static.h"
67 #include "magick/string_.h"
68 #include "magick/module.h"
69 #include "magick/token.h"
70 #include "magick/transform.h"
71 #include "magick/utility.h"
76 static MagickBooleanType
77 WritePCLImage(const ImageInfo *,Image *);
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90 % IsPCL() returns MagickTrue if the image format type, identified by the
91 % magick string, is PCL.
93 % The format of the IsPCL method is:
95 % MagickBooleanType IsPCL(const unsigned char *magick,const size_t length)
97 % A description of each parameter follows:
99 % o magick: compare image format pattern against these bytes.
101 % o length: Specifies the length of the magick string.
104 static MagickBooleanType IsPCL(const unsigned char *magick,const size_t length)
108 if (memcmp(magick,"\033E\033",3) == 0)
110 if (memcmp(magick,"\033E\033&",4) == 0)
116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
120 % R e a d P C L I m a g e %
124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 % ReadPCLImage() reads a Printer Control Language image file and returns it.
127 % It allocates the memory necessary for the new Image structure and returns a
128 % pointer to the new image.
130 % The format of the ReadPCLImage method is:
132 % Image *ReadPCLImage(const ImageInfo *image_info,ExceptionInfo *exception)
134 % A description of each parameter follows:
136 % o image_info: the image info.
138 % o exception: return any errors or warnings in this structure.
141 static Image *ReadPCLImage(const ImageInfo *image_info,ExceptionInfo *exception)
143 #define CropBox "CropBox"
144 #define DeviceCMYK "DeviceCMYK"
145 #define MediaBox "MediaBox"
146 #define RenderPCLText " Rendering PCL... "
149 command[MaxTextExtent],
150 density[MaxTextExtent],
151 filename[MaxTextExtent],
152 geometry[MaxTextExtent],
153 options[MaxTextExtent],
154 input_filename[MaxTextExtent];
193 assert(image_info != (const ImageInfo *) NULL);
194 assert(image_info->signature == MagickSignature);
195 if (image_info->debug != MagickFalse)
196 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
197 image_info->filename);
198 assert(exception != (ExceptionInfo *) NULL);
199 assert(exception->signature == MagickSignature);
203 image=AcquireImage(image_info);
204 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
205 if (status == MagickFalse)
207 image=DestroyImageList(image);
208 return((Image *) NULL);
210 status=AcquireUniqueSymbolicLink(image_info->filename,input_filename);
211 if (status == MagickFalse)
213 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
214 image_info->filename);
215 image=DestroyImageList(image);
216 return((Image *) NULL);
219 Set the page density.
221 delta.x=DefaultResolution;
222 delta.y=DefaultResolution;
223 if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0))
231 flags=ParseGeometry(PSDensityGeometry,&geometry_info);
232 image->x_resolution=geometry_info.rho;
233 image->y_resolution=geometry_info.sigma;
234 if ((flags & SigmaValue) == 0)
235 image->y_resolution=image->x_resolution;
238 Determine page geometry from the PCL media box.
240 cmyk=image->colorspace == CMYKColorspace ? MagickTrue : MagickFalse;
242 (void) ResetMagickMemory(&bounding_box,0,sizeof(bounding_box));
243 (void) ResetMagickMemory(&bounds,0,sizeof(bounds));
244 (void) ResetMagickMemory(&page,0,sizeof(page));
245 (void) ResetMagickMemory(command,0,sizeof(command));
247 for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
249 if (image_info->page != (char *) NULL)
255 if ((c != (int) '/') && (c != '\n') &&
256 ((size_t) (p-command) < (MaxTextExtent-1)))
261 Is this a CMYK document?
263 if (LocaleNCompare(DeviceCMYK,command,strlen(DeviceCMYK)) == 0)
265 if (LocaleNCompare(CropBox,command,strlen(CropBox)) == 0)
268 Note region defined by crop box.
270 count=(ssize_t) sscanf(command,"CropBox [%lf %lf %lf %lf",
271 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
273 count=(ssize_t) sscanf(command,"CropBox[%lf %lf %lf %lf",
274 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
276 if (LocaleNCompare(MediaBox,command,strlen(MediaBox)) == 0)
279 Note region defined by media box.
281 count=(ssize_t) sscanf(command,"MediaBox [%lf %lf %lf %lf",
282 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
284 count=(ssize_t) sscanf(command,"MediaBox[%lf %lf %lf %lf",
285 &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2);
290 Set PCL render geometry.
292 width=(unsigned long) (bounds.x2-bounds.x1+0.5);
293 height=(unsigned long) (bounds.y2-bounds.y1+0.5);
294 if (width > page.width)
296 if (height > page.height)
299 (void) CloseBlob(image);
301 Render PCL with the GhostPCL delegate.
303 if ((page.width == 0) || (page.height == 0))
304 (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
305 if (image_info->page != (char *) NULL)
306 (void) ParseAbsoluteGeometry(image_info->page,&page);
307 (void) FormatMagickString(geometry,MaxTextExtent,"%lux%lu",
308 page.width,page.height);
309 if (image_info->monochrome != MagickFalse)
310 delegate_info=GetDelegateInfo("pcl:mono",(char *) NULL,exception);
312 if (cmyk != MagickFalse)
313 delegate_info=GetDelegateInfo("pcl:cmyk",(char *) NULL,exception);
315 delegate_info=GetDelegateInfo("pcl:color",(char *) NULL,exception);
316 if (delegate_info == (const DelegateInfo *) NULL)
317 return((Image *) NULL);
319 if ((page.width == 0) || (page.height == 0))
320 (void) ParseAbsoluteGeometry(PSPageGeometry,&page);
321 if (image_info->page != (char *) NULL)
322 (void) ParseAbsoluteGeometry(image_info->page,&page);
323 (void) FormatMagickString(density,MaxTextExtent,"%gx%g",
324 image->x_resolution,image->y_resolution);
325 page.width=(unsigned long) (page.width*image->x_resolution/delta.x+0.5);
326 page.height=(unsigned long) (page.height*image->y_resolution/delta.y+0.5);
327 (void) FormatMagickString(options,MaxTextExtent,"-g%lux%lu ",
328 page.width,page.height);
329 image=DestroyImage(image);
330 read_info=CloneImageInfo(image_info);
331 *read_info->magick='\0';
332 if (read_info->number_scenes != 0)
334 if (read_info->number_scenes != 1)
335 (void) FormatMagickString(options,MaxTextExtent,"-dLastPage=%lu",
336 read_info->scene+read_info->number_scenes);
338 (void) FormatMagickString(options,MaxTextExtent,
339 "-dFirstPage=%lu -dLastPage=%lu",read_info->scene+1,read_info->scene+
340 read_info->number_scenes);
341 read_info->number_scenes=0;
342 if (read_info->scenes != (char *) NULL)
343 *read_info->scenes='\0';
345 if (read_info->authenticate != (char *) NULL)
346 (void) FormatMagickString(options+strlen(options),MaxTextExtent,
347 " -sPCLPassword=%s",read_info->authenticate);
348 (void) CopyMagickString(filename,read_info->filename,MaxTextExtent);
349 (void) AcquireUniqueFilename(read_info->filename);
350 (void) FormatMagickString(command,MaxTextExtent,
351 GetDelegateCommands(delegate_info),
352 read_info->antialias != MagickFalse ? 4 : 1,
353 read_info->antialias != MagickFalse ? 4 : 1,density,options,
354 read_info->filename,input_filename);
355 status=SystemCommand(read_info->verbose,command) != 0 ? MagickTrue :
357 image=ReadImage(read_info,exception);
358 (void) RelinquishUniqueFileResource(read_info->filename);
359 (void) RelinquishUniqueFileResource(input_filename);
360 read_info=DestroyImageInfo(read_info);
361 if (image == (Image *) NULL)
362 ThrowReaderException(DelegateError,"PCLDelegateFailed");
363 if (LocaleCompare(image->magick,"BMP") == 0)
368 cmyk_image=ConsolidateCMYKImages(image,&image->exception);
369 if (cmyk_image != (Image *) NULL)
371 image=DestroyImageList(image);
377 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
379 next_image=SyncNextImageInList(image);
380 if (next_image != (Image *) NULL)
382 } while (next_image != (Image *) NULL);
383 return(GetFirstImageInList(image));
387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391 % R e g i s t e r P C L I m a g e %
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 % RegisterPCLImage() adds attributes for the PCL image format to
398 % the list of supported formats. The attributes include the image format
399 % tag, a method to read and/or write the format, whether the format
400 % supports the saving of more than one frame to the i file or blob,
401 % whether the format supports native in-memory I/O, and a brief
402 % description of the format.
404 % The format of the RegisterPCLImage method is:
406 % unsigned long RegisterPCLImage(void)
409 ModuleExport unsigned long RegisterPCLImage(void)
414 entry=SetMagickInfo("PCL");
415 entry->decoder=(DecodeImageHandler *) ReadPCLImage;
416 entry->encoder=(EncodeImageHandler *) WritePCLImage;
417 entry->magick=(IsImageFormatHandler *) IsPCL;
418 entry->blob_support=MagickFalse;
419 entry->seekable_stream=MagickTrue;
420 entry->thread_support=EncoderThreadSupport;
421 entry->description=ConstantString("Printer Control Language");
422 entry->module=ConstantString("PCL");
423 (void) RegisterMagickInfo(entry);
424 return(MagickImageCoderSignature);
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % U n r e g i s t e r P C L I m a g e %
436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438 % UnregisterPCLImage() removes format registrations made by the PCL module
439 % from the list of supported formats.
441 % The format of the UnregisterPCLImage method is:
443 % UnregisterPCLImage(void)
446 ModuleExport void UnregisterPCLImage(void)
448 (void) UnregisterMagickInfo("PCL");
452 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 % W r i t e P C L I m a g e %
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462 % WritePCLImage() writes an image in the Page Control Language encoded
465 % The format of the WritePCLImage method is:
467 % MagickBooleanType WritePCLImage(const ImageInfo *image_info,Image *image)
469 % A description of each parameter follows.
471 % o image_info: the image info.
473 % o image: The image.
477 static size_t PCLDeltaCompressImage(const size_t length,
478 const unsigned char *previous_pixels,const unsigned char *pixels,
479 unsigned char *compress_pixels)
490 register unsigned char
494 for (x=0; x < (long) length; )
497 for (i=0; x < (long) length; x++)
499 if (*pixels++ != *previous_pixels++)
506 for ( ; x < (long) length; x++)
508 if (*pixels == *previous_pixels)
516 replacement=j >= 31 ? 31 : j;
518 delta=i >= 8 ? 8 : i;
519 *q++=(unsigned char) (((delta-1) << 5) | replacement);
520 if (replacement == 31)
522 for (replacement=255; j != 0; )
526 *q++=(unsigned char) replacement;
529 if (replacement == 255)
532 for (pixels-=i; i != 0; )
534 for (i-=delta; delta != 0; delta--)
541 *q++=(unsigned char) ((delta-1) << 5);
544 return((size_t) (q-compress_pixels));
547 static size_t PCLPackbitsCompressImage(const size_t length,
548 const unsigned char *pixels,unsigned char *compress_pixels)
559 register unsigned char
566 Compress pixels with Packbits encoding.
569 for (x=(long) length; x != 0; )
591 if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
593 *q++=(unsigned char) ((256-3)+1);
605 if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
611 while (((long) count < x) && (*pixels == *(pixels+count)))
618 *q++=(unsigned char) ((256-count)+1);
627 while ((*(pixels+count) != *(pixels+count+1)) ||
628 (*(pixels+count+1) != *(pixels+count+2)))
630 packbits[count+1]=pixels[count];
632 if (((long) count >= (x-3)) || (count >= 127))
636 *packbits=(unsigned char) (count-1);
637 for (j=0; j <= (long) count; j++)
644 *q++=128; /* EOD marker */
645 return((size_t) (q-compress_pixels));
648 static MagickBooleanType WritePCLImage(const ImageInfo *image_info,Image *image)
651 buffer[MaxTextExtent];
662 register const IndexPacket
665 register const PixelPacket
672 register unsigned char
689 Open output image file.
691 assert(image_info != (const ImageInfo *) NULL);
692 assert(image_info->signature == MagickSignature);
693 assert(image != (Image *) NULL);
694 assert(image->signature == MagickSignature);
695 if (image->debug != MagickFalse)
696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
697 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
698 if (status == MagickFalse)
701 if (image_info->density != (char *) NULL)
706 (void) ParseGeometry(image_info->density,&geometry);
707 density=(unsigned long) geometry.rho;
712 if (image->colorspace != RGBColorspace)
713 (void) TransformImageColorspace(image,RGBColorspace);
715 Initialize the printer.
717 (void) WriteBlobString(image,"\033E"); /* printer reset */
718 (void) WriteBlobString(image,"\033*r3F"); /* set presentation mode */
719 (void) FormatMagickString(buffer,MaxTextExtent,"\033*r%lus%luT",
720 image->columns,image->rows);
721 (void) WriteBlobString(image,buffer);
722 (void) FormatMagickString(buffer,MaxTextExtent,"\033*t%ldR",density);
723 (void) WriteBlobString(image,buffer);
724 (void) WriteBlobString(image,"\033&l0E"); /* top margin 0 */
725 if (IsMonochromeImage(image,&image->exception) != MagickFalse)
731 (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */
732 (void) WriteBlobByte(image,0); /* RGB */
733 (void) WriteBlobByte(image,1); /* indexed by pixel */
734 (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */
735 (void) WriteBlobByte(image,8); /* bits per red component */
736 (void) WriteBlobByte(image,8); /* bits per green component */
737 (void) WriteBlobByte(image,8); /* bits per blue component */
738 (void) FormatMagickString(buffer,MaxTextExtent,"\033*v0a0b0c0I");
739 (void) WriteBlobString(image,buffer);
740 (void) FormatMagickString(buffer,MaxTextExtent,"\033*v1a1b1c1I");
741 (void) WriteBlobString(image,buffer);
744 if (image->storage_class == DirectClass)
750 (void) WriteBlobString(image,"\033*v6W"); /* set color mode */
751 (void) WriteBlobByte(image,0); /* RGB */
752 (void) WriteBlobByte(image,3); /* direct by pixel */
753 (void) WriteBlobByte(image,0); /* bits per index (ignored) */
754 (void) WriteBlobByte(image,8); /* bits per red component */
755 (void) WriteBlobByte(image,8); /* bits per green component */
756 (void) WriteBlobByte(image,8); /* bits per blue component */
764 (void) WriteBlobString(image,"\033*v6W"); /* set color mode... */
765 (void) WriteBlobByte(image,0); /* RGB */
766 (void) WriteBlobByte(image,1); /* indexed by pixel */
767 (void) WriteBlobByte(image,bits_per_pixel); /* bits per index */
768 (void) WriteBlobByte(image,8); /* bits per red component */
769 (void) WriteBlobByte(image,8); /* bits per green component */
770 (void) WriteBlobByte(image,8); /* bits per blue component */
771 for (i=0; i < (long) image->colors; i++)
773 (void) FormatMagickString(buffer,MaxTextExtent,
774 "\033*v%da%db%dc%ldI",ScaleQuantumToChar(image->colormap[i].red),
775 ScaleQuantumToChar(image->colormap[i].green),
776 ScaleQuantumToChar(image->colormap[i].blue),i);
777 (void) WriteBlobString(image,buffer);
779 for ( ; i < (1L << bits_per_pixel); i++)
781 (void) FormatMagickString(buffer,MaxTextExtent,"\033*v%luI",i);
782 (void) WriteBlobString(image,buffer);
785 (void) WriteBlobString(image,"\033*r1A"); /* start raster graphics */
786 (void) WriteBlobString(image,"\033*b0Y"); /* set y offset */
787 length=(image->columns*bits_per_pixel+7)/8;
788 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
789 if (pixels == (unsigned char *) NULL)
790 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
791 compress_pixels=(unsigned char *) NULL;
792 previous_pixels=(unsigned char *) NULL;
793 switch (image->compression)
797 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b0M");
798 (void) WriteBlobString(image,buffer);
803 compress_pixels=(unsigned char *) AcquireQuantumMemory(length+256,
804 sizeof(*compress_pixels));
805 if (compress_pixels == (unsigned char *) NULL)
807 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
808 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
810 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b2M");
811 (void) WriteBlobString(image,buffer);
816 compress_pixels=(unsigned char *) AcquireQuantumMemory(length+
817 (length >> 3),sizeof(*compress_pixels));
818 if (compress_pixels == (unsigned char *) NULL)
820 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
821 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
823 previous_pixels=(unsigned char *) AcquireQuantumMemory(length,
824 sizeof(*previous_pixels));
825 if (previous_pixels == (unsigned char *) NULL)
827 compress_pixels=(unsigned char *) RelinquishMagickMemory(
829 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
830 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
832 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b3M");
833 (void) WriteBlobString(image,buffer);
837 for (y=0; y < (long) image->rows; y++)
839 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
840 if (p == (const PixelPacket *) NULL)
842 indexes=GetAuthenticIndexQueue(image);
844 switch (bits_per_pixel)
848 register unsigned char
857 for (x=0; x < (long) image->columns; x++)
860 if (PixelIntensity(p) >= ((MagickRealType) QuantumRange/2.0))
872 *q++=byte << (8-bit);
880 for (x=0; x < (long) image->columns; x++)
881 *q++=(unsigned char) indexes[x];
890 for (x=0; x < (long) image->columns; x++)
892 *q++=ScaleQuantumToChar(p->red);
893 *q++=ScaleQuantumToChar(p->green);
894 *q++=ScaleQuantumToChar(p->blue);
900 switch (image->compression)
904 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW",
905 (unsigned long) length);
906 (void) WriteBlobString(image,buffer);
907 (void) WriteBlob(image,length,pixels);
912 packets=PCLPackbitsCompressImage(length,pixels,
914 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW",
915 (unsigned long) packets);
916 (void) WriteBlobString(image,buffer);
917 (void) WriteBlob(image,packets,compress_pixels);
923 for (i=0; i < (long) length; i++)
924 previous_pixels[i]=(~pixels[i]);
925 packets=PCLDeltaCompressImage(length,previous_pixels,pixels,
927 (void) FormatMagickString(buffer,MaxTextExtent,"\033*b%luW",
928 (unsigned long) packets);
929 (void) WriteBlobString(image,buffer);
930 (void) WriteBlob(image,packets,compress_pixels);
931 (void) CopyMagickMemory(previous_pixels,pixels,length*
937 (void) WriteBlobString(image,"\033*r0B"); /* end graphics */
938 switch (image->compression)
944 compress_pixels=(unsigned char *) RelinquishMagickMemory(
950 previous_pixels=(unsigned char *) RelinquishMagickMemory(
952 compress_pixels=(unsigned char *) RelinquishMagickMemory(
957 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
958 if (GetNextImageInList(image) == (Image *) NULL)
960 image=SyncNextImageInList(image);
961 status=SetImageProgress(image,SaveImagesTag,scene++,
962 GetImageListLength(image));
963 if (status == MagickFalse)
965 } while (image_info->adjoin != MagickFalse);
966 (void) WriteBlobString(image,"\033E");
967 (void) CloseBlob(image);