• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                        M   M  IIIII  FFFFF  FFFFF                           %
7 %                        MM MM    I    F      F                               %
8 %                        M M M    I    FFF    FFF                             %
9 %                        M   M    I    F      F                               %
10 %                        M   M  IIIII  F      F                               %
11 %                                                                             %
12 %                                                                             %
13 %                      Read/Write MIFF Image Format                           %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                   Cristy                                    %
17 %                                 July 1992                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    https://imagemagick.org/script/license.php                               %
27 %                                                                             %
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.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/attribute.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/color.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colormap.h"
50 #include "MagickCore/colormap-private.h"
51 #include "MagickCore/colorspace.h"
52 #include "MagickCore/colorspace-private.h"
53 #include "MagickCore/constitute.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/geometry.h"
57 #include "MagickCore/image.h"
58 #include "MagickCore/image-private.h"
59 #include "MagickCore/linked-list.h"
60 #include "MagickCore/list.h"
61 #include "MagickCore/magick.h"
62 #include "MagickCore/memory_.h"
63 #include "MagickCore/memory-private.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/monitor.h"
66 #include "MagickCore/monitor-private.h"
67 #include "MagickCore/option.h"
68 #include "MagickCore/pixel.h"
69 #include "MagickCore/pixel-accessor.h"
70 #include "MagickCore/profile.h"
71 #include "MagickCore/property.h"
72 #include "MagickCore/quantum-private.h"
73 #include "MagickCore/static.h"
74 #include "MagickCore/statistic.h"
75 #include "MagickCore/string_.h"
76 #include "MagickCore/string-private.h"
77 #if defined(MAGICKCORE_BZLIB_DELEGATE)
78 #include "bzlib.h"
79 #endif
80 #if defined(MAGICKCORE_LZMA_DELEGATE)
81 #include "lzma.h"
82 #endif
83 #if defined(MAGICKCORE_ZLIB_DELEGATE)
84 #include "zlib.h"
85 #endif
86 
87 /*
88   Define declarations.
89 */
90 #if !defined(LZMA_OK)
91 #define LZMA_OK  0
92 #endif
93 
94 /*
95   Forward declarations.
96 */
97 static MagickBooleanType
98   WriteMIFFImage(const ImageInfo *,Image *,ExceptionInfo *);
99 
100 /*
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %                                                                             %
103 %                                                                             %
104 %                                                                             %
105 %   I s M I F F                                                               %
106 %                                                                             %
107 %                                                                             %
108 %                                                                             %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 %
111 %  IsMIFF() returns MagickTrue if the image format type, identified by the
112 %  magick string, is MIFF.
113 %
114 %  The format of the IsMIFF method is:
115 %
116 %      MagickBooleanType IsMIFF(const unsigned char *magick,const size_t length)
117 %
118 %  A description of each parameter follows:
119 %
120 %    o magick: compare image format pattern against these bytes.
121 %
122 %    o length: Specifies the length of the magick string.
123 %
124 */
IsMIFF(const unsigned char * magick,const size_t length)125 static MagickBooleanType IsMIFF(const unsigned char *magick,const size_t length)
126 {
127   if (length < 14)
128     return(MagickFalse);
129   if (LocaleNCompare((const char *) magick,"id=ImageMagick",14) == 0)
130     return(MagickTrue);
131   return(MagickFalse);
132 }
133 
134 /*
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 %                                                                             %
137 %                                                                             %
138 %                                                                             %
139 %   R e a d M I F F I m a g e                                                 %
140 %                                                                             %
141 %                                                                             %
142 %                                                                             %
143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144 %
145 %  ReadMIFFImage() reads a MIFF image file and returns it.  It allocates the
146 %  memory necessary for the new Image structure and returns a pointer to the
147 %  new image.
148 %
149 %  The format of the ReadMIFFImage method is:
150 %
151 %      Image *ReadMIFFImage(const ImageInfo *image_info,
152 %        ExceptionInfo *exception)
153 %
154 %  Decompression code contributed by Kyle Shorter.
155 %
156 %  A description of each parameter follows:
157 %
158 %    o image_info: the image info.
159 %
160 %    o exception: return any errors or warnings in this structure.
161 %
162 */
163 
164 #if defined(MAGICKCORE_BZLIB_DELEGATE) || defined(MAGICKCORE_LZMA_DELEGATE) || defined(MAGICKCORE_ZLIB_DELEGATE)
AcquireCompressionMemory(void * context,const size_t items,const size_t size)165 static void *AcquireCompressionMemory(void *context,const size_t items,
166   const size_t size)
167 {
168   size_t
169     extent;
170 
171   (void) context;
172   if (HeapOverflowSanityCheck(items,size) != MagickFalse)
173     return((void *) NULL);
174   extent=items*size;
175   if (extent > GetMaxMemoryRequest())
176     return((void *) NULL);
177   return(AcquireMagickMemory(extent));
178 }
179 #endif
180 
181 #if defined(MAGICKCORE_BZLIB_DELEGATE)
182 static void *AcquireBZIPMemory(void *,int,int) magick_attribute((__malloc__));
183 
AcquireBZIPMemory(void * context,int items,int size)184 static void *AcquireBZIPMemory(void *context,int items,int size)
185 {
186   return(AcquireCompressionMemory(context,(size_t) items,(size_t) size));
187 }
188 #endif
189 
190 #if defined(MAGICKCORE_LZMA_DELEGATE)
191 static void *AcquireLZMAMemory(void *,size_t,size_t)
192   magick_attribute((__malloc__));
193 
AcquireLZMAMemory(void * context,size_t items,size_t size)194 static void *AcquireLZMAMemory(void *context,size_t items,size_t size)
195 {
196   return(AcquireCompressionMemory(context,items,size));
197 }
198 #endif
199 
200 #if defined(MAGICKCORE_ZLIB_DELEGATE)
201 static voidpf AcquireZIPMemory(voidpf,unsigned int,unsigned int)
202    magick_attribute((__malloc__));
203 
AcquireZIPMemory(voidpf context,unsigned int items,unsigned int size)204 static voidpf AcquireZIPMemory(voidpf context,unsigned int items,
205   unsigned int size)
206 {
207   return((voidpf) AcquireCompressionMemory(context,(size_t) items,
208     (size_t) size));
209 }
210 #endif
211 
PushRunlengthPacket(Image * image,const unsigned char * pixels,size_t * length,PixelInfo * pixel,ExceptionInfo * exception)212 static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
213   size_t *length,PixelInfo *pixel,ExceptionInfo *exception)
214 {
215   const unsigned char
216     *p;
217 
218   p=pixels;
219   if (image->storage_class == PseudoClass)
220     {
221       pixel->index=0.0;
222       switch (image->depth)
223       {
224         case 32:
225         {
226           pixel->index=(MagickRealType) ConstrainColormapIndex(image,(ssize_t)
227             (((size_t) *p << 24) | ((size_t) *(p+1) << 16) |
228             ((size_t) *(p+2) << 8) | (size_t) *(p+3)),exception);
229           p+=4;
230           break;
231         }
232         case 16:
233         {
234           pixel->index=(MagickRealType) ConstrainColormapIndex(image,(ssize_t)
235             ((*p << 8) | *(p+1)),exception);
236           p+=2;
237           break;
238         }
239         case 8:
240         {
241           pixel->index=(MagickRealType) ConstrainColormapIndex(image,
242             (ssize_t) *p,exception);
243           p++;
244           break;
245         }
246         default:
247           (void) ThrowMagickException(exception,GetMagickModule(),
248             CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename);
249       }
250       switch (image->depth)
251       {
252         case 8:
253         {
254           unsigned char
255             quantum;
256 
257           if (image->alpha_trait != UndefinedPixelTrait)
258             {
259               p=PushCharPixel(p,&quantum);
260               pixel->alpha=(MagickRealType) ScaleCharToQuantum(quantum);
261             }
262           break;
263         }
264         case 16:
265         {
266           unsigned short
267             quantum;
268 
269           if (image->alpha_trait != UndefinedPixelTrait)
270             {
271               p=PushShortPixel(MSBEndian,p,&quantum);
272               pixel->alpha=(MagickRealType) (quantum >> (image->depth-
273                 MAGICKCORE_QUANTUM_DEPTH));
274             }
275           break;
276         }
277         case 32:
278         {
279           unsigned int
280             quantum;
281 
282           if (image->alpha_trait != UndefinedPixelTrait)
283             {
284               p=PushLongPixel(MSBEndian,p,&quantum);
285               pixel->alpha=(MagickRealType) (quantum >> (image->depth-
286                 MAGICKCORE_QUANTUM_DEPTH));
287             }
288           break;
289         }
290         default:
291           (void) ThrowMagickException(exception,GetMagickModule(),
292             CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename);
293       }
294       *length=(size_t) (*p++)+1;
295       return;
296     }
297   switch (image->depth)
298   {
299     case 8:
300     {
301       unsigned char
302         quantum;
303 
304       p=PushCharPixel(p,&quantum);
305       pixel->red=(MagickRealType) ScaleCharToQuantum(quantum);
306       pixel->green=pixel->red;
307       pixel->blue=pixel->red;
308       if (IsGrayColorspace(image->colorspace) == MagickFalse)
309         {
310           p=PushCharPixel(p,&quantum);
311           pixel->green=(MagickRealType) ScaleCharToQuantum(quantum);
312           p=PushCharPixel(p,&quantum);
313           pixel->blue=(MagickRealType) ScaleCharToQuantum(quantum);
314         }
315       if (image->colorspace == CMYKColorspace)
316         {
317           p=PushCharPixel(p,&quantum);
318           pixel->black=(MagickRealType) ScaleCharToQuantum(quantum);
319         }
320       if (image->alpha_trait != UndefinedPixelTrait)
321         {
322           p=PushCharPixel(p,&quantum);
323           pixel->alpha=(MagickRealType) ScaleCharToQuantum(quantum);
324         }
325       break;
326     }
327     case 16:
328     {
329       unsigned short
330         quantum;
331 
332       p=PushShortPixel(MSBEndian,p,&quantum);
333       pixel->red=(MagickRealType) (quantum >> (image->depth-
334         MAGICKCORE_QUANTUM_DEPTH));
335       pixel->green=pixel->red;
336       pixel->blue=pixel->red;
337       if (IsGrayColorspace(image->colorspace) == MagickFalse)
338         {
339           p=PushShortPixel(MSBEndian,p,&quantum);
340           pixel->green=(MagickRealType) (quantum >> (image->depth-
341             MAGICKCORE_QUANTUM_DEPTH));
342           p=PushShortPixel(MSBEndian,p,&quantum);
343           pixel->blue=(MagickRealType) (quantum >> (image->depth-
344             MAGICKCORE_QUANTUM_DEPTH));
345         }
346       if (image->colorspace == CMYKColorspace)
347         {
348           p=PushShortPixel(MSBEndian,p,&quantum);
349           pixel->black=(MagickRealType) (quantum >> (image->depth-
350             MAGICKCORE_QUANTUM_DEPTH));
351         }
352       if (image->alpha_trait != UndefinedPixelTrait)
353         {
354           p=PushShortPixel(MSBEndian,p,&quantum);
355           pixel->alpha=(MagickRealType) (quantum >> (image->depth-
356             MAGICKCORE_QUANTUM_DEPTH));
357         }
358       break;
359     }
360     case 32:
361     {
362       unsigned int
363         quantum;
364 
365       p=PushLongPixel(MSBEndian,p,&quantum);
366       pixel->red=(MagickRealType) (quantum >> (image->depth-
367         MAGICKCORE_QUANTUM_DEPTH));
368       pixel->green=pixel->red;
369       pixel->blue=pixel->red;
370       if (IsGrayColorspace(image->colorspace) == MagickFalse)
371         {
372           p=PushLongPixel(MSBEndian,p,&quantum);
373           pixel->green=(MagickRealType) (quantum >> (image->depth-
374             MAGICKCORE_QUANTUM_DEPTH));
375           p=PushLongPixel(MSBEndian,p,&quantum);
376           pixel->blue=(MagickRealType) (quantum >> (image->depth-
377             MAGICKCORE_QUANTUM_DEPTH));
378         }
379       if (image->colorspace == CMYKColorspace)
380         {
381           p=PushLongPixel(MSBEndian,p,&quantum);
382           pixel->black=(MagickRealType) (quantum >> (image->depth-
383             MAGICKCORE_QUANTUM_DEPTH));
384         }
385       if (image->alpha_trait != UndefinedPixelTrait)
386         {
387           p=PushLongPixel(MSBEndian,p,&quantum);
388           pixel->alpha=(MagickRealType) (quantum >> (image->depth-
389             MAGICKCORE_QUANTUM_DEPTH));
390         }
391       break;
392     }
393     default:
394       (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
395         "ImageDepthNotSupported","`%s'",image->filename);
396   }
397   *length=(size_t) (*p++)+1;
398 }
399 
400 #if defined(MAGICKCORE_BZLIB_DELEGATE)
RelinquishBZIPMemory(void * context,void * memory)401 static void RelinquishBZIPMemory(void *context,void *memory)
402 {
403   (void) context;
404   memory=RelinquishMagickMemory(memory);
405 }
406 #endif
407 
408 #if defined(MAGICKCORE_LZMA_DELEGATE)
RelinquishLZMAMemory(void * context,void * memory)409 static void RelinquishLZMAMemory(void *context,void *memory)
410 {
411   (void) context;
412   memory=RelinquishMagickMemory(memory);
413 }
414 #endif
415 
416 #if defined(MAGICKCORE_ZLIB_DELEGATE)
RelinquishZIPMemory(voidpf context,voidpf memory)417 static void RelinquishZIPMemory(voidpf context,voidpf memory)
418 {
419   (void) context;
420   memory=RelinquishMagickMemory(memory);
421 }
422 #endif
423 
ReadMIFFImage(const ImageInfo * image_info,ExceptionInfo * exception)424 static Image *ReadMIFFImage(const ImageInfo *image_info,
425   ExceptionInfo *exception)
426 {
427 #define BZipMaxExtent(x)  ((x)+((x)/100)+600)
428 #define LZMAMaxExtent(x)  ((x)+((x)/3)+128)
429 #define ThrowMIFFException(exception,message) \
430 { \
431   if (quantum_info != (QuantumInfo *) NULL) \
432     quantum_info=DestroyQuantumInfo(quantum_info); \
433   if (compress_pixels != (unsigned char *) NULL) \
434     compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); \
435   ThrowReaderException((exception),(message)); \
436 }
437 #define ZipMaxExtent(x)  ((x)+(((x)+7) >> 3)+(((x)+63) >> 6)+11)
438 
439 #if defined(MAGICKCORE_BZLIB_DELEGATE)
440   bz_stream
441     bzip_info;
442 #endif
443 
444   char
445     id[MagickPathExtent],
446     keyword[MagickPathExtent],
447     *options;
448 
449   double
450     version;
451 
452   GeometryInfo
453     geometry_info;
454 
455   Image
456     *image;
457 
458   int
459     c;
460 
461   LinkedListInfo
462     *profiles;
463 
464 #if defined(MAGICKCORE_LZMA_DELEGATE)
465   lzma_stream
466     initialize_lzma = LZMA_STREAM_INIT,
467     lzma_info;
468 
469   lzma_allocator
470     allocator;
471 #endif
472 
473   MagickBooleanType
474     status;
475 
476   PixelInfo
477     pixel;
478 
479   MagickStatusType
480     flags;
481 
482   QuantumFormatType
483     quantum_format;
484 
485   QuantumInfo
486     *quantum_info;
487 
488   QuantumType
489     quantum_type;
490 
491   register ssize_t
492     i;
493 
494   size_t
495     compress_extent,
496     extent,
497     length,
498     packet_size;
499 
500   ssize_t
501     count;
502 
503   unsigned char
504     *compress_pixels,
505     *pixels;
506 
507   size_t
508     colors;
509 
510   ssize_t
511     y;
512 
513 #if defined(MAGICKCORE_ZLIB_DELEGATE)
514   z_stream
515     zip_info;
516 #endif
517 
518   /*
519     Open image file.
520   */
521   assert(image_info != (const ImageInfo *) NULL);
522   assert(image_info->signature == MagickCoreSignature);
523   if (image_info->debug != MagickFalse)
524     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
525       image_info->filename);
526   assert(exception != (ExceptionInfo *) NULL);
527   assert(exception->signature == MagickCoreSignature);
528   image=AcquireImage(image_info,exception);
529   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
530   if (status == MagickFalse)
531     {
532       image=DestroyImageList(image);
533       return((Image *) NULL);
534     }
535   /*
536     Decode image header;  header terminates one character beyond a ':'.
537   */
538   c=ReadBlobByte(image);
539   if (c == EOF)
540     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
541   *id='\0';
542   compress_pixels=(unsigned char *) NULL;
543   quantum_info=(QuantumInfo *) NULL;
544   (void) memset(keyword,0,sizeof(keyword));
545   version=0.0;
546   (void) version;
547   do
548   {
549     /*
550       Decode image header;  header terminates one character beyond a ':'.
551     */
552     SetGeometryInfo(&geometry_info);
553     length=MagickPathExtent;
554     options=AcquireString((char *) NULL);
555     quantum_format=UndefinedQuantumFormat;
556     profiles=(LinkedListInfo *) NULL;
557     colors=0;
558     image->depth=8UL;
559     image->compression=NoCompression;
560     while ((isgraph(c) != MagickFalse) && (c != (int) ':'))
561     {
562       register char
563         *p;
564 
565       if (c == (int) '{')
566         {
567           char
568             *comment;
569 
570           /*
571             Read comment-- any text between { }.
572           */
573           length=MagickPathExtent;
574           comment=AcquireString((char *) NULL);
575           for (p=comment; comment != (char *) NULL; p++)
576           {
577             c=ReadBlobByte(image);
578             if (c == (int) '\\')
579               c=ReadBlobByte(image);
580             else
581               if ((c == EOF) || (c == (int) '}'))
582                 break;
583             if ((size_t) (p-comment+1) >= length)
584               {
585                 *p='\0';
586                 length<<=1;
587                 comment=(char *) ResizeQuantumMemory(comment,length+
588                   MagickPathExtent,sizeof(*comment));
589                 if (comment == (char *) NULL)
590                   break;
591                 p=comment+strlen(comment);
592               }
593             *p=(char) c;
594           }
595           if (comment == (char *) NULL)
596             {
597               options=DestroyString(options);
598               ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
599             }
600           *p='\0';
601           (void) SetImageProperty(image,"comment",comment,exception);
602           comment=DestroyString(comment);
603           c=ReadBlobByte(image);
604         }
605       else
606         if (isalnum(c) != MagickFalse)
607           {
608             /*
609               Get the keyword.
610             */
611             length=MagickPathExtent-1;
612             p=keyword;
613             do
614             {
615               if (c == (int) '=')
616                 break;
617               if ((size_t) (p-keyword) < (MagickPathExtent-1))
618                 *p++=(char) c;
619               c=ReadBlobByte(image);
620             } while (c != EOF);
621             *p='\0';
622             p=options;
623             while ((isspace((int) ((unsigned char) c)) != 0) && (c != EOF))
624               c=ReadBlobByte(image);
625             if (c == (int) '=')
626               {
627                 /*
628                   Get the keyword value.
629                 */
630                 c=ReadBlobByte(image);
631                 while ((c != (int) '}') && (c != EOF))
632                 {
633                   if ((size_t) (p-options+1) >= length)
634                     {
635                       *p='\0';
636                       length<<=1;
637                       options=(char *) ResizeQuantumMemory(options,length+
638                         MagickPathExtent,sizeof(*options));
639                       if (options == (char *) NULL)
640                         break;
641                       p=options+strlen(options);
642                     }
643                   *p++=(char) c;
644                   c=ReadBlobByte(image);
645                   if (c == '\\')
646                     {
647                       c=ReadBlobByte(image);
648                       if (c == (int) '}')
649                         {
650                           *p++=(char) c;
651                           c=ReadBlobByte(image);
652                         }
653                     }
654                   if (*options != '{')
655                     if (isspace((int) ((unsigned char) c)) != 0)
656                       break;
657                 }
658                 if (options == (char *) NULL)
659                   ThrowMIFFException(ResourceLimitError,
660                     "MemoryAllocationFailed");
661               }
662             *p='\0';
663             if (*options == '{')
664               (void) CopyMagickString(options,options+1,strlen(options));
665             /*
666               Assign a value to the specified keyword.
667             */
668             switch (*keyword)
669             {
670               case 'a':
671               case 'A':
672               {
673                 if (LocaleCompare(keyword,"alpha-trait") == 0)
674                   {
675                     ssize_t
676                       alpha_trait;
677 
678                     alpha_trait=ParseCommandOption(MagickPixelTraitOptions,
679                       MagickFalse,options);
680                     if (alpha_trait < 0)
681                       break;
682                     image->alpha_trait=(PixelTrait) alpha_trait;
683                     break;
684                   }
685                 (void) SetImageProperty(image,keyword,options,exception);
686                 break;
687               }
688               case 'b':
689               case 'B':
690               {
691                 if (LocaleCompare(keyword,"background-color") == 0)
692                   {
693                     (void) QueryColorCompliance(options,AllCompliance,
694                       &image->background_color,exception);
695                     break;
696                   }
697                 if (LocaleCompare(keyword,"blue-primary") == 0)
698                   {
699                     flags=ParseGeometry(options,&geometry_info);
700                     image->chromaticity.blue_primary.x=geometry_info.rho;
701                     image->chromaticity.blue_primary.y=geometry_info.sigma;
702                     if ((flags & SigmaValue) == 0)
703                       image->chromaticity.blue_primary.y=
704                         image->chromaticity.blue_primary.x;
705                     break;
706                   }
707                 if (LocaleCompare(keyword,"border-color") == 0)
708                   {
709                     (void) QueryColorCompliance(options,AllCompliance,
710                       &image->border_color,exception);
711                     break;
712                   }
713                 (void) SetImageProperty(image,keyword,options,exception);
714                 break;
715               }
716               case 'c':
717               case 'C':
718               {
719                 if (LocaleCompare(keyword,"class") == 0)
720                   {
721                     ssize_t
722                       storage_class;
723 
724                     storage_class=ParseCommandOption(MagickClassOptions,
725                       MagickFalse,options);
726                     if (storage_class < 0)
727                       break;
728                     image->storage_class=(ClassType) storage_class;
729                     break;
730                   }
731                 if (LocaleCompare(keyword,"colors") == 0)
732                   {
733                     colors=StringToUnsignedLong(options);
734                     break;
735                   }
736                 if (LocaleCompare(keyword,"colorspace") == 0)
737                   {
738                     ssize_t
739                       colorspace;
740 
741                     colorspace=ParseCommandOption(MagickColorspaceOptions,
742                       MagickFalse,options);
743                     if (colorspace < 0)
744                       break;
745                     image->colorspace=(ColorspaceType) colorspace;
746                     break;
747                   }
748                 if (LocaleCompare(keyword,"compression") == 0)
749                   {
750                     ssize_t
751                       compression;
752 
753                     compression=ParseCommandOption(MagickCompressOptions,
754                       MagickFalse,options);
755                     if (compression < 0)
756                       break;
757                     image->compression=(CompressionType) compression;
758                     break;
759                   }
760                 if (LocaleCompare(keyword,"columns") == 0)
761                   {
762                     image->columns=StringToUnsignedLong(options);
763                     break;
764                   }
765                 (void) SetImageProperty(image,keyword,options,exception);
766                 break;
767               }
768               case 'd':
769               case 'D':
770               {
771                 if (LocaleCompare(keyword,"delay") == 0)
772                   {
773                     image->delay=StringToUnsignedLong(options);
774                     break;
775                   }
776                 if (LocaleCompare(keyword,"depth") == 0)
777                   {
778                     image->depth=StringToUnsignedLong(options);
779                     break;
780                   }
781                 if (LocaleCompare(keyword,"dispose") == 0)
782                   {
783                     ssize_t
784                       dispose;
785 
786                     dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,
787                       options);
788                     if (dispose < 0)
789                       break;
790                     image->dispose=(DisposeType) dispose;
791                     break;
792                   }
793                 (void) SetImageProperty(image,keyword,options,exception);
794                 break;
795               }
796               case 'e':
797               case 'E':
798               {
799                 if (LocaleCompare(keyword,"endian") == 0)
800                   {
801                     ssize_t
802                       endian;
803 
804                     endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
805                       options);
806                     if (endian < 0)
807                       break;
808                     image->endian=(EndianType) endian;
809                     break;
810                   }
811                 (void) SetImageProperty(image,keyword,options,exception);
812                 break;
813               }
814               case 'g':
815               case 'G':
816               {
817                 if (LocaleCompare(keyword,"gamma") == 0)
818                   {
819                     image->gamma=StringToDouble(options,(char **) NULL);
820                     break;
821                   }
822                 if (LocaleCompare(keyword,"gravity") == 0)
823                   {
824                     ssize_t
825                       gravity;
826 
827                     gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
828                       options);
829                     if (gravity < 0)
830                       break;
831                     image->gravity=(GravityType) gravity;
832                     break;
833                   }
834                 if (LocaleCompare(keyword,"green-primary") == 0)
835                   {
836                     flags=ParseGeometry(options,&geometry_info);
837                     image->chromaticity.green_primary.x=geometry_info.rho;
838                     image->chromaticity.green_primary.y=geometry_info.sigma;
839                     if ((flags & SigmaValue) == 0)
840                       image->chromaticity.green_primary.y=
841                         image->chromaticity.green_primary.x;
842                     break;
843                   }
844                 (void) SetImageProperty(image,keyword,options,exception);
845                 break;
846               }
847               case 'i':
848               case 'I':
849               {
850                 if (LocaleCompare(keyword,"id") == 0)
851                   {
852                     (void) CopyMagickString(id,options,MagickPathExtent);
853                     break;
854                   }
855                 if (LocaleCompare(keyword,"iterations") == 0)
856                   {
857                     image->iterations=StringToUnsignedLong(options);
858                     break;
859                   }
860                 (void) SetImageProperty(image,keyword,options,exception);
861                 break;
862               }
863               case 'm':
864               case 'M':
865               {
866                 if (LocaleCompare(keyword,"matte") == 0)
867                   {
868                     ssize_t
869                       matte;
870 
871                     matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
872                       options);
873                     if (matte < 0)
874                       break;
875                     image->alpha_trait=matte == 0 ? UndefinedPixelTrait :
876                       BlendPixelTrait;
877                     break;
878                   }
879                 if (LocaleCompare(keyword,"mattecolor") == 0)
880                   {
881                     (void) QueryColorCompliance(options,AllCompliance,
882                       &image->matte_color,exception);
883                     break;
884                   }
885                 if (LocaleCompare(keyword,"montage") == 0)
886                   {
887                     (void) CloneString(&image->montage,options);
888                     break;
889                   }
890                 (void) SetImageProperty(image,keyword,options,exception);
891                 break;
892               }
893               case 'o':
894               case 'O':
895               {
896                 if (LocaleCompare(keyword,"orientation") == 0)
897                   {
898                     ssize_t
899                       orientation;
900 
901                     orientation=ParseCommandOption(MagickOrientationOptions,
902                       MagickFalse,options);
903                     if (orientation < 0)
904                       break;
905                     image->orientation=(OrientationType) orientation;
906                     break;
907                   }
908                 (void) SetImageProperty(image,keyword,options,exception);
909                 break;
910               }
911               case 'p':
912               case 'P':
913               {
914                 if (LocaleCompare(keyword,"page") == 0)
915                   {
916                     char
917                       *geometry;
918 
919                     geometry=GetPageGeometry(options);
920                     (void) ParseAbsoluteGeometry(geometry,&image->page);
921                     geometry=DestroyString(geometry);
922                     break;
923                   }
924                 if (LocaleCompare(keyword,"pixel-intensity") == 0)
925                   {
926                     ssize_t
927                       intensity;
928 
929                     intensity=ParseCommandOption(MagickPixelIntensityOptions,
930                       MagickFalse,options);
931                     if (intensity < 0)
932                       break;
933                     image->intensity=(PixelIntensityMethod) intensity;
934                     break;
935                   }
936                 if (LocaleCompare(keyword,"profile") == 0)
937                   {
938                     if (profiles == (LinkedListInfo *) NULL)
939                       profiles=NewLinkedList(0);
940                     (void) AppendValueToLinkedList(profiles,
941                       AcquireString(options));
942                     break;
943                   }
944                 (void) SetImageProperty(image,keyword,options,exception);
945                 break;
946               }
947               case 'q':
948               case 'Q':
949               {
950                 if (LocaleCompare(keyword,"quality") == 0)
951                   {
952                     image->quality=StringToUnsignedLong(options);
953                     break;
954                   }
955                 if ((LocaleCompare(keyword,"quantum-format") == 0) ||
956                     (LocaleCompare(keyword,"quantum:format") == 0))
957                   {
958                     ssize_t
959                       format;
960 
961                     format=ParseCommandOption(MagickQuantumFormatOptions,
962                       MagickFalse,options);
963                     if (format < 0)
964                       break;
965                     quantum_format=(QuantumFormatType) format;
966                     break;
967                   }
968                 (void) SetImageProperty(image,keyword,options,exception);
969                 break;
970               }
971               case 'r':
972               case 'R':
973               {
974                 if (LocaleCompare(keyword,"red-primary") == 0)
975                   {
976                     flags=ParseGeometry(options,&geometry_info);
977                     image->chromaticity.red_primary.x=geometry_info.rho;
978                     image->chromaticity.red_primary.y=geometry_info.sigma;
979                     if ((flags & SigmaValue) == 0)
980                       image->chromaticity.red_primary.y=
981                         image->chromaticity.red_primary.x;
982                     break;
983                   }
984                 if (LocaleCompare(keyword,"rendering-intent") == 0)
985                   {
986                     ssize_t
987                       rendering_intent;
988 
989                     rendering_intent=ParseCommandOption(MagickIntentOptions,
990                       MagickFalse,options);
991                     if (rendering_intent < 0)
992                       break;
993                     image->rendering_intent=(RenderingIntent) rendering_intent;
994                     break;
995                   }
996                 if (LocaleCompare(keyword,"resolution") == 0)
997                   {
998                     flags=ParseGeometry(options,&geometry_info);
999                     image->resolution.x=geometry_info.rho;
1000                     image->resolution.y=geometry_info.sigma;
1001                     if ((flags & SigmaValue) == 0)
1002                       image->resolution.y=image->resolution.x;
1003                     break;
1004                   }
1005                 if (LocaleCompare(keyword,"rows") == 0)
1006                   {
1007                     image->rows=StringToUnsignedLong(options);
1008                     break;
1009                   }
1010                 (void) SetImageProperty(image,keyword,options,exception);
1011                 break;
1012               }
1013               case 's':
1014               case 'S':
1015               {
1016                 if (LocaleCompare(keyword,"scene") == 0)
1017                   {
1018                     image->scene=StringToUnsignedLong(options);
1019                     break;
1020                   }
1021                 (void) SetImageProperty(image,keyword,options,exception);
1022                 break;
1023               }
1024               case 't':
1025               case 'T':
1026               {
1027                 if (LocaleCompare(keyword,"ticks-per-second") == 0)
1028                   {
1029                     image->ticks_per_second=(ssize_t) StringToLong(options);
1030                     break;
1031                   }
1032                 if (LocaleCompare(keyword,"tile-offset") == 0)
1033                   {
1034                     char
1035                       *geometry;
1036 
1037                     geometry=GetPageGeometry(options);
1038                     (void) ParseAbsoluteGeometry(geometry,&image->tile_offset);
1039                     geometry=DestroyString(geometry);
1040                     break;
1041                   }
1042                 if (LocaleCompare(keyword,"type") == 0)
1043                   {
1044                     ssize_t
1045                       type;
1046 
1047                     type=ParseCommandOption(MagickTypeOptions,MagickFalse,
1048                       options);
1049                     if (type < 0)
1050                       break;
1051                     image->type=(ImageType) type;
1052                     break;
1053                   }
1054                 (void) SetImageProperty(image,keyword,options,exception);
1055                 break;
1056               }
1057               case 'u':
1058               case 'U':
1059               {
1060                 if (LocaleCompare(keyword,"units") == 0)
1061                   {
1062                     ssize_t
1063                       units;
1064 
1065                     units=ParseCommandOption(MagickResolutionOptions,
1066                       MagickFalse,options);
1067                     if (units < 0)
1068                       break;
1069                     image->units=(ResolutionType) units;
1070                     break;
1071                   }
1072                 (void) SetImageProperty(image,keyword,options,exception);
1073                 break;
1074               }
1075               case 'v':
1076               case 'V':
1077               {
1078                 if (LocaleCompare(keyword,"version") == 0)
1079                   {
1080                     version=StringToDouble(options,(char **) NULL);
1081                     break;
1082                   }
1083                 (void) SetImageProperty(image,keyword,options,exception);
1084                 break;
1085               }
1086               case 'w':
1087               case 'W':
1088               {
1089                 if (LocaleCompare(keyword,"white-point") == 0)
1090                   {
1091                     flags=ParseGeometry(options,&geometry_info);
1092                     image->chromaticity.white_point.x=geometry_info.rho;
1093                     image->chromaticity.white_point.y=geometry_info.sigma;
1094                     if ((flags & SigmaValue) == 0)
1095                       image->chromaticity.white_point.y=
1096                         image->chromaticity.white_point.x;
1097                     break;
1098                   }
1099                 (void) SetImageProperty(image,keyword,options,exception);
1100                 break;
1101               }
1102               default:
1103               {
1104                 (void) SetImageProperty(image,keyword,options,exception);
1105                 break;
1106               }
1107             }
1108           }
1109         else
1110           c=ReadBlobByte(image);
1111       while (isspace((int) ((unsigned char) c)) != 0)
1112         c=ReadBlobByte(image);
1113     }
1114     options=DestroyString(options);
1115     (void) ReadBlobByte(image);
1116     /*
1117       Verify that required image information is defined.
1118     */
1119     if ((LocaleCompare(id,"ImageMagick") != 0) ||
1120         (image->storage_class == UndefinedClass) ||
1121         (image->compression == UndefinedCompression) ||
1122         (image->colorspace == UndefinedColorspace) ||
1123         (image->columns == 0) || (image->rows == 0) ||
1124         (image->depth == 0) || (image->depth > 64))
1125       {
1126         if (profiles != (LinkedListInfo *) NULL)
1127           profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
1128         if (image->previous == (Image *) NULL)
1129           ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1130         DeleteImageFromList(&image);
1131         (void) ThrowMagickException(exception,GetMagickModule(),
1132           CorruptImageError,"ImproperImageHeader","`%s'",image->filename);
1133         break;
1134       }
1135     if (image->montage != (char *) NULL)
1136       {
1137         register char
1138           *p;
1139 
1140         /*
1141           Image directory.
1142         */
1143         extent=MagickPathExtent;
1144         image->directory=AcquireString((char *) NULL);
1145         p=image->directory;
1146         length=0;
1147         do
1148         {
1149           *p='\0';
1150           if ((length+MagickPathExtent) >= extent)
1151             {
1152               /*
1153                 Allocate more memory for the image directory.
1154               */
1155               extent<<=1;
1156               image->directory=(char *) ResizeQuantumMemory(image->directory,
1157                 extent+MagickPathExtent,sizeof(*image->directory));
1158               if (image->directory == (char *) NULL)
1159                 ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1160               p=image->directory+length;
1161             }
1162           c=ReadBlobByte(image);
1163           if (c == EOF)
1164             break;
1165           *p++=(char) c;
1166           length++;
1167         } while (c != (int) '\0');
1168       }
1169     if (profiles != (LinkedListInfo *) NULL)
1170       {
1171         const char
1172           *name;
1173 
1174         StringInfo
1175           *profile;
1176 
1177         /*
1178           Read image profiles.
1179         */
1180         ResetLinkedListIterator(profiles);
1181         name=(const char *) GetNextValueInLinkedList(profiles);
1182         while (name != (const char *) NULL)
1183         {
1184           length=ReadBlobMSBLong(image);
1185           if ((MagickSizeType) length > GetBlobSize(image))
1186             break;
1187           profile=AcquireStringInfo(length);
1188           if (profile == (StringInfo *) NULL)
1189             break;
1190           count=ReadBlob(image,length,GetStringInfoDatum(profile));
1191           if (count != (ssize_t) length)
1192             {
1193               profile=DestroyStringInfo(profile);
1194               break;
1195             }
1196           status=SetImageProfile(image,name,profile,exception);
1197           profile=DestroyStringInfo(profile);
1198           if (status == MagickFalse)
1199             break;
1200           name=(const char *) GetNextValueInLinkedList(profiles);
1201         }
1202         profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
1203       }
1204     image->depth=GetImageQuantumDepth(image,MagickFalse);
1205     if (image->storage_class == PseudoClass)
1206       {
1207         unsigned char
1208           *colormap;
1209 
1210         /*
1211           Create image colormap.
1212         */
1213         packet_size=(size_t) (3UL*image->depth/8UL);
1214         if ((MagickSizeType) colors > GetBlobSize(image))
1215           ThrowMIFFException(CorruptImageError,"InsufficientImageDataInFile");
1216         if (((MagickSizeType) packet_size*colors) > GetBlobSize(image))
1217           ThrowMIFFException(CorruptImageError,"InsufficientImageDataInFile");
1218         status=AcquireImageColormap(image,colors != 0 ? colors : 256,exception);
1219         if (status == MagickFalse)
1220           ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1221         if (colors != 0)
1222           {
1223             const unsigned char
1224               *p;
1225 
1226             /*
1227               Read image colormap from file.
1228             */
1229             colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
1230               packet_size*sizeof(*colormap));
1231             if (colormap == (unsigned char *) NULL)
1232               ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1233             count=ReadBlob(image,packet_size*image->colors,colormap);
1234             p=colormap;
1235             switch (image->depth)
1236             {
1237               default:
1238               {
1239                 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
1240                 ThrowMIFFException(CorruptImageError,"ImageDepthNotSupported");
1241                 break;
1242               }
1243               case 8:
1244               {
1245                 unsigned char
1246                   char_pixel;
1247 
1248                 for (i=0; i < (ssize_t) image->colors; i++)
1249                 {
1250                   p=PushCharPixel(p,&char_pixel);
1251                   image->colormap[i].red=(MagickRealType)
1252                     ScaleCharToQuantum(char_pixel);
1253                   p=PushCharPixel(p,&char_pixel);
1254                   image->colormap[i].green=(MagickRealType)
1255                     ScaleCharToQuantum(char_pixel);
1256                   p=PushCharPixel(p,&char_pixel);
1257                   image->colormap[i].blue=(MagickRealType)
1258                     ScaleCharToQuantum(char_pixel);
1259                 }
1260                 break;
1261               }
1262               case 16:
1263               {
1264                 unsigned short
1265                   short_pixel;
1266 
1267                 for (i=0; i < (ssize_t) image->colors; i++)
1268                 {
1269                   p=PushShortPixel(MSBEndian,p,&short_pixel);
1270                   image->colormap[i].red=(MagickRealType)
1271                     ScaleShortToQuantum(short_pixel);
1272                   p=PushShortPixel(MSBEndian,p,&short_pixel);
1273                   image->colormap[i].green=(MagickRealType)
1274                     ScaleShortToQuantum(short_pixel);
1275                   p=PushShortPixel(MSBEndian,p,&short_pixel);
1276                   image->colormap[i].blue=(MagickRealType)
1277                     ScaleShortToQuantum(short_pixel);
1278                 }
1279                 break;
1280               }
1281               case 32:
1282               {
1283                 unsigned int
1284                   long_pixel;
1285 
1286                 for (i=0; i < (ssize_t) image->colors; i++)
1287                 {
1288                   p=PushLongPixel(MSBEndian,p,&long_pixel);
1289                   image->colormap[i].red=(MagickRealType)
1290                     ScaleLongToQuantum(long_pixel);
1291                   p=PushLongPixel(MSBEndian,p,&long_pixel);
1292                   image->colormap[i].green=(MagickRealType)
1293                     ScaleLongToQuantum(long_pixel);
1294                   p=PushLongPixel(MSBEndian,p,&long_pixel);
1295                   image->colormap[i].blue=(MagickRealType)
1296                     ScaleLongToQuantum(long_pixel);
1297                 }
1298                 break;
1299               }
1300             }
1301             colormap=(unsigned char *) RelinquishMagickMemory(colormap);
1302           }
1303       }
1304     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
1305       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1306         break;
1307     status=SetImageExtent(image,image->columns,image->rows,exception);
1308     if (status == MagickFalse)
1309       return(DestroyImageList(image));
1310     status=ResetImagePixels(image,exception);
1311     if (status == MagickFalse)
1312       return(DestroyImageList(image));
1313     /*
1314       Allocate image pixels.
1315     */
1316     quantum_info=AcquireQuantumInfo(image_info,image);
1317     if (quantum_info == (QuantumInfo *) NULL)
1318       ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1319     if (quantum_format != UndefinedQuantumFormat)
1320       {
1321         status=SetQuantumFormat(image,quantum_info,quantum_format);
1322         if (status == MagickFalse)
1323           ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1324       }
1325     packet_size=(size_t) (quantum_info->depth/8);
1326     if (image->storage_class == DirectClass)
1327       packet_size=(size_t) (3*quantum_info->depth/8);
1328     if (IsGrayColorspace(image->colorspace) != MagickFalse)
1329       packet_size=quantum_info->depth/8;
1330     if (image->alpha_trait != UndefinedPixelTrait)
1331       packet_size+=quantum_info->depth/8;
1332     if (image->colorspace == CMYKColorspace)
1333       packet_size+=quantum_info->depth/8;
1334     if (image->compression == RLECompression)
1335       packet_size++;
1336     compress_extent=MagickMax(MagickMax(BZipMaxExtent(packet_size*
1337       image->columns),LZMAMaxExtent(packet_size*image->columns)),
1338       ZipMaxExtent(packet_size*image->columns));
1339     if (compress_extent < (packet_size*image->columns))
1340       ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1341     compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_extent,
1342       sizeof(*compress_pixels));
1343     if (compress_pixels == (unsigned char *) NULL)
1344       ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1345     /*
1346       Read image pixels.
1347     */
1348     quantum_type=RGBQuantum;
1349     if (image->alpha_trait != UndefinedPixelTrait)
1350       quantum_type=RGBAQuantum;
1351     if (image->colorspace == CMYKColorspace)
1352       {
1353         quantum_type=CMYKQuantum;
1354         if (image->alpha_trait != UndefinedPixelTrait)
1355           quantum_type=CMYKAQuantum;
1356       }
1357     if (IsGrayColorspace(image->colorspace) != MagickFalse)
1358       {
1359         quantum_type=GrayQuantum;
1360         if (image->alpha_trait != UndefinedPixelTrait)
1361           quantum_type=GrayAlphaQuantum;
1362       }
1363     if (image->storage_class == PseudoClass)
1364       {
1365         quantum_type=IndexQuantum;
1366         if (image->alpha_trait != UndefinedPixelTrait)
1367           quantum_type=IndexAlphaQuantum;
1368       }
1369     status=MagickTrue;
1370     GetPixelInfo(image,&pixel);
1371 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1372    (void) memset(&bzip_info,0,sizeof(bzip_info));
1373 #endif
1374 #if defined(MAGICKCORE_LZMA_DELEGATE)
1375     (void) memset(&allocator,0,sizeof(allocator));
1376 #endif
1377 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1378     (void) memset(&zip_info,0,sizeof(zip_info));
1379 #endif
1380     switch (image->compression)
1381     {
1382 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1383       case BZipCompression:
1384       {
1385         int
1386           code;
1387 
1388         bzip_info.bzalloc=AcquireBZIPMemory;
1389         bzip_info.bzfree=RelinquishBZIPMemory;
1390         bzip_info.opaque=(void *) image;
1391         code=BZ2_bzDecompressInit(&bzip_info,(int) image_info->verbose,
1392           MagickFalse);
1393         if (code != BZ_OK)
1394           status=MagickFalse;
1395         break;
1396       }
1397 #endif
1398 #if defined(MAGICKCORE_LZMA_DELEGATE)
1399       case LZMACompression:
1400       {
1401         int
1402           code;
1403 
1404         allocator.alloc=AcquireLZMAMemory;
1405         allocator.free=RelinquishLZMAMemory;
1406         allocator.opaque=(void *) image;
1407         lzma_info=initialize_lzma;
1408         lzma_info.allocator=(&allocator);
1409         code=lzma_auto_decoder(&lzma_info,(uint64_t) -1,0);
1410         if (code != LZMA_OK)
1411           status=MagickFalse;
1412         break;
1413       }
1414 #endif
1415 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1416       case LZWCompression:
1417       case ZipCompression:
1418       {
1419         int
1420           code;
1421 
1422         zip_info.zalloc=AcquireZIPMemory;
1423         zip_info.zfree=RelinquishZIPMemory;
1424         zip_info.opaque=(voidpf) image;
1425         code=inflateInit(&zip_info);
1426         if (code != Z_OK)
1427           status=MagickFalse;
1428         break;
1429       }
1430 #endif
1431       case RLECompression:
1432         break;
1433       default:
1434         break;
1435     }
1436     pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1437     length=0;
1438     for (y=0; y < (ssize_t) image->rows; y++)
1439     {
1440       register ssize_t
1441         x;
1442 
1443       register Quantum
1444         *magick_restrict q;
1445 
1446       if (status == MagickFalse)
1447         break;
1448       q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1449       if (q == (Quantum *) NULL)
1450         break;
1451       extent=0;
1452       switch (image->compression)
1453       {
1454 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1455         case BZipCompression:
1456         {
1457           bzip_info.next_out=(char *) pixels;
1458           bzip_info.avail_out=(unsigned int) (packet_size*image->columns);
1459           do
1460           {
1461             int
1462               code;
1463 
1464             if (bzip_info.avail_in == 0)
1465               {
1466                 bzip_info.next_in=(char *) compress_pixels;
1467                 length=(size_t) BZipMaxExtent(packet_size*image->columns);
1468                 if (version != 0.0)
1469                   length=(size_t) ReadBlobMSBLong(image);
1470                 if (length <= compress_extent)
1471                   bzip_info.avail_in=(unsigned int) ReadBlob(image,length,
1472                     (unsigned char *) bzip_info.next_in);
1473                 if ((length > compress_extent) ||
1474                     ((size_t) bzip_info.avail_in != length))
1475                   {
1476                     (void) BZ2_bzDecompressEnd(&bzip_info);
1477                     ThrowMIFFException(CorruptImageError,
1478                       "UnableToReadImageData");
1479                   }
1480               }
1481             code=BZ2_bzDecompress(&bzip_info);
1482             if ((code != BZ_OK) && (code != BZ_STREAM_END))
1483               {
1484                 status=MagickFalse;
1485                 break;
1486               }
1487             if (code == BZ_STREAM_END)
1488               break;
1489           } while (bzip_info.avail_out != 0);
1490           extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1491             quantum_type,pixels,exception);
1492           break;
1493         }
1494 #endif
1495 #if defined(MAGICKCORE_LZMA_DELEGATE)
1496         case LZMACompression:
1497         {
1498           lzma_info.next_out=pixels;
1499           lzma_info.avail_out=packet_size*image->columns;
1500           do
1501           {
1502             int
1503               code;
1504 
1505             if (lzma_info.avail_in == 0)
1506               {
1507                 lzma_info.next_in=compress_pixels;
1508                 length=(size_t) ReadBlobMSBLong(image);
1509                 if (length <= compress_extent)
1510                   lzma_info.avail_in=(unsigned int) ReadBlob(image,length,
1511                     (unsigned char *) lzma_info.next_in);
1512                 if ((length > compress_extent) ||
1513                     (lzma_info.avail_in != length))
1514                   {
1515                     lzma_end(&lzma_info);
1516                     ThrowMIFFException(CorruptImageError,
1517                       "UnableToReadImageData");
1518                   }
1519               }
1520             code=lzma_code(&lzma_info,LZMA_RUN);
1521             if ((code != LZMA_OK) && (code != LZMA_STREAM_END))
1522               {
1523                 status=MagickFalse;
1524                 break;
1525               }
1526             if (code == LZMA_STREAM_END)
1527               break;
1528           } while (lzma_info.avail_out != 0);
1529           extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1530             quantum_type,pixels,exception);
1531           break;
1532         }
1533 #endif
1534 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1535         case LZWCompression:
1536         case ZipCompression:
1537         {
1538           zip_info.next_out=pixels;
1539           zip_info.avail_out=(uInt) (packet_size*image->columns);
1540           do
1541           {
1542             int
1543               code;
1544 
1545             if (zip_info.avail_in == 0)
1546               {
1547                 zip_info.next_in=compress_pixels;
1548                 length=(size_t) ZipMaxExtent(packet_size*image->columns);
1549                 if (version != 0.0)
1550                   length=(size_t) ReadBlobMSBLong(image);
1551                 if (length <= compress_extent)
1552                   zip_info.avail_in=(unsigned int) ReadBlob(image,length,
1553                     zip_info.next_in);
1554                 if ((length > compress_extent) ||
1555                     ((size_t) zip_info.avail_in != length))
1556                   {
1557                     (void) inflateEnd(&zip_info);
1558                     ThrowMIFFException(CorruptImageError,
1559                       "UnableToReadImageData");
1560                   }
1561               }
1562             code=inflate(&zip_info,Z_SYNC_FLUSH);
1563             if ((code != Z_OK) && (code != Z_STREAM_END))
1564               {
1565                 status=MagickFalse;
1566                 break;
1567               }
1568             if (code == Z_STREAM_END)
1569               break;
1570           } while (zip_info.avail_out != 0);
1571           extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1572             quantum_type,pixels,exception);
1573           break;
1574         }
1575 #endif
1576         case RLECompression:
1577         {
1578           for (x=0; x < (ssize_t) image->columns; x++)
1579           {
1580             if (length == 0)
1581               {
1582                 count=ReadBlob(image,packet_size,pixels);
1583                 if (count != (ssize_t) packet_size)
1584                   ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1585                 PushRunlengthPacket(image,pixels,&length,&pixel,exception);
1586               }
1587             length--;
1588             if (image->storage_class == PseudoClass)
1589               SetPixelIndex(image,ClampToQuantum(pixel.index),q);
1590             else
1591               {
1592                 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1593                 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1594                 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1595                 if (image->colorspace == CMYKColorspace)
1596                   SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1597               }
1598             if (image->alpha_trait != UndefinedPixelTrait)
1599               SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1600             q+=GetPixelChannels(image);
1601           }
1602           extent=(size_t) x;
1603           break;
1604         }
1605         default:
1606         {
1607           count=ReadBlob(image,packet_size*image->columns,pixels);
1608           if (count != (ssize_t) (packet_size*image->columns))
1609             ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1610           extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1611             quantum_type,pixels,exception);
1612           break;
1613         }
1614       }
1615       if (extent < image->columns)
1616         break;
1617       if (SyncAuthenticPixels(image,exception) == MagickFalse)
1618         break;
1619     }
1620     SetQuantumImageType(image,quantum_type);
1621     switch (image->compression)
1622     {
1623 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1624       case BZipCompression:
1625       {
1626         int
1627           code;
1628 
1629         if (version == 0.0)
1630           {
1631             MagickOffsetType
1632               offset;
1633 
1634             offset=SeekBlob(image,-((MagickOffsetType) bzip_info.avail_in),
1635               SEEK_CUR);
1636             if (offset < 0)
1637               {
1638                 (void) BZ2_bzDecompressEnd(&bzip_info);
1639                 ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1640               }
1641           }
1642         code=BZ2_bzDecompressEnd(&bzip_info);
1643         if (code != BZ_OK)
1644           status=MagickFalse;
1645         break;
1646       }
1647 #endif
1648 #if defined(MAGICKCORE_LZMA_DELEGATE)
1649       case LZMACompression:
1650       {
1651         int
1652           code;
1653 
1654         code=lzma_code(&lzma_info,LZMA_FINISH);
1655         if ((code != LZMA_STREAM_END) && (code != LZMA_OK))
1656           status=MagickFalse;
1657         lzma_end(&lzma_info);
1658         break;
1659       }
1660 #endif
1661 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1662       case LZWCompression:
1663       case ZipCompression:
1664       {
1665         int
1666           code;
1667 
1668         if (version == 0.0)
1669           {
1670             MagickOffsetType
1671               offset;
1672 
1673             offset=SeekBlob(image,-((MagickOffsetType) zip_info.avail_in),
1674               SEEK_CUR);
1675             if (offset < 0)
1676               {
1677                 (void) inflateEnd(&zip_info);
1678                 ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1679               }
1680           }
1681         code=inflateEnd(&zip_info);
1682         if (code != Z_OK)
1683           status=MagickFalse;
1684         break;
1685       }
1686 #endif
1687       default:
1688         break;
1689     }
1690     quantum_info=DestroyQuantumInfo(quantum_info);
1691     compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
1692     if (((y != (ssize_t) image->rows)) || (status == MagickFalse))
1693       {
1694         image=DestroyImageList(image);
1695         return((Image *) NULL);
1696       }
1697     if (EOFBlob(image) != MagickFalse)
1698       {
1699         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
1700           image->filename);
1701         break;
1702       }
1703     /*
1704       Proceed to next image.
1705     */
1706     if (image_info->number_scenes != 0)
1707       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1708         break;
1709     do
1710     {
1711       c=ReadBlobByte(image);
1712     } while ((isgraph(c) == MagickFalse) && (c != EOF));
1713     if (c != EOF)
1714       {
1715         /*
1716           Allocate next image structure.
1717         */
1718         AcquireNextImage(image_info,image,exception);
1719         if (GetNextImageInList(image) == (Image *) NULL)
1720           {
1721             status=MagickFalse;
1722             break;
1723           }
1724         image=SyncNextImageInList(image);
1725         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1726           GetBlobSize(image));
1727         if (status == MagickFalse)
1728           break;
1729       }
1730   } while (c != EOF);
1731   (void) CloseBlob(image);
1732   if (status == MagickFalse)
1733     return(DestroyImageList(image));
1734   return(GetFirstImageInList(image));
1735 }
1736 
1737 /*
1738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1739 %                                                                             %
1740 %                                                                             %
1741 %                                                                             %
1742 %   R e g i s t e r M I F F I m a g e                                         %
1743 %                                                                             %
1744 %                                                                             %
1745 %                                                                             %
1746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1747 %
1748 %  RegisterMIFFImage() adds properties for the MIFF image format to the list of
1749 %  supported formats.  The properties include the image format tag, a method to
1750 %  read and/or write the format, whether the format supports the saving of more
1751 %  than one frame to the same file or blob, whether the format supports native
1752 %  in-memory I/O, and a brief description of the format.
1753 %
1754 %  The format of the RegisterMIFFImage method is:
1755 %
1756 %      size_t RegisterMIFFImage(void)
1757 %
1758 */
RegisterMIFFImage(void)1759 ModuleExport size_t RegisterMIFFImage(void)
1760 {
1761   char
1762     version[MagickPathExtent];
1763 
1764   MagickInfo
1765     *entry;
1766 
1767   *version='\0';
1768 #if defined(MagickImageCoderSignatureText)
1769   (void) CopyMagickString(version,MagickLibVersionText,MagickPathExtent);
1770 #if defined(ZLIB_VERSION)
1771   (void) ConcatenateMagickString(version," with Zlib ",MagickPathExtent);
1772   (void) ConcatenateMagickString(version,ZLIB_VERSION,MagickPathExtent);
1773 #endif
1774 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1775   (void) ConcatenateMagickString(version," and BZlib",MagickPathExtent);
1776 #endif
1777 #endif
1778   entry=AcquireMagickInfo("MIFF","MIFF","Magick Image File Format");
1779   entry->decoder=(DecodeImageHandler *) ReadMIFFImage;
1780   entry->encoder=(EncodeImageHandler *) WriteMIFFImage;
1781   entry->magick=(IsImageFormatHandler *) IsMIFF;
1782   entry->flags|=CoderDecoderSeekableStreamFlag;
1783   if (*version != '\0')
1784     entry->version=ConstantString(version);
1785   (void) RegisterMagickInfo(entry);
1786   return(MagickImageCoderSignature);
1787 }
1788 
1789 /*
1790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1791 %                                                                             %
1792 %                                                                             %
1793 %                                                                             %
1794 %   U n r e g i s t e r M I F F I m a g e                                     %
1795 %                                                                             %
1796 %                                                                             %
1797 %                                                                             %
1798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1799 %
1800 %  UnregisterMIFFImage() removes format registrations made by the MIFF module
1801 %  from the list of supported formats.
1802 %
1803 %  The format of the UnregisterMIFFImage method is:
1804 %
1805 %      UnregisterMIFFImage(void)
1806 %
1807 */
UnregisterMIFFImage(void)1808 ModuleExport void UnregisterMIFFImage(void)
1809 {
1810   (void) UnregisterMagickInfo("MIFF");
1811 }
1812 
1813 /*
1814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1815 %                                                                             %
1816 %                                                                             %
1817 %                                                                             %
1818 %   W r i t e M I F F I m a g e                                               %
1819 %                                                                             %
1820 %                                                                             %
1821 %                                                                             %
1822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1823 %
1824 %  WriteMIFFImage() writes a MIFF image to a file.
1825 %
1826 %  The format of the WriteMIFFImage method is:
1827 %
1828 %      MagickBooleanType WriteMIFFImage(const ImageInfo *image_info,
1829 %        Image *image,ExceptionInfo *exception)
1830 %
1831 %  Compression code contributed by Kyle Shorter.
1832 %
1833 %  A description of each parameter follows:
1834 %
1835 %    o image_info: the image info.
1836 %
1837 %    o image: the image.
1838 %
1839 %    o exception: return any errors or warnings in this structure.
1840 %
1841 */
1842 
PopRunlengthPacket(Image * image,unsigned char * pixels,size_t length,PixelInfo * pixel,ExceptionInfo * exception)1843 static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
1844   size_t length,PixelInfo *pixel,ExceptionInfo *exception)
1845 {
1846   if (image->storage_class != DirectClass)
1847     {
1848       unsigned int
1849         value;
1850 
1851       value=(unsigned int) ClampToQuantum(pixel->index);
1852       switch (image->depth)
1853       {
1854         case 32:
1855         {
1856           *pixels++=(unsigned char) (value >> 24);
1857           *pixels++=(unsigned char) (value >> 16);
1858         }
1859         case 16:
1860           *pixels++=(unsigned char) (value >> 8);
1861         case 8:
1862         {
1863           *pixels++=(unsigned char) value;
1864           break;
1865         }
1866         default:
1867           (void) ThrowMagickException(exception,GetMagickModule(),
1868             CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename);
1869       }
1870       switch (image->depth)
1871       {
1872         case 32:
1873         {
1874           unsigned int
1875             long_value;
1876 
1877           if (image->alpha_trait != UndefinedPixelTrait)
1878             {
1879               long_value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
1880               pixels=PopLongPixel(MSBEndian,long_value,pixels);
1881             }
1882           break;
1883         }
1884         case 16:
1885         {
1886           unsigned short
1887             short_value;
1888 
1889           if (image->alpha_trait != UndefinedPixelTrait)
1890             {
1891               short_value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
1892               pixels=PopShortPixel(MSBEndian,short_value,pixels);
1893             }
1894           break;
1895         }
1896         case 8:
1897         {
1898           unsigned char
1899             char_value;
1900 
1901           if (image->alpha_trait != UndefinedPixelTrait)
1902             {
1903               char_value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1904                 pixel->alpha));
1905               pixels=PopCharPixel(char_value,pixels);
1906             }
1907           break;
1908         }
1909         default:
1910           (void) ThrowMagickException(exception,GetMagickModule(),
1911             CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename);
1912       }
1913       *pixels++=(unsigned char) length;
1914       return(pixels);
1915     }
1916   switch (image->depth)
1917   {
1918     case 32:
1919     {
1920       unsigned int
1921         value;
1922 
1923       value=ScaleQuantumToLong(ClampToQuantum(pixel->red));
1924       pixels=PopLongPixel(MSBEndian,value,pixels);
1925       if (IsGrayColorspace(image->colorspace) == MagickFalse)
1926         {
1927           value=ScaleQuantumToLong(ClampToQuantum(pixel->green));
1928           pixels=PopLongPixel(MSBEndian,value,pixels);
1929           value=ScaleQuantumToLong(ClampToQuantum(pixel->blue));
1930           pixels=PopLongPixel(MSBEndian,value,pixels);
1931         }
1932       if (image->colorspace == CMYKColorspace)
1933         {
1934           value=ScaleQuantumToLong(ClampToQuantum(pixel->black));
1935           pixels=PopLongPixel(MSBEndian,value,pixels);
1936         }
1937       if (image->alpha_trait != UndefinedPixelTrait)
1938         {
1939           value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
1940           pixels=PopLongPixel(MSBEndian,value,pixels);
1941         }
1942       break;
1943     }
1944     case 16:
1945     {
1946       unsigned short
1947         value;
1948 
1949       value=ScaleQuantumToShort(ClampToQuantum(pixel->red));
1950       pixels=PopShortPixel(MSBEndian,value,pixels);
1951       if (IsGrayColorspace(image->colorspace) == MagickFalse)
1952         {
1953           value=ScaleQuantumToShort(ClampToQuantum(pixel->green));
1954           pixels=PopShortPixel(MSBEndian,value,pixels);
1955           value=ScaleQuantumToShort(ClampToQuantum(pixel->blue));
1956           pixels=PopShortPixel(MSBEndian,value,pixels);
1957         }
1958       if (image->colorspace == CMYKColorspace)
1959         {
1960           value=ScaleQuantumToShort(ClampToQuantum(pixel->black));
1961           pixels=PopShortPixel(MSBEndian,value,pixels);
1962         }
1963       if (image->alpha_trait != UndefinedPixelTrait)
1964         {
1965           value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
1966           pixels=PopShortPixel(MSBEndian,value,pixels);
1967         }
1968       break;
1969     }
1970     case 8:
1971     {
1972       unsigned char
1973         value;
1974 
1975       value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->red));
1976       pixels=PopCharPixel(value,pixels);
1977       if (IsGrayColorspace(image->colorspace) == MagickFalse)
1978         {
1979           value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1980             pixel->green));
1981           pixels=PopCharPixel(value,pixels);
1982           value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->blue));
1983           pixels=PopCharPixel(value,pixels);
1984         }
1985       if (image->colorspace == CMYKColorspace)
1986         {
1987           value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1988             pixel->black));
1989           pixels=PopCharPixel(value,pixels);
1990         }
1991       if (image->alpha_trait != UndefinedPixelTrait)
1992         {
1993           value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1994             pixel->alpha));
1995           pixels=PopCharPixel(value,pixels);
1996         }
1997       break;
1998     }
1999     default:
2000       (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError,
2001         "ImageDepthNotSupported","`%s'",image->filename);
2002   }
2003   *pixels++=(unsigned char) length;
2004   return(pixels);
2005 }
2006 
WriteMIFFImage(const ImageInfo * image_info,Image * image,ExceptionInfo * exception)2007 static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info,
2008   Image *image,ExceptionInfo *exception)
2009 {
2010 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2011   bz_stream
2012     bzip_info;
2013 #endif
2014 
2015   char
2016     buffer[MagickPathExtent];
2017 
2018   CompressionType
2019     compression;
2020 
2021   const char
2022     *property,
2023     *value;
2024 
2025 #if defined(MAGICKCORE_LZMA_DELEGATE)
2026   lzma_allocator
2027     allocator;
2028 
2029   lzma_stream
2030     initialize_lzma = LZMA_STREAM_INIT,
2031     lzma_info;
2032 #endif
2033 
2034   MagickBooleanType
2035     status;
2036 
2037   MagickOffsetType
2038     scene;
2039 
2040   PixelInfo
2041     pixel,
2042     target;
2043 
2044   QuantumInfo
2045     *quantum_info;
2046 
2047   QuantumType
2048     quantum_type;
2049 
2050   register ssize_t
2051     i;
2052 
2053   size_t
2054     imageListLength,
2055     length,
2056     packet_size;
2057 
2058   ssize_t
2059     y;
2060 
2061   unsigned char
2062     *compress_pixels,
2063     *pixels,
2064     *q;
2065 
2066 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2067   z_stream
2068     zip_info;
2069 #endif
2070 
2071   /*
2072     Open output image file.
2073   */
2074   assert(image_info != (const ImageInfo *) NULL);
2075   assert(image_info->signature == MagickCoreSignature);
2076   assert(image != (Image *) NULL);
2077   assert(image->signature == MagickCoreSignature);
2078   if (image->debug != MagickFalse)
2079     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2080   assert(exception != (ExceptionInfo *) NULL);
2081   assert(exception->signature == MagickCoreSignature);
2082   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
2083   if (status == MagickFalse)
2084     return(status);
2085   scene=0;
2086   imageListLength=GetImageListLength(image);
2087   do
2088   {
2089     /*
2090       Allocate image pixels.
2091     */
2092     if ((image->storage_class == PseudoClass) &&
2093         (image->colors > (size_t) (GetQuantumRange(image->depth)+1)))
2094       (void) SetImageStorageClass(image,DirectClass,exception);
2095     image->depth=image->depth <= 8 ? 8UL : image->depth <= 16 ? 16UL :
2096       image->depth <= 32 ? 32UL : 64UL;
2097     quantum_info=AcquireQuantumInfo(image_info,image);
2098     if (quantum_info == (QuantumInfo *) NULL)
2099       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2100     if ((image->storage_class != PseudoClass) && (image->depth >= 16) &&
2101         (quantum_info->format == UndefinedQuantumFormat) &&
2102         (IsHighDynamicRangeImage(image,exception) != MagickFalse))
2103       {
2104         status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2105         if (status == MagickFalse)
2106           {
2107             quantum_info=DestroyQuantumInfo(quantum_info);
2108             ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2109           }
2110       }
2111     else
2112       if (image->depth < 16)
2113         (void) DeleteImageProperty(image,"quantum:format");
2114     compression=UndefinedCompression;
2115     if (image_info->compression != UndefinedCompression)
2116       compression=image_info->compression;
2117     switch (compression)
2118     {
2119 #if !defined(MAGICKCORE_LZMA_DELEGATE)
2120       case LZMACompression: compression=NoCompression; break;
2121 #endif
2122 #if !defined(MAGICKCORE_ZLIB_DELEGATE)
2123       case LZWCompression:
2124       case ZipCompression: compression=NoCompression; break;
2125 #endif
2126 #if !defined(MAGICKCORE_BZLIB_DELEGATE)
2127       case BZipCompression: compression=NoCompression; break;
2128 #endif
2129       case RLECompression:
2130       {
2131         if (quantum_info->format == FloatingPointQuantumFormat)
2132           compression=NoCompression;
2133         GetPixelInfo(image,&target);
2134         break;
2135       }
2136       default:
2137         break;
2138     }
2139     packet_size=(size_t) (quantum_info->depth/8);
2140     if (image->storage_class == DirectClass)
2141       packet_size=(size_t) (3*quantum_info->depth/8);
2142     if (IsGrayColorspace(image->colorspace) != MagickFalse)
2143       packet_size=(size_t) (quantum_info->depth/8);
2144     if (image->alpha_trait != UndefinedPixelTrait)
2145       packet_size+=quantum_info->depth/8;
2146     if (image->colorspace == CMYKColorspace)
2147       packet_size+=quantum_info->depth/8;
2148     if (compression == RLECompression)
2149       packet_size++;
2150     length=MagickMax(BZipMaxExtent(packet_size*image->columns),ZipMaxExtent(
2151       packet_size*image->columns));
2152     if ((compression == BZipCompression) || (compression == ZipCompression))
2153       if (length != (size_t) ((unsigned int) length))
2154         compression=NoCompression;
2155     compress_pixels=(unsigned char *) AcquireQuantumMemory(length,
2156       sizeof(*compress_pixels));
2157     if (compress_pixels == (unsigned char *) NULL)
2158       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2159     /*
2160       Write MIFF header.
2161     */
2162     (void) WriteBlobString(image,"id=ImageMagick  version=1.0\n");
2163     (void) FormatLocaleString(buffer,MagickPathExtent,
2164       "class=%s  colors=%.20g  alpha-trait=%s\n",CommandOptionToMnemonic(
2165       MagickClassOptions,image->storage_class),(double) image->colors,
2166       CommandOptionToMnemonic(MagickPixelTraitOptions,(ssize_t)
2167       image->alpha_trait));
2168     (void) WriteBlobString(image,buffer);
2169     if (image->alpha_trait != UndefinedPixelTrait)
2170       (void) WriteBlobString(image,"matte=True\n");
2171     (void) FormatLocaleString(buffer,MagickPathExtent,
2172       "columns=%.20g  rows=%.20g  depth=%.20g\n",(double) image->columns,
2173       (double) image->rows,(double) image->depth);
2174     (void) WriteBlobString(image,buffer);
2175     if (image->type != UndefinedType)
2176       {
2177         (void) FormatLocaleString(buffer,MagickPathExtent,"type=%s\n",
2178           CommandOptionToMnemonic(MagickTypeOptions,image->type));
2179         (void) WriteBlobString(image,buffer);
2180       }
2181     if (image->colorspace != UndefinedColorspace)
2182       {
2183         (void) FormatLocaleString(buffer,MagickPathExtent,"colorspace=%s\n",
2184           CommandOptionToMnemonic(MagickColorspaceOptions,image->colorspace));
2185         (void) WriteBlobString(image,buffer);
2186       }
2187     if (image->intensity != UndefinedPixelIntensityMethod)
2188       {
2189         (void) FormatLocaleString(buffer,MagickPathExtent,
2190           "pixel-intensity=%s\n",CommandOptionToMnemonic(
2191           MagickPixelIntensityOptions,image->intensity));
2192         (void) WriteBlobString(image,buffer);
2193       }
2194     if (image->endian != UndefinedEndian)
2195       {
2196         (void) FormatLocaleString(buffer,MagickPathExtent,"endian=%s\n",
2197           CommandOptionToMnemonic(MagickEndianOptions,image->endian));
2198         (void) WriteBlobString(image,buffer);
2199       }
2200     if (compression != UndefinedCompression)
2201       {
2202         (void) FormatLocaleString(buffer,MagickPathExtent,"compression=%s  "
2203           "quality=%.20g\n",CommandOptionToMnemonic(MagickCompressOptions,
2204           compression),(double) image->quality);
2205         (void) WriteBlobString(image,buffer);
2206       }
2207     if (image->units != UndefinedResolution)
2208       {
2209         (void) FormatLocaleString(buffer,MagickPathExtent,"units=%s\n",
2210           CommandOptionToMnemonic(MagickResolutionOptions,image->units));
2211         (void) WriteBlobString(image,buffer);
2212       }
2213     if ((image->resolution.x != 0) || (image->resolution.y != 0))
2214       {
2215         (void) FormatLocaleString(buffer,MagickPathExtent,
2216           "resolution=%gx%g\n",image->resolution.x,image->resolution.y);
2217         (void) WriteBlobString(image,buffer);
2218       }
2219     if ((image->page.width != 0) || (image->page.height != 0))
2220       {
2221         (void) FormatLocaleString(buffer,MagickPathExtent,
2222           "page=%.20gx%.20g%+.20g%+.20g\n",(double) image->page.width,(double)
2223           image->page.height,(double) image->page.x,(double) image->page.y);
2224         (void) WriteBlobString(image,buffer);
2225       }
2226     else
2227       if ((image->page.x != 0) || (image->page.y != 0))
2228         {
2229           (void) FormatLocaleString(buffer,MagickPathExtent,"page=%+ld%+ld\n",
2230             (long) image->page.x,(long) image->page.y);
2231           (void) WriteBlobString(image,buffer);
2232         }
2233     if ((image->tile_offset.x != 0) || (image->tile_offset.y != 0))
2234       {
2235         (void) FormatLocaleString(buffer,MagickPathExtent,
2236           "tile-offset=%+ld%+ld\n",(long) image->tile_offset.x,(long)
2237           image->tile_offset.y);
2238         (void) WriteBlobString(image,buffer);
2239       }
2240     if ((GetNextImageInList(image) != (Image *) NULL) ||
2241         (GetPreviousImageInList(image) != (Image *) NULL))
2242       {
2243         if (image->scene == 0)
2244           (void) FormatLocaleString(buffer,MagickPathExtent,"iterations=%.20g  "
2245             "delay=%.20g  ticks-per-second=%.20g\n",(double) image->iterations,
2246             (double) image->delay,(double) image->ticks_per_second);
2247         else
2248           (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g  "
2249             "iterations=%.20g  delay=%.20g  ticks-per-second=%.20g\n",(double)
2250             image->scene,(double) image->iterations,(double) image->delay,
2251             (double) image->ticks_per_second);
2252         (void) WriteBlobString(image,buffer);
2253       }
2254     else
2255       {
2256         if (image->scene != 0)
2257           {
2258             (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g\n",
2259               (double) image->scene);
2260             (void) WriteBlobString(image,buffer);
2261           }
2262         if (image->iterations != 0)
2263           {
2264             (void) FormatLocaleString(buffer,MagickPathExtent,
2265               "iterations=%.20g\n",(double) image->iterations);
2266             (void) WriteBlobString(image,buffer);
2267           }
2268         if (image->delay != 0)
2269           {
2270             (void) FormatLocaleString(buffer,MagickPathExtent,"delay=%.20g\n",
2271               (double) image->delay);
2272             (void) WriteBlobString(image,buffer);
2273           }
2274         if (image->ticks_per_second != UndefinedTicksPerSecond)
2275           {
2276             (void) FormatLocaleString(buffer,MagickPathExtent,
2277               "ticks-per-second=%.20g\n",(double) image->ticks_per_second);
2278             (void) WriteBlobString(image,buffer);
2279           }
2280       }
2281     if (image->gravity != UndefinedGravity)
2282       {
2283         (void) FormatLocaleString(buffer,MagickPathExtent,"gravity=%s\n",
2284           CommandOptionToMnemonic(MagickGravityOptions,image->gravity));
2285         (void) WriteBlobString(image,buffer);
2286       }
2287     if (image->dispose != UndefinedDispose)
2288       {
2289         (void) FormatLocaleString(buffer,MagickPathExtent,"dispose=%s\n",
2290           CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
2291         (void) WriteBlobString(image,buffer);
2292       }
2293     if (image->rendering_intent != UndefinedIntent)
2294       {
2295         (void) FormatLocaleString(buffer,MagickPathExtent,
2296           "rendering-intent=%s\n",CommandOptionToMnemonic(MagickIntentOptions,
2297           image->rendering_intent));
2298         (void) WriteBlobString(image,buffer);
2299       }
2300     if (image->gamma != 0.0)
2301       {
2302         (void) FormatLocaleString(buffer,MagickPathExtent,"gamma=%g\n",
2303           image->gamma);
2304         (void) WriteBlobString(image,buffer);
2305       }
2306     if (image->chromaticity.white_point.x != 0.0)
2307       {
2308         /*
2309           Note chomaticity points.
2310         */
2311         (void) FormatLocaleString(buffer,MagickPathExtent,"red-primary=%g,"
2312           "%g  green-primary=%g,%g  blue-primary=%g,%g\n",
2313           image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
2314           image->chromaticity.green_primary.x,
2315           image->chromaticity.green_primary.y,
2316           image->chromaticity.blue_primary.x,
2317           image->chromaticity.blue_primary.y);
2318         (void) WriteBlobString(image,buffer);
2319         (void) FormatLocaleString(buffer,MagickPathExtent,
2320           "white-point=%g,%g\n",image->chromaticity.white_point.x,
2321           image->chromaticity.white_point.y);
2322         (void) WriteBlobString(image,buffer);
2323       }
2324     if (image->orientation != UndefinedOrientation)
2325       {
2326         (void) FormatLocaleString(buffer,MagickPathExtent,"orientation=%s\n",
2327           CommandOptionToMnemonic(MagickOrientationOptions,image->orientation));
2328         (void) WriteBlobString(image,buffer);
2329       }
2330     if (image->profiles != (void *) NULL)
2331       {
2332         const char
2333           *name;
2334 
2335         const StringInfo
2336           *profile;
2337 
2338         /*
2339           Write image profile names.
2340         */
2341         ResetImageProfileIterator(image);
2342         for (name=GetNextImageProfile(image); name != (const char *) NULL; )
2343         {
2344           profile=GetImageProfile(image,name);
2345           if (profile != (StringInfo *) NULL)
2346             {
2347               (void) FormatLocaleString(buffer,MagickPathExtent,"profile=%s\n",
2348                 name);
2349               (void) WriteBlobString(image,buffer);
2350             }
2351           name=GetNextImageProfile(image);
2352         }
2353       }
2354     if (image->montage != (char *) NULL)
2355       {
2356         (void) FormatLocaleString(buffer,MagickPathExtent,"montage=%s\n",
2357           image->montage);
2358         (void) WriteBlobString(image,buffer);
2359       }
2360     if (quantum_info->format == FloatingPointQuantumFormat)
2361       (void) SetImageProperty(image,"quantum:format","floating-point",
2362         exception);
2363     ResetImagePropertyIterator(image);
2364     property=GetNextImageProperty(image);
2365     while (property != (const char *) NULL)
2366     {
2367       (void) FormatLocaleString(buffer,MagickPathExtent,"%s=",property);
2368       (void) WriteBlobString(image,buffer);
2369       value=GetImageProperty(image,property,exception);
2370       if (value != (const char *) NULL)
2371         {
2372           length=strlen(value);
2373           for (i=0; i < (ssize_t) length; i++)
2374             if ((isspace((int) ((unsigned char) value[i])) != 0) ||
2375                 (value[i] == '}'))
2376               break;
2377           if ((i == (ssize_t) length) && (i != 0))
2378             (void) WriteBlob(image,length,(const unsigned char *) value);
2379           else
2380             {
2381               (void) WriteBlobByte(image,'{');
2382               if (strchr(value,'}') == (char *) NULL)
2383                 (void) WriteBlob(image,length,(const unsigned char *) value);
2384               else
2385                 for (i=0; i < (ssize_t) length; i++)
2386                 {
2387                   if (value[i] == (int) '}')
2388                     (void) WriteBlobByte(image,'\\');
2389                   (void) WriteBlobByte(image,(unsigned char) value[i]);
2390                 }
2391               (void) WriteBlobByte(image,'}');
2392             }
2393         }
2394       (void) WriteBlobByte(image,'\n');
2395       property=GetNextImageProperty(image);
2396     }
2397     (void) WriteBlobString(image,"\f\n:\032");
2398     if (image->montage != (char *) NULL)
2399       {
2400         /*
2401           Write montage tile directory.
2402         */
2403         if (image->directory != (char *) NULL)
2404           (void) WriteBlob(image,strlen(image->directory),(unsigned char *)
2405             image->directory);
2406         (void) WriteBlobByte(image,'\0');
2407       }
2408     if (image->profiles != 0)
2409       {
2410         const char
2411           *name;
2412 
2413         const StringInfo
2414           *profile;
2415 
2416         /*
2417           Write image profile blob.
2418         */
2419         ResetImageProfileIterator(image);
2420         name=GetNextImageProfile(image);
2421         while (name != (const char *) NULL)
2422         {
2423           profile=GetImageProfile(image,name);
2424           (void) WriteBlobMSBLong(image,(unsigned int)
2425             GetStringInfoLength(profile));
2426           (void) WriteBlob(image,GetStringInfoLength(profile),
2427             GetStringInfoDatum(profile));
2428           name=GetNextImageProfile(image);
2429         }
2430       }
2431     if (image->storage_class == PseudoClass)
2432       {
2433         size_t
2434           colormap_size;
2435 
2436         unsigned char
2437           *colormap;
2438 
2439         /*
2440           Allocate colormap.
2441         */
2442         colormap_size=(size_t) (3*quantum_info->depth/8);
2443         colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
2444           colormap_size*sizeof(*colormap));
2445         if (colormap == (unsigned char *) NULL)
2446           ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2447         /*
2448           Write colormap to file.
2449         */
2450         q=colormap;
2451         for (i=0; i < (ssize_t) image->colors; i++)
2452         {
2453           switch (quantum_info->depth)
2454           {
2455             default:
2456               ThrowWriterException(CorruptImageError,"ImageDepthNotSupported");
2457             case 32:
2458             {
2459               register unsigned int
2460                 long_pixel;
2461 
2462               long_pixel=ScaleQuantumToLong((Quantum)
2463                 image->colormap[i].red);
2464               q=PopLongPixel(MSBEndian,long_pixel,q);
2465               long_pixel=ScaleQuantumToLong((Quantum)
2466                 image->colormap[i].green);
2467               q=PopLongPixel(MSBEndian,long_pixel,q);
2468               long_pixel=ScaleQuantumToLong((Quantum)
2469                 image->colormap[i].blue);
2470               q=PopLongPixel(MSBEndian,long_pixel,q);
2471               break;
2472             }
2473             case 16:
2474             {
2475               register unsigned short
2476                 short_pixel;
2477 
2478               short_pixel=ScaleQuantumToShort((Quantum)
2479                 image->colormap[i].red);
2480               q=PopShortPixel(MSBEndian,short_pixel,q);
2481               short_pixel=ScaleQuantumToShort((Quantum)
2482                 image->colormap[i].green);
2483               q=PopShortPixel(MSBEndian,short_pixel,q);
2484               short_pixel=ScaleQuantumToShort((Quantum)
2485                 image->colormap[i].blue);
2486               q=PopShortPixel(MSBEndian,short_pixel,q);
2487               break;
2488             }
2489             case 8:
2490             {
2491               register unsigned char
2492                 char_pixel;
2493 
2494               char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2495                 image->colormap[i].red);
2496               q=PopCharPixel(char_pixel,q);
2497               char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2498                 image->colormap[i].green);
2499               q=PopCharPixel(char_pixel,q);
2500               char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2501                 image->colormap[i].blue);
2502               q=PopCharPixel(char_pixel,q);
2503               break;
2504             }
2505           }
2506         }
2507         (void) WriteBlob(image,colormap_size*image->colors,colormap);
2508         colormap=(unsigned char *) RelinquishMagickMemory(colormap);
2509       }
2510     /*
2511       Write image pixels to file.
2512     */
2513     status=MagickTrue;
2514     switch (compression)
2515     {
2516 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2517       case BZipCompression:
2518       {
2519         int
2520           code;
2521 
2522         (void) memset(&bzip_info,0,sizeof(bzip_info));
2523         bzip_info.bzalloc=AcquireBZIPMemory;
2524         bzip_info.bzfree=RelinquishBZIPMemory;
2525         bzip_info.opaque=(void *) NULL;
2526         code=BZ2_bzCompressInit(&bzip_info,(int) (image->quality ==
2527           UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)),
2528           (int) image_info->verbose,0);
2529         if (code != BZ_OK)
2530           status=MagickFalse;
2531         break;
2532       }
2533 #endif
2534 #if defined(MAGICKCORE_LZMA_DELEGATE)
2535       case LZMACompression:
2536       {
2537         int
2538           code;
2539 
2540         allocator.alloc=AcquireLZMAMemory;
2541         allocator.free=RelinquishLZMAMemory;
2542         allocator.opaque=(void *) NULL;
2543         lzma_info=initialize_lzma;
2544         lzma_info.allocator=&allocator;
2545         code=lzma_easy_encoder(&lzma_info,(uint32_t) (image->quality/10),
2546           LZMA_CHECK_SHA256);
2547         if (code != LZMA_OK)
2548           status=MagickTrue;
2549         break;
2550       }
2551 #endif
2552 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2553       case LZWCompression:
2554       case ZipCompression:
2555       {
2556         int
2557           code;
2558 
2559         zip_info.zalloc=AcquireZIPMemory;
2560         zip_info.zfree=RelinquishZIPMemory;
2561         zip_info.opaque=(void *) NULL;
2562         code=deflateInit(&zip_info,(int) (image->quality ==
2563           UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)));
2564         if (code != Z_OK)
2565           status=MagickFalse;
2566         break;
2567       }
2568 #endif
2569       default:
2570         break;
2571     }
2572     quantum_type=GetQuantumType(image,exception);
2573     pixels=(unsigned char *) GetQuantumPixels(quantum_info);
2574     for (y=0; y < (ssize_t) image->rows; y++)
2575     {
2576       register const Quantum
2577         *magick_restrict p;
2578 
2579       register ssize_t
2580         x;
2581 
2582       if (status == MagickFalse)
2583         break;
2584       p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2585       if (p == (const Quantum *) NULL)
2586         break;
2587       q=pixels;
2588       switch (compression)
2589       {
2590 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2591         case BZipCompression:
2592         {
2593           bzip_info.next_in=(char *) pixels;
2594           bzip_info.avail_in=(unsigned int) (packet_size*image->columns);
2595           (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2596             quantum_type,pixels,exception);
2597           do
2598           {
2599             int
2600               code;
2601 
2602             bzip_info.next_out=(char *) compress_pixels;
2603             bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size*
2604               image->columns);
2605             code=BZ2_bzCompress(&bzip_info,BZ_FLUSH);
2606             if (code < 0)
2607               status=MagickFalse;
2608             length=(size_t) (bzip_info.next_out-(char *) compress_pixels);
2609             if (length != 0)
2610               {
2611                 (void) WriteBlobMSBLong(image,(unsigned int) length);
2612                 (void) WriteBlob(image,length,compress_pixels);
2613               }
2614           } while (bzip_info.avail_in != 0);
2615           break;
2616         }
2617 #endif
2618 #if defined(MAGICKCORE_LZMA_DELEGATE)
2619         case LZMACompression:
2620         {
2621           lzma_info.next_in=pixels;
2622           lzma_info.avail_in=packet_size*image->columns;
2623           (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2624             quantum_type,pixels,exception);
2625           do
2626           {
2627             int
2628               code;
2629 
2630             lzma_info.next_out=compress_pixels;
2631             lzma_info.avail_out=LZMAMaxExtent(packet_size*image->columns);
2632             code=lzma_code(&lzma_info,LZMA_RUN);
2633             if (code != LZMA_OK)
2634               status=MagickFalse;
2635             length=(size_t) (lzma_info.next_out-compress_pixels);
2636             if (length != 0)
2637               {
2638                 (void) WriteBlobMSBLong(image,(unsigned int) length);
2639                 (void) WriteBlob(image,length,compress_pixels);
2640               }
2641           } while (lzma_info.avail_in != 0);
2642           break;
2643         }
2644 #endif
2645 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2646         case LZWCompression:
2647         case ZipCompression:
2648         {
2649           zip_info.next_in=pixels;
2650           zip_info.avail_in=(uInt) (packet_size*image->columns);
2651           (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2652             quantum_type,pixels,exception);
2653           do
2654           {
2655             int
2656               code;
2657 
2658             zip_info.next_out=compress_pixels;
2659             zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns);
2660             code=deflate(&zip_info,Z_SYNC_FLUSH);
2661             if (code != Z_OK)
2662               status=MagickFalse;
2663             length=(size_t) (zip_info.next_out-compress_pixels);
2664             if (length != 0)
2665               {
2666                 (void) WriteBlobMSBLong(image,(unsigned int) length);
2667                 (void) WriteBlob(image,length,compress_pixels);
2668               }
2669           } while (zip_info.avail_in != 0);
2670           break;
2671         }
2672 #endif
2673         case RLECompression:
2674         {
2675           length=0;
2676           GetPixelInfoPixel(image,p,&pixel);
2677           p+=GetPixelChannels(image);
2678           for (x=1; x < (ssize_t) image->columns; x++)
2679           {
2680             GetPixelInfoPixel(image,p,&target);
2681             if ((length < 255) &&
2682                 (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse))
2683               length++;
2684             else
2685               {
2686                 q=PopRunlengthPacket(image,q,length,&pixel,exception);
2687                 length=0;
2688               }
2689             GetPixelInfoPixel(image,p,&pixel);
2690             p+=GetPixelChannels(image);
2691           }
2692           q=PopRunlengthPacket(image,q,length,&pixel,exception);
2693           (void) WriteBlob(image,(size_t) (q-pixels),pixels);
2694           break;
2695         }
2696         default:
2697         {
2698           (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2699             quantum_type,pixels,exception);
2700           (void) WriteBlob(image,packet_size*image->columns,pixels);
2701           break;
2702         }
2703       }
2704       if (image->previous == (Image *) NULL)
2705         {
2706           status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2707             image->rows);
2708           if (status == MagickFalse)
2709             break;
2710         }
2711     }
2712     switch (compression)
2713     {
2714 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2715       case BZipCompression:
2716       {
2717         int
2718           code;
2719 
2720         for ( ; ; )
2721         {
2722           if (status == MagickFalse)
2723             break;
2724           bzip_info.next_out=(char *) compress_pixels;
2725           bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size*
2726             image->columns);
2727           code=BZ2_bzCompress(&bzip_info,BZ_FINISH);
2728           length=(size_t) (bzip_info.next_out-(char *) compress_pixels);
2729           if (length != 0)
2730             {
2731               (void) WriteBlobMSBLong(image,(unsigned int) length);
2732               (void) WriteBlob(image,length,compress_pixels);
2733             }
2734           if (code == BZ_STREAM_END)
2735             break;
2736         }
2737         code=BZ2_bzCompressEnd(&bzip_info);
2738         if (code != BZ_OK)
2739           status=MagickFalse;
2740         break;
2741       }
2742 #endif
2743 #if defined(MAGICKCORE_LZMA_DELEGATE)
2744       case LZMACompression:
2745       {
2746         int
2747           code;
2748 
2749         for ( ; ; )
2750         {
2751           if (status == MagickFalse)
2752             break;
2753           lzma_info.next_out=compress_pixels;
2754           lzma_info.avail_out=packet_size*image->columns;
2755           code=lzma_code(&lzma_info,LZMA_FINISH);
2756           length=(size_t) (lzma_info.next_out-compress_pixels);
2757           if (length > 6)
2758             {
2759               (void) WriteBlobMSBLong(image,(unsigned int) length);
2760               (void) WriteBlob(image,length,compress_pixels);
2761             }
2762           if (code == LZMA_STREAM_END)
2763             break;
2764         }
2765         lzma_end(&lzma_info);
2766         break;
2767       }
2768 #endif
2769 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2770       case LZWCompression:
2771       case ZipCompression:
2772       {
2773         int
2774           code;
2775 
2776         for ( ; ; )
2777         {
2778           if (status == MagickFalse)
2779             break;
2780           zip_info.next_out=compress_pixels;
2781           zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns);
2782           code=deflate(&zip_info,Z_FINISH);
2783           length=(size_t) (zip_info.next_out-compress_pixels);
2784           if (length > 6)
2785             {
2786               (void) WriteBlobMSBLong(image,(unsigned int) length);
2787               (void) WriteBlob(image,length,compress_pixels);
2788             }
2789           if (code == Z_STREAM_END)
2790             break;
2791         }
2792         code=deflateEnd(&zip_info);
2793         if (code != Z_OK)
2794           status=MagickFalse;
2795         break;
2796       }
2797 #endif
2798       default:
2799         break;
2800     }
2801     quantum_info=DestroyQuantumInfo(quantum_info);
2802     compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
2803     if (GetNextImageInList(image) == (Image *) NULL)
2804       break;
2805     image=SyncNextImageInList(image);
2806     status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
2807     if (status == MagickFalse)
2808       break;
2809   } while (image_info->adjoin != MagickFalse);
2810   (void) CloseBlob(image);
2811   return(status);
2812 }
2813