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