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