Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                         CCCC  M   M  Y   Y  K   K                           %
      7 %                        C      MM MM   Y Y   K  K                            %
      8 %                        C      M M M    Y    KKK                             %
      9 %                        C      M   M    Y    K  K                            %
     10 %                         CCCC  M   M    Y    K   K                           %
     11 %                                                                             %
     12 %                                                                             %
     13 %                     Read/Write RAW CMYK Image Format                        %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 July 1992                                   %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  dedicated to making software imaging solutions freely available.           %
     22 %                                                                             %
     23 %  You may not use this file except in compliance with the License.  You may  %
     24 %  obtain a copy of the License at                                            %
     25 %                                                                             %
     26 %    http://www.imagemagick.org/script/license.php                            %
     27 %                                                                             %
     28 %  Unless required by applicable law or agreed to in writing, software        %
     29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     31 %  See the License for the specific language governing permissions and        %
     32 %  limitations under the License.                                             %
     33 %                                                                             %
     34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     35 %
     36 %
     37 */
     38 
     39 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/blob.h"
     45 #include "MagickCore/blob-private.h"
     46 #include "MagickCore/cache.h"
     47 #include "MagickCore/channel.h"
     48 #include "MagickCore/colorspace.h"
     49 #include "MagickCore/constitute.h"
     50 #include "MagickCore/exception.h"
     51 #include "MagickCore/exception-private.h"
     52 #include "MagickCore/image.h"
     53 #include "MagickCore/image-private.h"
     54 #include "MagickCore/list.h"
     55 #include "MagickCore/magick.h"
     56 #include "MagickCore/memory_.h"
     57 #include "MagickCore/monitor.h"
     58 #include "MagickCore/monitor-private.h"
     59 #include "MagickCore/pixel-accessor.h"
     60 #include "MagickCore/quantum-private.h"
     61 #include "MagickCore/static.h"
     62 #include "MagickCore/statistic.h"
     63 #include "MagickCore/string_.h"
     64 #include "MagickCore/module.h"
     65 #include "MagickCore/utility.h"
     66 
     67 /*
     69   Forward declarations.
     70 */
     71 static MagickBooleanType
     72   WriteCMYKImage(const ImageInfo *,Image *,ExceptionInfo *);
     73 
     74 /*
     76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     77 %                                                                             %
     78 %                                                                             %
     79 %                                                                             %
     80 %   R e a d C M Y K I m a g e                                                 %
     81 %                                                                             %
     82 %                                                                             %
     83 %                                                                             %
     84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     85 %
     86 %  ReadCMYKImage() reads an image of raw CMYK or CMYKA samples and returns it.
     87 %  It allocates the memory necessary for the new Image structure and returns a
     88 %  pointer to the new image.
     89 %
     90 %  The format of the ReadCMYKImage method is:
     91 %
     92 %      Image *ReadCMYKImage(const ImageInfo *image_info,
     93 %        ExceptionInfo *exception)
     94 %
     95 %  A description of each parameter follows:
     96 %
     97 %    o image_info: the image info.
     98 %
     99 %    o exception: return any errors or warnings in this structure.
    100 %
    101 */
    102 static Image *ReadCMYKImage(const ImageInfo *image_info,
    103   ExceptionInfo *exception)
    104 {
    105   const unsigned char
    106     *pixels;
    107 
    108   Image
    109     *canvas_image,
    110     *image;
    111 
    112   MagickBooleanType
    113     status;
    114 
    115   MagickOffsetType
    116     scene;
    117 
    118   QuantumInfo
    119     *quantum_info;
    120 
    121   QuantumType
    122     quantum_type;
    123 
    124   register ssize_t
    125     i;
    126 
    127   size_t
    128     length;
    129 
    130   ssize_t
    131     count,
    132     y;
    133 
    134   /*
    135     Open image file.
    136   */
    137   assert(image_info != (const ImageInfo *) NULL);
    138   assert(image_info->signature == MagickCoreSignature);
    139   if (image_info->debug != MagickFalse)
    140     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    141       image_info->filename);
    142   assert(exception != (ExceptionInfo *) NULL);
    143   assert(exception->signature == MagickCoreSignature);
    144   image=AcquireImage(image_info,exception);
    145   if ((image->columns == 0) || (image->rows == 0))
    146     ThrowReaderException(OptionError,"MustSpecifyImageSize");
    147   SetImageColorspace(image,CMYKColorspace,exception);
    148   if (image_info->interlace != PartitionInterlace)
    149     {
    150       status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    151       if (status == MagickFalse)
    152         {
    153           image=DestroyImageList(image);
    154           return((Image *) NULL);
    155         }
    156       if (DiscardBlobBytes(image,image->offset) == MagickFalse)
    157         ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    158           image->filename);
    159     }
    160   /*
    161     Create virtual canvas to support cropping (i.e. image.cmyk[100x100+10+20]).
    162   */
    163   canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
    164     exception);
    165   (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
    166     exception);
    167   quantum_info=AcquireQuantumInfo(image_info,canvas_image);
    168   if (quantum_info == (QuantumInfo *) NULL)
    169     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    170   quantum_type=CMYKQuantum;
    171   if (LocaleCompare(image_info->magick,"CMYKA") == 0)
    172     {
    173       quantum_type=CMYKAQuantum;
    174       image->alpha_trait=BlendPixelTrait;
    175     }
    176   pixels=(const unsigned char *) NULL;
    177   if (image_info->number_scenes != 0)
    178     while (image->scene < image_info->scene)
    179     {
    180       /*
    181         Skip to next image.
    182       */
    183       image->scene++;
    184       length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
    185       for (y=0; y < (ssize_t) image->rows; y++)
    186       {
    187         pixels=(const unsigned char *) ReadBlobStream(image,length,
    188           GetQuantumPixels(quantum_info),&count);
    189         if (count != (ssize_t) length)
    190           break;
    191       }
    192     }
    193   count=0;
    194   length=0;
    195   scene=0;
    196   do
    197   {
    198     /*
    199       Read pixels to virtual canvas image then push to image.
    200     */
    201     if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
    202       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
    203         break;
    204     status=SetImageExtent(image,image->columns,image->rows,exception);
    205     if (status == MagickFalse)
    206       return(DestroyImageList(image));
    207     SetImageColorspace(image,CMYKColorspace,exception);
    208     switch (image_info->interlace)
    209     {
    210       case NoInterlace:
    211       default:
    212       {
    213         /*
    214           No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
    215         */
    216         if (scene == 0)
    217           {
    218             length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
    219             pixels=(const unsigned char *) ReadBlobStream(image,length,
    220               GetQuantumPixels(quantum_info),&count);
    221           }
    222         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    223         {
    224           register const Quantum
    225             *magick_restrict p;
    226 
    227           register Quantum
    228             *magick_restrict q;
    229 
    230           register ssize_t
    231             x;
    232 
    233           if (count != (ssize_t) length)
    234             {
    235               ThrowFileException(exception,CorruptImageError,
    236                 "UnexpectedEndOfFile",image->filename);
    237               break;
    238             }
    239           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    240             exception);
    241           if (q == (Quantum *) NULL)
    242             break;
    243           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    244             quantum_info,quantum_type,pixels,exception);
    245           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    246             break;
    247           if (((y-image->extract_info.y) >= 0) &&
    248               ((y-image->extract_info.y) < (ssize_t) image->rows))
    249             {
    250               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    251                 canvas_image->columns,1,exception);
    252               q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
    253                 image->columns,1,exception);
    254               if ((p == (const Quantum *) NULL) ||
    255                   (q == (Quantum *) NULL))
    256                 break;
    257               for (x=0; x < (ssize_t) image->columns; x++)
    258               {
    259                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
    260                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
    261                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
    262                 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
    263                 SetPixelAlpha(image,OpaqueAlpha,q);
    264                 if (image->alpha_trait != UndefinedPixelTrait)
    265                   SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
    266                 p+=GetPixelChannels(canvas_image);
    267                 q+=GetPixelChannels(image);
    268               }
    269               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    270                 break;
    271             }
    272           if (image->previous == (Image *) NULL)
    273             {
    274               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    275                 image->rows);
    276               if (status == MagickFalse)
    277                 break;
    278             }
    279           pixels=(const unsigned char *) ReadBlobStream(image,length,
    280             GetQuantumPixels(quantum_info),&count);
    281         }
    282         break;
    283       }
    284       case LineInterlace:
    285       {
    286         static QuantumType
    287           quantum_types[5] =
    288           {
    289             CyanQuantum,
    290             MagentaQuantum,
    291             YellowQuantum,
    292             BlackQuantum,
    293             OpacityQuantum
    294           };
    295 
    296         /*
    297           Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
    298         */
    299         if (scene == 0)
    300           {
    301             length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
    302             pixels=(const unsigned char *) ReadBlobStream(image,length,
    303               GetQuantumPixels(quantum_info),&count);
    304           }
    305         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    306         {
    307           register const Quantum
    308             *magick_restrict p;
    309 
    310           register Quantum
    311             *magick_restrict q;
    312 
    313           register ssize_t
    314             x;
    315 
    316           if (count != (ssize_t) length)
    317             {
    318               ThrowFileException(exception,CorruptImageError,
    319                 "UnexpectedEndOfFile",image->filename);
    320               break;
    321             }
    322           for (i=0; i < (image->alpha_trait != UndefinedPixelTrait ? 5 : 4); i++)
    323           {
    324             quantum_type=quantum_types[i];
    325             q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    326               exception);
    327             if (q == (Quantum *) NULL)
    328               break;
    329             length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    330               quantum_info,quantum_type,pixels,exception);
    331             if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    332               break;
    333             if (((y-image->extract_info.y) >= 0) &&
    334                 ((y-image->extract_info.y) < (ssize_t) image->rows))
    335               {
    336                 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
    337                   0,canvas_image->columns,1,exception);
    338                 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    339                   image->columns,1,exception);
    340                 if ((p == (const Quantum *) NULL) ||
    341                     (q == (Quantum *) NULL))
    342                   break;
    343                 for (x=0; x < (ssize_t) image->columns; x++)
    344                 {
    345                   switch (quantum_type)
    346                   {
    347                     case CyanQuantum:
    348                     {
    349                       SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
    350                       break;
    351                     }
    352                     case MagentaQuantum:
    353                     {
    354                       SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
    355                       break;
    356                     }
    357                     case YellowQuantum:
    358                     {
    359                       SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
    360                       break;
    361                     }
    362                     case BlackQuantum:
    363                     {
    364                       SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
    365                       break;
    366                     }
    367                     case OpacityQuantum:
    368                     {
    369                       SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
    370                       break;
    371                     }
    372                     default:
    373                       break;
    374                   }
    375                   p+=GetPixelChannels(canvas_image);
    376                   q+=GetPixelChannels(image);
    377                 }
    378                 if (SyncAuthenticPixels(image,exception) == MagickFalse)
    379                   break;
    380               }
    381             pixels=(const unsigned char *) ReadBlobStream(image,length,
    382               GetQuantumPixels(quantum_info),&count);
    383           }
    384           if (image->previous == (Image *) NULL)
    385             {
    386               status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
    387                 image->rows);
    388               if (status == MagickFalse)
    389                 break;
    390             }
    391         }
    392         break;
    393       }
    394       case PlaneInterlace:
    395       {
    396         /*
    397           Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
    398         */
    399         if (scene == 0)
    400           {
    401             length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
    402             pixels=(const unsigned char *) ReadBlobStream(image,length,
    403               GetQuantumPixels(quantum_info),&count);
    404           }
    405         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    406         {
    407           register const Quantum
    408             *magick_restrict p;
    409 
    410           register Quantum
    411             *magick_restrict q;
    412 
    413           register ssize_t
    414             x;
    415 
    416           if (count != (ssize_t) length)
    417             {
    418               ThrowFileException(exception,CorruptImageError,
    419                 "UnexpectedEndOfFile",image->filename);
    420               break;
    421             }
    422           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    423             exception);
    424           if (q == (Quantum *) NULL)
    425             break;
    426           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    427             quantum_info,CyanQuantum,pixels,exception);
    428           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    429             break;
    430           if (((y-image->extract_info.y) >= 0) &&
    431               ((y-image->extract_info.y) < (ssize_t) image->rows))
    432             {
    433               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    434                 canvas_image->columns,1,exception);
    435               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    436                 image->columns,1,exception);
    437               if ((p == (const Quantum *) NULL) ||
    438                   (q == (Quantum *) NULL))
    439                 break;
    440               for (x=0; x < (ssize_t) image->columns; x++)
    441               {
    442                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
    443                 p+=GetPixelChannels(canvas_image);
    444                 q+=GetPixelChannels(image);
    445               }
    446               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    447                 break;
    448             }
    449           pixels=(const unsigned char *) ReadBlobStream(image,length,
    450             GetQuantumPixels(quantum_info),&count);
    451         }
    452         if (image->previous == (Image *) NULL)
    453           {
    454             status=SetImageProgress(image,LoadImageTag,1,6);
    455             if (status == MagickFalse)
    456               break;
    457           }
    458         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    459         {
    460           register const Quantum
    461             *magick_restrict p;
    462 
    463           register Quantum
    464             *magick_restrict q;
    465 
    466           register ssize_t
    467             x;
    468 
    469           if (count != (ssize_t) length)
    470             {
    471               ThrowFileException(exception,CorruptImageError,
    472                 "UnexpectedEndOfFile",image->filename);
    473               break;
    474             }
    475           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    476             exception);
    477           if (q == (Quantum *) NULL)
    478             break;
    479           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    480             quantum_info,MagentaQuantum,pixels,exception);
    481           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    482             break;
    483           if (((y-image->extract_info.y) >= 0) &&
    484               ((y-image->extract_info.y) < (ssize_t) image->rows))
    485             {
    486               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    487                 canvas_image->columns,1,exception);
    488               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    489                 image->columns,1,exception);
    490               if ((p == (const Quantum *) NULL) ||
    491                   (q == (Quantum *) NULL))
    492                 break;
    493               for (x=0; x < (ssize_t) image->columns; x++)
    494               {
    495                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
    496                 p+=GetPixelChannels(canvas_image);
    497                 q+=GetPixelChannels(image);
    498               }
    499               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    500                 break;
    501            }
    502           pixels=(const unsigned char *) ReadBlobStream(image,length,
    503             GetQuantumPixels(quantum_info),&count);
    504         }
    505         if (image->previous == (Image *) NULL)
    506           {
    507             status=SetImageProgress(image,LoadImageTag,2,6);
    508             if (status == MagickFalse)
    509               break;
    510           }
    511         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    512         {
    513           register const Quantum
    514             *magick_restrict p;
    515 
    516           register Quantum
    517             *magick_restrict q;
    518 
    519           register ssize_t
    520             x;
    521 
    522           if (count != (ssize_t) length)
    523             {
    524               ThrowFileException(exception,CorruptImageError,
    525                 "UnexpectedEndOfFile",image->filename);
    526               break;
    527             }
    528           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    529             exception);
    530           if (q == (Quantum *) NULL)
    531             break;
    532           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    533             quantum_info,YellowQuantum,pixels,exception);
    534           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    535             break;
    536           if (((y-image->extract_info.y) >= 0) &&
    537               ((y-image->extract_info.y) < (ssize_t) image->rows))
    538             {
    539               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    540                 canvas_image->columns,1,exception);
    541               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    542                 image->columns,1,exception);
    543               if ((p == (const Quantum *) NULL) ||
    544                   (q == (Quantum *) NULL))
    545                 break;
    546               for (x=0; x < (ssize_t) image->columns; x++)
    547               {
    548                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
    549                 p+=GetPixelChannels(canvas_image);
    550                 q+=GetPixelChannels(image);
    551               }
    552               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    553                 break;
    554             }
    555           pixels=(const unsigned char *) ReadBlobStream(image,length,
    556             GetQuantumPixels(quantum_info),&count);
    557         }
    558         if (image->previous == (Image *) NULL)
    559           {
    560             status=SetImageProgress(image,LoadImageTag,3,6);
    561             if (status == MagickFalse)
    562               break;
    563           }
    564         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    565         {
    566           register const Quantum
    567             *magick_restrict p;
    568 
    569           register Quantum
    570             *magick_restrict q;
    571 
    572           register ssize_t
    573             x;
    574 
    575           if (count != (ssize_t) length)
    576             {
    577               ThrowFileException(exception,CorruptImageError,
    578                 "UnexpectedEndOfFile",image->filename);
    579               break;
    580             }
    581           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    582             exception);
    583           if (q == (Quantum *) NULL)
    584             break;
    585           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    586             quantum_info,BlackQuantum,pixels,exception);
    587           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    588             break;
    589           if (((y-image->extract_info.y) >= 0) &&
    590               ((y-image->extract_info.y) < (ssize_t) image->rows))
    591             {
    592               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    593                 canvas_image->columns,1,exception);
    594               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    595                 image->columns,1,exception);
    596               if ((p == (const Quantum *) NULL) ||
    597                   (q == (Quantum *) NULL))
    598                 break;
    599               for (x=0; x < (ssize_t) image->columns; x++)
    600               {
    601                 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
    602                 p+=GetPixelChannels(canvas_image);
    603                 q+=GetPixelChannels(image);
    604               }
    605               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    606                 break;
    607             }
    608           pixels=(const unsigned char *) ReadBlobStream(image,length,
    609             GetQuantumPixels(quantum_info),&count);
    610         }
    611         if (image->previous == (Image *) NULL)
    612           {
    613             status=SetImageProgress(image,LoadImageTag,4,6);
    614             if (status == MagickFalse)
    615               break;
    616           }
    617         if (image->alpha_trait != UndefinedPixelTrait)
    618           {
    619             for (y=0; y < (ssize_t) image->extract_info.height; y++)
    620             {
    621               register const Quantum
    622                 *magick_restrict p;
    623 
    624               register Quantum
    625                 *magick_restrict q;
    626 
    627               register ssize_t
    628                 x;
    629 
    630               if (count != (ssize_t) length)
    631                 {
    632                   ThrowFileException(exception,CorruptImageError,
    633                     "UnexpectedEndOfFile",image->filename);
    634                   break;
    635                 }
    636               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    637                 exception);
    638               if (q == (Quantum *) NULL)
    639                 break;
    640               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    641                 quantum_info,AlphaQuantum,pixels,exception);
    642               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    643                 break;
    644               if (((y-image->extract_info.y) >= 0) &&
    645                   ((y-image->extract_info.y) < (ssize_t) image->rows))
    646                 {
    647                   p=GetVirtualPixels(canvas_image,
    648                     canvas_image->extract_info.x,0,canvas_image->columns,1,
    649                     exception);
    650                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    651                     image->columns,1,exception);
    652                   if ((p == (const Quantum *) NULL) ||
    653                       (q == (Quantum *) NULL))
    654                     break;
    655                   for (x=0; x < (ssize_t) image->columns; x++)
    656                   {
    657                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
    658                     p+=GetPixelChannels(canvas_image);
    659                     q+=GetPixelChannels(image);
    660                   }
    661                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
    662                     break;
    663                 }
    664               pixels=(const unsigned char *) ReadBlobStream(image,length,
    665                 GetQuantumPixels(quantum_info),&count);
    666             }
    667             if (image->previous == (Image *) NULL)
    668               {
    669                 status=SetImageProgress(image,LoadImageTag,5,6);
    670                 if (status == MagickFalse)
    671                   break;
    672               }
    673           }
    674         if (image->previous == (Image *) NULL)
    675           {
    676             status=SetImageProgress(image,LoadImageTag,6,6);
    677             if (status == MagickFalse)
    678               break;
    679           }
    680         break;
    681       }
    682       case PartitionInterlace:
    683       {
    684         /*
    685           Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
    686         */
    687         AppendImageFormat("C",image->filename);
    688         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    689         if (status == MagickFalse)
    690           {
    691             canvas_image=DestroyImageList(canvas_image);
    692             image=DestroyImageList(image);
    693             return((Image *) NULL);
    694           }
    695         if (DiscardBlobBytes(image,image->offset) == MagickFalse)
    696           ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    697             image->filename);
    698         length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
    699         for (i=0; i < (ssize_t) scene; i++)
    700           for (y=0; y < (ssize_t) image->extract_info.height; y++)
    701           {
    702             pixels=(const unsigned char *) ReadBlobStream(image,length,
    703               GetQuantumPixels(quantum_info),&count);
    704             if (count != (ssize_t) length)
    705               {
    706                 ThrowFileException(exception,CorruptImageError,
    707                   "UnexpectedEndOfFile",image->filename);
    708                 break;
    709               }
    710           }
    711         pixels=(const unsigned char *) ReadBlobStream(image,length,
    712           GetQuantumPixels(quantum_info),&count);
    713         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    714         {
    715           register const Quantum
    716             *magick_restrict p;
    717 
    718           register Quantum
    719             *magick_restrict q;
    720 
    721           register ssize_t
    722             x;
    723 
    724           if (count != (ssize_t) length)
    725             {
    726               ThrowFileException(exception,CorruptImageError,
    727                 "UnexpectedEndOfFile",image->filename);
    728               break;
    729             }
    730           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    731             exception);
    732           if (q == (Quantum *) NULL)
    733             break;
    734           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    735             quantum_info,CyanQuantum,pixels,exception);
    736           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    737             break;
    738           if (((y-image->extract_info.y) >= 0) &&
    739               ((y-image->extract_info.y) < (ssize_t) image->rows))
    740             {
    741               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    742                 canvas_image->columns,1,exception);
    743               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    744                 image->columns,1,exception);
    745               if ((p == (const Quantum *) NULL) ||
    746                   (q == (Quantum *) NULL))
    747                 break;
    748               for (x=0; x < (ssize_t) image->columns; x++)
    749               {
    750                 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
    751                 p+=GetPixelChannels(canvas_image);
    752                 q+=GetPixelChannels(image);
    753               }
    754               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    755                 break;
    756             }
    757           pixels=(const unsigned char *) ReadBlobStream(image,length,
    758             GetQuantumPixels(quantum_info),&count);
    759         }
    760         if (image->previous == (Image *) NULL)
    761           {
    762             status=SetImageProgress(image,LoadImageTag,1,5);
    763             if (status == MagickFalse)
    764               break;
    765           }
    766         (void) CloseBlob(image);
    767         AppendImageFormat("M",image->filename);
    768         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    769         if (status == MagickFalse)
    770           {
    771             canvas_image=DestroyImageList(canvas_image);
    772             image=DestroyImageList(image);
    773             return((Image *) NULL);
    774           }
    775         length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
    776         for (i=0; i < (ssize_t) scene; i++)
    777           for (y=0; y < (ssize_t) image->extract_info.height; y++)
    778           {
    779             pixels=(const unsigned char *) ReadBlobStream(image,length,
    780               GetQuantumPixels(quantum_info),&count);
    781             if (count != (ssize_t) length)
    782               {
    783                 ThrowFileException(exception,CorruptImageError,
    784                   "UnexpectedEndOfFile",image->filename);
    785                 break;
    786               }
    787           }
    788         pixels=(const unsigned char *) ReadBlobStream(image,length,
    789           GetQuantumPixels(quantum_info),&count);
    790         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    791         {
    792           register const Quantum
    793             *magick_restrict p;
    794 
    795           register Quantum
    796             *magick_restrict q;
    797 
    798           register ssize_t
    799             x;
    800 
    801           if (count != (ssize_t) length)
    802             {
    803               ThrowFileException(exception,CorruptImageError,
    804                 "UnexpectedEndOfFile",image->filename);
    805               break;
    806             }
    807           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    808             exception);
    809           if (q == (Quantum *) NULL)
    810             break;
    811           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    812             quantum_info,MagentaQuantum,pixels,exception);
    813           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    814             break;
    815           if (((y-image->extract_info.y) >= 0) &&
    816               ((y-image->extract_info.y) < (ssize_t) image->rows))
    817             {
    818               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    819                 canvas_image->columns,1,exception);
    820               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    821                 image->columns,1,exception);
    822               if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
    823                 break;
    824               for (x=0; x < (ssize_t) image->columns; x++)
    825               {
    826                 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
    827                 p+=GetPixelChannels(canvas_image);
    828                 q+=GetPixelChannels(image);
    829               }
    830               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    831                 break;
    832            }
    833           pixels=(const unsigned char *) ReadBlobStream(image,length,
    834             GetQuantumPixels(quantum_info),&count);
    835         }
    836         if (image->previous == (Image *) NULL)
    837           {
    838             status=SetImageProgress(image,LoadImageTag,2,5);
    839             if (status == MagickFalse)
    840               break;
    841           }
    842         (void) CloseBlob(image);
    843         AppendImageFormat("Y",image->filename);
    844         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    845         if (status == MagickFalse)
    846           {
    847             canvas_image=DestroyImageList(canvas_image);
    848             image=DestroyImageList(image);
    849             return((Image *) NULL);
    850           }
    851         length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
    852         for (i=0; i < (ssize_t) scene; i++)
    853           for (y=0; y < (ssize_t) image->extract_info.height; y++)
    854           {
    855             pixels=(const unsigned char *) ReadBlobStream(image,length,
    856               GetQuantumPixels(quantum_info),&count);
    857             if (count != (ssize_t) length)
    858               {
    859                 ThrowFileException(exception,CorruptImageError,
    860                   "UnexpectedEndOfFile",image->filename);
    861                 break;
    862               }
    863           }
    864         pixels=(const unsigned char *) ReadBlobStream(image,length,
    865           GetQuantumPixels(quantum_info),&count);
    866         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    867         {
    868           register const Quantum
    869             *magick_restrict p;
    870 
    871           register Quantum
    872             *magick_restrict q;
    873 
    874           register ssize_t
    875             x;
    876 
    877           if (count != (ssize_t) length)
    878             {
    879               ThrowFileException(exception,CorruptImageError,
    880                 "UnexpectedEndOfFile",image->filename);
    881               break;
    882             }
    883           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    884             exception);
    885           if (q == (Quantum *) NULL)
    886             break;
    887           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    888             quantum_info,YellowQuantum,pixels,exception);
    889           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    890             break;
    891           if (((y-image->extract_info.y) >= 0) &&
    892               ((y-image->extract_info.y) < (ssize_t) image->rows))
    893             {
    894               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    895                 canvas_image->columns,1,exception);
    896               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    897                 image->columns,1,exception);
    898               if ((p == (const Quantum *) NULL) ||
    899                   (q == (Quantum *) NULL))
    900                 break;
    901               for (x=0; x < (ssize_t) image->columns; x++)
    902               {
    903                 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
    904                 p+=GetPixelChannels(canvas_image);
    905                 q+=GetPixelChannels(image);
    906               }
    907               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    908                 break;
    909            }
    910           pixels=(const unsigned char *) ReadBlobStream(image,length,
    911             GetQuantumPixels(quantum_info),&count);
    912         }
    913         if (image->previous == (Image *) NULL)
    914           {
    915             status=SetImageProgress(image,LoadImageTag,3,5);
    916             if (status == MagickFalse)
    917               break;
    918           }
    919         (void) CloseBlob(image);
    920         AppendImageFormat("K",image->filename);
    921         status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    922         if (status == MagickFalse)
    923           {
    924             canvas_image=DestroyImageList(canvas_image);
    925             image=DestroyImageList(image);
    926             return((Image *) NULL);
    927           }
    928         length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
    929         for (i=0; i < (ssize_t) scene; i++)
    930           for (y=0; y < (ssize_t) image->extract_info.height; y++)
    931           {
    932             pixels=(const unsigned char *) ReadBlobStream(image,length,
    933               GetQuantumPixels(quantum_info),&count);
    934             if (count != (ssize_t) length)
    935               {
    936                 ThrowFileException(exception,CorruptImageError,
    937                   "UnexpectedEndOfFile",image->filename);
    938                 break;
    939               }
    940           }
    941         pixels=(const unsigned char *) ReadBlobStream(image,length,
    942           GetQuantumPixels(quantum_info),&count);
    943         for (y=0; y < (ssize_t) image->extract_info.height; y++)
    944         {
    945           register const Quantum
    946             *magick_restrict p;
    947 
    948           register Quantum
    949             *magick_restrict q;
    950 
    951           register ssize_t
    952             x;
    953 
    954           if (count != (ssize_t) length)
    955             {
    956               ThrowFileException(exception,CorruptImageError,
    957                 "UnexpectedEndOfFile",image->filename);
    958               break;
    959             }
    960           q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
    961             exception);
    962           if (q == (Quantum *) NULL)
    963             break;
    964           length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
    965             quantum_info,BlackQuantum,pixels,exception);
    966           if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
    967             break;
    968           if (((y-image->extract_info.y) >= 0) &&
    969               ((y-image->extract_info.y) < (ssize_t) image->rows))
    970             {
    971               p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
    972                 canvas_image->columns,1,exception);
    973               q=GetAuthenticPixels(image,0,y-image->extract_info.y,
    974                 image->columns,1,exception);
    975               if ((p == (const Quantum *) NULL) ||
    976                   (q == (Quantum *) NULL))
    977                 break;
    978               for (x=0; x < (ssize_t) image->columns; x++)
    979               {
    980                 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
    981                 p+=GetPixelChannels(canvas_image);
    982                 q+=GetPixelChannels(image);
    983               }
    984               if (SyncAuthenticPixels(image,exception) == MagickFalse)
    985                 break;
    986            }
    987           pixels=(const unsigned char *) ReadBlobStream(image,length,
    988             GetQuantumPixels(quantum_info),&count);
    989         }
    990         if (image->previous == (Image *) NULL)
    991           {
    992             status=SetImageProgress(image,LoadImageTag,3,5);
    993             if (status == MagickFalse)
    994               break;
    995           }
    996         if (image->alpha_trait != UndefinedPixelTrait)
    997           {
    998             (void) CloseBlob(image);
    999             AppendImageFormat("A",image->filename);
   1000             status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   1001             if (status == MagickFalse)
   1002               {
   1003                 canvas_image=DestroyImageList(canvas_image);
   1004                 image=DestroyImageList(image);
   1005                 return((Image *) NULL);
   1006               }
   1007             length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
   1008             for (i=0; i < (ssize_t) scene; i++)
   1009               for (y=0; y < (ssize_t) image->extract_info.height; y++)
   1010               {
   1011                 pixels=(const unsigned char *) ReadBlobStream(image,length,
   1012                   GetQuantumPixels(quantum_info),&count);
   1013                 if (count != (ssize_t) length)
   1014                   {
   1015                     ThrowFileException(exception,CorruptImageError,
   1016                       "UnexpectedEndOfFile",image->filename);
   1017                     break;
   1018                   }
   1019               }
   1020             pixels=(const unsigned char *) ReadBlobStream(image,length,
   1021               GetQuantumPixels(quantum_info),
   1022               &count);
   1023             for (y=0; y < (ssize_t) image->extract_info.height; y++)
   1024             {
   1025               register const Quantum
   1026                 *magick_restrict p;
   1027 
   1028               register Quantum
   1029                 *magick_restrict q;
   1030 
   1031               register ssize_t
   1032                 x;
   1033 
   1034               if (count != (ssize_t) length)
   1035                 {
   1036                   ThrowFileException(exception,CorruptImageError,
   1037                     "UnexpectedEndOfFile",image->filename);
   1038                   break;
   1039                 }
   1040               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
   1041                 exception);
   1042               if (q == (Quantum *) NULL)
   1043                 break;
   1044               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
   1045                 quantum_info,YellowQuantum,pixels,exception);
   1046               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
   1047                 break;
   1048               if (((y-image->extract_info.y) >= 0) &&
   1049                   ((y-image->extract_info.y) < (ssize_t) image->rows))
   1050                 {
   1051                   p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
   1052                     0,canvas_image->columns,1,exception);
   1053                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
   1054                     image->columns,1,exception);
   1055                   if ((p == (const Quantum *) NULL) ||
   1056                       (q == (Quantum *) NULL))
   1057                     break;
   1058                   for (x=0; x < (ssize_t) image->columns; x++)
   1059                   {
   1060                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
   1061                     p+=GetPixelChannels(canvas_image);
   1062                     q+=GetPixelChannels(image);
   1063                   }
   1064                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
   1065                     break;
   1066                }
   1067               pixels=(const unsigned char *) ReadBlobStream(image,length,
   1068                 GetQuantumPixels(quantum_info),&count);
   1069             }
   1070             if (image->previous == (Image *) NULL)
   1071               {
   1072                 status=SetImageProgress(image,LoadImageTag,4,5);
   1073                 if (status == MagickFalse)
   1074                   break;
   1075               }
   1076           }
   1077         if (image->previous == (Image *) NULL)
   1078           {
   1079             status=SetImageProgress(image,LoadImageTag,5,5);
   1080             if (status == MagickFalse)
   1081               break;
   1082           }
   1083         break;
   1084       }
   1085     }
   1086     SetQuantumImageType(image,quantum_type);
   1087     /*
   1088       Proceed to next image.
   1089     */
   1090     if (image_info->number_scenes != 0)
   1091       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
   1092         break;
   1093     if (count == (ssize_t) length)
   1094       {
   1095         /*
   1096           Allocate next image structure.
   1097         */
   1098         AcquireNextImage(image_info,image,exception);
   1099         if (GetNextImageInList(image) == (Image *) NULL)
   1100           {
   1101             image=DestroyImageList(image);
   1102             return((Image *) NULL);
   1103           }
   1104         image=SyncNextImageInList(image);
   1105         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
   1106           GetBlobSize(image));
   1107         if (status == MagickFalse)
   1108           break;
   1109       }
   1110     scene++;
   1111   } while (count == (ssize_t) length);
   1112   quantum_info=DestroyQuantumInfo(quantum_info);
   1113   canvas_image=DestroyImage(canvas_image);
   1114   (void) CloseBlob(image);
   1115   return(GetFirstImageInList(image));
   1116 }
   1117 
   1118 /*
   1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1121 %                                                                             %
   1122 %                                                                             %
   1123 %                                                                             %
   1124 %   R e g i s t e r C M Y K I m a g e                                         %
   1125 %                                                                             %
   1126 %                                                                             %
   1127 %                                                                             %
   1128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1129 %
   1130 %  RegisterCMYKImage() adds attributes for the CMYK image format to
   1131 %  the list of supported formats.  The attributes include the image format
   1132 %  tag, a method to read and/or write the format, whether the format
   1133 %  supports the saving of more than one frame to the same file or blob,
   1134 %  whether the format supports native in-memory I/O, and a brief
   1135 %  description of the format.
   1136 %
   1137 %  The format of the RegisterCMYKImage method is:
   1138 %
   1139 %      size_t RegisterCMYKImage(void)
   1140 %
   1141 */
   1142 ModuleExport size_t RegisterCMYKImage(void)
   1143 {
   1144   MagickInfo
   1145     *entry;
   1146 
   1147   entry=AcquireMagickInfo("CMYK","CMYK",
   1148     "Raw cyan, magenta, yellow, and black samples");
   1149   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
   1150   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
   1151   entry->flags|=CoderRawSupportFlag;
   1152   entry->flags|=CoderEndianSupportFlag;
   1153   (void) RegisterMagickInfo(entry);
   1154   entry=AcquireMagickInfo("CMYK","CMYKA",
   1155     "Raw cyan, magenta, yellow, black, and alpha samples");
   1156   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
   1157   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
   1158   entry->flags|=CoderRawSupportFlag;
   1159   entry->flags|=CoderEndianSupportFlag;
   1160   (void) RegisterMagickInfo(entry);
   1161   return(MagickImageCoderSignature);
   1162 }
   1163 
   1164 /*
   1166 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1167 %                                                                             %
   1168 %                                                                             %
   1169 %                                                                             %
   1170 %   U n r e g i s t e r C M Y K I m a g e                                     %
   1171 %                                                                             %
   1172 %                                                                             %
   1173 %                                                                             %
   1174 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1175 %
   1176 %  UnregisterCMYKImage() removes format registrations made by the
   1177 %  CMYK module from the list of supported formats.
   1178 %
   1179 %  The format of the UnregisterCMYKImage method is:
   1180 %
   1181 %      UnregisterCMYKImage(void)
   1182 %
   1183 */
   1184 ModuleExport void UnregisterCMYKImage(void)
   1185 {
   1186   (void) UnregisterMagickInfo("CMYK");
   1187   (void) UnregisterMagickInfo("CMYKA");
   1188 }
   1189 
   1190 /*
   1192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1193 %                                                                             %
   1194 %                                                                             %
   1195 %                                                                             %
   1196 %   W r i t e C M Y K I m a g e                                               %
   1197 %                                                                             %
   1198 %                                                                             %
   1199 %                                                                             %
   1200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1201 %
   1202 %  WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
   1203 %  black,rasterfile format.
   1204 %
   1205 %  The format of the WriteCMYKImage method is:
   1206 %
   1207 %      MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
   1208 %        Image *image,ExceptionInfo *exception)
   1209 %
   1210 %  A description of each parameter follows.
   1211 %
   1212 %    o image_info: the image info.
   1213 %
   1214 %    o image:  The image.
   1215 %
   1216 %    o exception: return any errors or warnings in this structure.
   1217 %
   1218 */
   1219 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
   1220   Image *image,ExceptionInfo *exception)
   1221 {
   1222   MagickBooleanType
   1223     status;
   1224 
   1225   MagickOffsetType
   1226     scene;
   1227 
   1228   QuantumInfo
   1229     *quantum_info;
   1230 
   1231   QuantumType
   1232     quantum_type;
   1233 
   1234   size_t
   1235     length;
   1236 
   1237   ssize_t
   1238     count,
   1239     y;
   1240 
   1241   unsigned char
   1242     *pixels;
   1243 
   1244   /*
   1245     Allocate memory for pixels.
   1246   */
   1247   assert(image_info != (const ImageInfo *) NULL);
   1248   assert(image_info->signature == MagickCoreSignature);
   1249   assert(image != (Image *) NULL);
   1250   assert(image->signature == MagickCoreSignature);
   1251   if (image->debug != MagickFalse)
   1252     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1253   if (image_info->interlace != PartitionInterlace)
   1254     {
   1255       /*
   1256         Open output image file.
   1257       */
   1258       status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   1259       if (status == MagickFalse)
   1260         return(status);
   1261     }
   1262   scene=0;
   1263   do
   1264   {
   1265     /*
   1266       Convert MIFF to CMYK raster pixels.
   1267     */
   1268     if (image->colorspace != CMYKColorspace)
   1269       (void) TransformImageColorspace(image,CMYKColorspace,exception);
   1270     quantum_type=CMYKQuantum;
   1271     if (LocaleCompare(image_info->magick,"CMYKA") == 0)
   1272       {
   1273         quantum_type=CMYKAQuantum;
   1274         if (image->alpha_trait == UndefinedPixelTrait)
   1275           (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
   1276       }
   1277     quantum_info=AcquireQuantumInfo(image_info,image);
   1278     if (quantum_info == (QuantumInfo *) NULL)
   1279       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   1280     pixels=(unsigned char *) GetQuantumPixels(quantum_info);
   1281     switch (image_info->interlace)
   1282     {
   1283       case NoInterlace:
   1284       default:
   1285       {
   1286         /*
   1287           No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
   1288         */
   1289         for (y=0; y < (ssize_t) image->rows; y++)
   1290         {
   1291           register const Quantum
   1292             *magick_restrict p;
   1293 
   1294           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1295           if (p == (const Quantum *) NULL)
   1296             break;
   1297           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1298             quantum_type,pixels,exception);
   1299           count=WriteBlob(image,length,pixels);
   1300           if (count != (ssize_t) length)
   1301             break;
   1302           if (image->previous == (Image *) NULL)
   1303             {
   1304               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1305                 image->rows);
   1306               if (status == MagickFalse)
   1307                 break;
   1308             }
   1309         }
   1310         break;
   1311       }
   1312       case LineInterlace:
   1313       {
   1314         /*
   1315           Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
   1316         */
   1317         for (y=0; y < (ssize_t) image->rows; y++)
   1318         {
   1319           register const Quantum
   1320             *magick_restrict p;
   1321 
   1322           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1323           if (p == (const Quantum *) NULL)
   1324             break;
   1325           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1326             CyanQuantum,pixels,exception);
   1327           count=WriteBlob(image,length,pixels);
   1328           if (count != (ssize_t) length)
   1329             break;
   1330           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1331             MagentaQuantum,pixels,exception);
   1332           count=WriteBlob(image,length,pixels);
   1333           if (count != (ssize_t) length)
   1334             break;
   1335           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1336             YellowQuantum,pixels,exception);
   1337           count=WriteBlob(image,length,pixels);
   1338           if (count != (ssize_t) length)
   1339             break;
   1340           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1341             BlackQuantum,pixels,exception);
   1342           count=WriteBlob(image,length,pixels);
   1343           if (count != (ssize_t) length)
   1344             break;
   1345           if (quantum_type == CMYKAQuantum)
   1346             {
   1347               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1348                 AlphaQuantum,pixels,exception);
   1349               count=WriteBlob(image,length,pixels);
   1350               if (count != (ssize_t) length)
   1351                 break;
   1352             }
   1353           if (image->previous == (Image *) NULL)
   1354             {
   1355               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   1356                 image->rows);
   1357               if (status == MagickFalse)
   1358                 break;
   1359             }
   1360         }
   1361         break;
   1362       }
   1363       case PlaneInterlace:
   1364       {
   1365         /*
   1366           Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
   1367         */
   1368         for (y=0; y < (ssize_t) image->rows; y++)
   1369         {
   1370           register const Quantum
   1371             *magick_restrict p;
   1372 
   1373           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1374           if (p == (const Quantum *) NULL)
   1375             break;
   1376           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1377             CyanQuantum,pixels,exception);
   1378           count=WriteBlob(image,length,pixels);
   1379           if (count != (ssize_t) length)
   1380             break;
   1381         }
   1382         if (image->previous == (Image *) NULL)
   1383           {
   1384             status=SetImageProgress(image,SaveImageTag,1,6);
   1385             if (status == MagickFalse)
   1386               break;
   1387           }
   1388         for (y=0; y < (ssize_t) image->rows; y++)
   1389         {
   1390           register const Quantum
   1391             *magick_restrict p;
   1392 
   1393           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1394           if (p == (const Quantum *) NULL)
   1395             break;
   1396           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1397             MagentaQuantum,pixels,exception);
   1398           count=WriteBlob(image,length,pixels);
   1399           if (count != (ssize_t) length)
   1400             break;
   1401         }
   1402         if (image->previous == (Image *) NULL)
   1403           {
   1404             status=SetImageProgress(image,SaveImageTag,2,6);
   1405             if (status == MagickFalse)
   1406               break;
   1407           }
   1408         for (y=0; y < (ssize_t) image->rows; y++)
   1409         {
   1410           register const Quantum
   1411             *magick_restrict p;
   1412 
   1413           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1414           if (p == (const Quantum *) NULL)
   1415             break;
   1416           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1417             YellowQuantum,pixels,exception);
   1418           count=WriteBlob(image,length,pixels);
   1419           if (count != (ssize_t) length)
   1420             break;
   1421         }
   1422         if (image->previous == (Image *) NULL)
   1423           {
   1424             status=SetImageProgress(image,SaveImageTag,3,6);
   1425             if (status == MagickFalse)
   1426               break;
   1427           }
   1428         for (y=0; y < (ssize_t) image->rows; y++)
   1429         {
   1430           register const Quantum
   1431             *magick_restrict p;
   1432 
   1433           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1434           if (p == (const Quantum *) NULL)
   1435             break;
   1436           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1437             BlackQuantum,pixels,exception);
   1438           count=WriteBlob(image,length,pixels);
   1439           if (count != (ssize_t) length)
   1440             break;
   1441         }
   1442         if (image->previous == (Image *) NULL)
   1443           {
   1444             status=SetImageProgress(image,SaveImageTag,4,6);
   1445             if (status == MagickFalse)
   1446               break;
   1447           }
   1448         if (quantum_type == CMYKAQuantum)
   1449           {
   1450             for (y=0; y < (ssize_t) image->rows; y++)
   1451             {
   1452               register const Quantum
   1453                 *magick_restrict p;
   1454 
   1455               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1456               if (p == (const Quantum *) NULL)
   1457                 break;
   1458               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1459                 AlphaQuantum,pixels,exception);
   1460               count=WriteBlob(image,length,pixels);
   1461               if (count != (ssize_t) length)
   1462               break;
   1463             }
   1464             if (image->previous == (Image *) NULL)
   1465               {
   1466                 status=SetImageProgress(image,SaveImageTag,5,6);
   1467                 if (status == MagickFalse)
   1468                   break;
   1469               }
   1470           }
   1471         if (image_info->interlace == PartitionInterlace)
   1472           (void) CopyMagickString(image->filename,image_info->filename,
   1473             MagickPathExtent);
   1474         if (image->previous == (Image *) NULL)
   1475           {
   1476             status=SetImageProgress(image,SaveImageTag,6,6);
   1477             if (status == MagickFalse)
   1478               break;
   1479           }
   1480         break;
   1481       }
   1482       case PartitionInterlace:
   1483       {
   1484         /*
   1485           Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
   1486         */
   1487         AppendImageFormat("C",image->filename);
   1488         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
   1489           AppendBinaryBlobMode,exception);
   1490         if (status == MagickFalse)
   1491           return(status);
   1492         for (y=0; y < (ssize_t) image->rows; y++)
   1493         {
   1494           register const Quantum
   1495             *magick_restrict p;
   1496 
   1497           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1498           if (p == (const Quantum *) NULL)
   1499             break;
   1500           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1501             CyanQuantum,pixels,exception);
   1502           count=WriteBlob(image,length,pixels);
   1503           if (count != (ssize_t) length)
   1504             break;
   1505         }
   1506         if (image->previous == (Image *) NULL)
   1507           {
   1508             status=SetImageProgress(image,SaveImageTag,1,6);
   1509             if (status == MagickFalse)
   1510               break;
   1511           }
   1512         (void) CloseBlob(image);
   1513         AppendImageFormat("M",image->filename);
   1514         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
   1515           AppendBinaryBlobMode,exception);
   1516         if (status == MagickFalse)
   1517           return(status);
   1518         for (y=0; y < (ssize_t) image->rows; y++)
   1519         {
   1520           register const Quantum
   1521             *magick_restrict p;
   1522 
   1523           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1524           if (p == (const Quantum *) NULL)
   1525             break;
   1526           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1527             MagentaQuantum,pixels,exception);
   1528           count=WriteBlob(image,length,pixels);
   1529           if (count != (ssize_t) length)
   1530             break;
   1531         }
   1532         if (image->previous == (Image *) NULL)
   1533           {
   1534             status=SetImageProgress(image,SaveImageTag,2,6);
   1535             if (status == MagickFalse)
   1536               break;
   1537           }
   1538         (void) CloseBlob(image);
   1539         AppendImageFormat("Y",image->filename);
   1540         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
   1541           AppendBinaryBlobMode,exception);
   1542         if (status == MagickFalse)
   1543           return(status);
   1544         for (y=0; y < (ssize_t) image->rows; y++)
   1545         {
   1546           register const Quantum
   1547             *magick_restrict p;
   1548 
   1549           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1550           if (p == (const Quantum *) NULL)
   1551             break;
   1552           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1553             YellowQuantum,pixels,exception);
   1554           count=WriteBlob(image,length,pixels);
   1555           if (count != (ssize_t) length)
   1556             break;
   1557         }
   1558         if (image->previous == (Image *) NULL)
   1559           {
   1560             status=SetImageProgress(image,SaveImageTag,3,6);
   1561             if (status == MagickFalse)
   1562               break;
   1563           }
   1564         (void) CloseBlob(image);
   1565         AppendImageFormat("K",image->filename);
   1566         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
   1567           AppendBinaryBlobMode,exception);
   1568         if (status == MagickFalse)
   1569           return(status);
   1570         for (y=0; y < (ssize_t) image->rows; y++)
   1571         {
   1572           register const Quantum
   1573             *magick_restrict p;
   1574 
   1575           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1576           if (p == (const Quantum *) NULL)
   1577             break;
   1578           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1579             BlackQuantum,pixels,exception);
   1580           count=WriteBlob(image,length,pixels);
   1581           if (count != (ssize_t) length)
   1582             break;
   1583         }
   1584         if (image->previous == (Image *) NULL)
   1585           {
   1586             status=SetImageProgress(image,SaveImageTag,4,6);
   1587             if (status == MagickFalse)
   1588               break;
   1589           }
   1590         if (quantum_type == CMYKAQuantum)
   1591           {
   1592             (void) CloseBlob(image);
   1593             AppendImageFormat("A",image->filename);
   1594             status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
   1595               AppendBinaryBlobMode,exception);
   1596             if (status == MagickFalse)
   1597               return(status);
   1598             for (y=0; y < (ssize_t) image->rows; y++)
   1599             {
   1600               register const Quantum
   1601                 *magick_restrict p;
   1602 
   1603               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   1604               if (p == (const Quantum *) NULL)
   1605                 break;
   1606               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1607                 AlphaQuantum,pixels,exception);
   1608               count=WriteBlob(image,length,pixels);
   1609               if (count != (ssize_t) length)
   1610                 break;
   1611             }
   1612             if (image->previous == (Image *) NULL)
   1613               {
   1614                 status=SetImageProgress(image,SaveImageTag,5,6);
   1615                 if (status == MagickFalse)
   1616                   break;
   1617               }
   1618           }
   1619         (void) CloseBlob(image);
   1620         (void) CopyMagickString(image->filename,image_info->filename,
   1621           MagickPathExtent);
   1622         if (image->previous == (Image *) NULL)
   1623           {
   1624             status=SetImageProgress(image,SaveImageTag,6,6);
   1625             if (status == MagickFalse)
   1626               break;
   1627           }
   1628         break;
   1629       }
   1630     }
   1631     quantum_info=DestroyQuantumInfo(quantum_info);
   1632     if (GetNextImageInList(image) == (Image *) NULL)
   1633       break;
   1634     image=SyncNextImageInList(image);
   1635     status=SetImageProgress(image,SaveImagesTag,scene++,
   1636       GetImageListLength(image));
   1637     if (status == MagickFalse)
   1638       break;
   1639   } while (image_info->adjoin != MagickFalse);
   1640   (void) CloseBlob(image);
   1641   return(MagickTrue);
   1642 }
   1643