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