]> granicus.if.org Git - imagemagick/blob - coders/cmyk.c
(no commit message)
[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-2015 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 void
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 == MagickSignature);
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 == MagickSignature);
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 void *) 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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
185           &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
217               &count);
218           }
219         for (y=0; y < (ssize_t) image->extract_info.height; y++)
220         {
221           register const Quantum
222             *restrict p;
223
224           register Quantum
225             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
277             &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
300               &count);
301           }
302         for (y=0; y < (ssize_t) image->extract_info.height; y++)
303         {
304           register const Quantum
305             *restrict p;
306
307           register Quantum
308             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
379               &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
400               &count);
401           }
402         for (y=0; y < (ssize_t) image->extract_info.height; y++)
403         {
404           register const Quantum
405             *restrict p;
406
407           register Quantum
408             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
447             &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             *restrict p;
459
460           register Quantum
461             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
500             &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             *restrict p;
512
513           register Quantum
514             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
553             &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             *restrict p;
565
566           register Quantum
567             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
606             &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                 *restrict p;
620
621               register Quantum
622                 *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
662                 &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
700               &count);
701             if (count != (ssize_t) length)
702               {
703                 ThrowFileException(exception,CorruptImageError,
704                   "UnexpectedEndOfFile",image->filename);
705                 break;
706               }
707           }
708         pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
709           &count);
710         for (y=0; y < (ssize_t) image->extract_info.height; y++)
711         {
712           register const Quantum
713             *restrict p;
714
715           register Quantum
716             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
755             &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
777               &count);
778             if (count != (ssize_t) length)
779               {
780                 ThrowFileException(exception,CorruptImageError,
781                   "UnexpectedEndOfFile",image->filename);
782                 break;
783               }
784           }
785         pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
786           &count);
787         for (y=0; y < (ssize_t) image->extract_info.height; y++)
788         {
789           register const Quantum
790             *restrict p;
791
792           register Quantum
793             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
831             &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
853               &count);
854             if (count != (ssize_t) length)
855               {
856                 ThrowFileException(exception,CorruptImageError,
857                   "UnexpectedEndOfFile",image->filename);
858                 break;
859               }
860           }
861         pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
862           &count);
863         for (y=0; y < (ssize_t) image->extract_info.height; y++)
864         {
865           register const Quantum
866             *restrict p;
867
868           register Quantum
869             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
908             &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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
930               &count);
931             if (count != (ssize_t) length)
932               {
933                 ThrowFileException(exception,CorruptImageError,
934                   "UnexpectedEndOfFile",image->filename);
935                 break;
936               }
937           }
938         pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
939           &count);
940         for (y=0; y < (ssize_t) image->extract_info.height; y++)
941         {
942           register const Quantum
943             *restrict p;
944
945           register Quantum
946             *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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
985             &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=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=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
1018               &count);
1019             for (y=0; y < (ssize_t) image->extract_info.height; y++)
1020             {
1021               register const Quantum
1022                 *restrict p;
1023
1024               register Quantum
1025                 *restrict q;
1026
1027               register ssize_t
1028                 x;
1029
1030               if (count != (ssize_t) length)
1031                 {
1032                   ThrowFileException(exception,CorruptImageError,
1033                     "UnexpectedEndOfFile",image->filename);
1034                   break;
1035                 }
1036               q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
1037                 exception);
1038               if (q == (Quantum *) NULL)
1039                 break;
1040               length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
1041                 quantum_info,YellowQuantum,pixels,exception);
1042               if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1043                 break;
1044               if (((y-image->extract_info.y) >= 0) && 
1045                   ((y-image->extract_info.y) < (ssize_t) image->rows))
1046                 {
1047                   p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
1048                     0,canvas_image->columns,1,exception);
1049                   q=GetAuthenticPixels(image,0,y-image->extract_info.y,
1050                     image->columns,1,exception);
1051                   if ((p == (const Quantum *) NULL) ||
1052                       (q == (Quantum *) NULL))
1053                     break;
1054                   for (x=0; x < (ssize_t) image->columns; x++)
1055                   {
1056                     SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1057                     p+=GetPixelChannels(canvas_image);
1058                     q+=GetPixelChannels(image);
1059                   }
1060                   if (SyncAuthenticPixels(image,exception) == MagickFalse)
1061                     break;
1062                }
1063               pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
1064                 &count);
1065             }
1066             if (image->previous == (Image *) NULL)
1067               {
1068                 status=SetImageProgress(image,LoadImageTag,4,5);
1069                 if (status == MagickFalse)
1070                   break;
1071               }
1072           }
1073         if (image->previous == (Image *) NULL)
1074           {
1075             status=SetImageProgress(image,LoadImageTag,5,5);
1076             if (status == MagickFalse)
1077               break;
1078           }
1079         break;
1080       }
1081     }
1082     SetQuantumImageType(image,quantum_type);
1083     /*
1084       Proceed to next image.
1085     */
1086     if (image_info->number_scenes != 0)
1087       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1088         break;
1089     if (count == (ssize_t) length)
1090       {
1091         /*
1092           Allocate next image structure.
1093         */
1094         AcquireNextImage(image_info,image,exception);
1095         if (GetNextImageInList(image) == (Image *) NULL)
1096           {
1097             image=DestroyImageList(image);
1098             return((Image *) NULL);
1099           }
1100         image=SyncNextImageInList(image);
1101         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1102           GetBlobSize(image));
1103         if (status == MagickFalse)
1104           break;
1105       }
1106     scene++;
1107   } while (count == (ssize_t) length);
1108   quantum_info=DestroyQuantumInfo(quantum_info);
1109   canvas_image=DestroyImage(canvas_image);
1110   (void) CloseBlob(image);
1111   return(GetFirstImageInList(image));
1112 }
1113 \f
1114 /*
1115 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1116 %                                                                             %
1117 %                                                                             %
1118 %                                                                             %
1119 %   R e g i s t e r C M Y K I m a g e                                         %
1120 %                                                                             %
1121 %                                                                             %
1122 %                                                                             %
1123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 %
1125 %  RegisterCMYKImage() adds attributes for the CMYK image format to
1126 %  the list of supported formats.  The attributes include the image format
1127 %  tag, a method to read and/or write the format, whether the format
1128 %  supports the saving of more than one frame to the same file or blob,
1129 %  whether the format supports native in-memory I/O, and a brief
1130 %  description of the format.
1131 %
1132 %  The format of the RegisterCMYKImage method is:
1133 %
1134 %      size_t RegisterCMYKImage(void)
1135 %
1136 */
1137 ModuleExport size_t RegisterCMYKImage(void)
1138 {
1139   MagickInfo
1140     *entry;
1141
1142   entry=AcquireMagickInfo("CMYK","CMYK",
1143     "Raw cyan, magenta, yellow, and black samples");
1144   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1145   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1146   entry->flags|=CoderRawSupportFlag;
1147   entry->flags|=CoderEndianSupportFlag;
1148   (void) RegisterMagickInfo(entry);
1149   entry=AcquireMagickInfo("CMYK","CMYKA",
1150     "Raw cyan, magenta, yellow, black, and alpha samples");
1151   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1152   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1153   entry->flags|=CoderRawSupportFlag;
1154   entry->flags|=CoderEndianSupportFlag;
1155   (void) RegisterMagickInfo(entry);
1156   return(MagickImageCoderSignature);
1157 }
1158 \f
1159 /*
1160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1161 %                                                                             %
1162 %                                                                             %
1163 %                                                                             %
1164 %   U n r e g i s t e r C M Y K I m a g e                                     %
1165 %                                                                             %
1166 %                                                                             %
1167 %                                                                             %
1168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1169 %
1170 %  UnregisterCMYKImage() removes format registrations made by the
1171 %  CMYK module from the list of supported formats.
1172 %
1173 %  The format of the UnregisterCMYKImage method is:
1174 %
1175 %      UnregisterCMYKImage(void)
1176 %
1177 */
1178 ModuleExport void UnregisterCMYKImage(void)
1179 {
1180   (void) UnregisterMagickInfo("CMYK");
1181   (void) UnregisterMagickInfo("CMYKA");
1182 }
1183 \f
1184 /*
1185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1186 %                                                                             %
1187 %                                                                             %
1188 %                                                                             %
1189 %   W r i t e C M Y K I m a g e                                               %
1190 %                                                                             %
1191 %                                                                             %
1192 %                                                                             %
1193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1194 %
1195 %  WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1196 %  black,rasterfile format.
1197 %
1198 %  The format of the WriteCMYKImage method is:
1199 %
1200 %      MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1201 %        Image *image,ExceptionInfo *exception)
1202 %
1203 %  A description of each parameter follows.
1204 %
1205 %    o image_info: the image info.
1206 %
1207 %    o image:  The image.
1208 %
1209 %    o exception: return any errors or warnings in this structure.
1210 %
1211 */
1212 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1213   Image *image,ExceptionInfo *exception)
1214 {
1215   MagickBooleanType
1216     status;
1217
1218   MagickOffsetType
1219     scene;
1220
1221   QuantumInfo
1222     *quantum_info;
1223
1224   QuantumType
1225     quantum_type;
1226
1227   size_t
1228     length;
1229
1230   ssize_t
1231     count,
1232     y;
1233
1234   unsigned char
1235     *pixels;
1236
1237   /*
1238     Allocate memory for pixels.
1239   */
1240   assert(image_info != (const ImageInfo *) NULL);
1241   assert(image_info->signature == MagickSignature);
1242   assert(image != (Image *) NULL);
1243   assert(image->signature == MagickSignature);
1244   if (image->debug != MagickFalse)
1245     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1246   if (image_info->interlace != PartitionInterlace)
1247     {
1248       /*
1249         Open output image file.
1250       */
1251       status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1252       if (status == MagickFalse)
1253         return(status);
1254     }
1255   scene=0;
1256   do
1257   {
1258     /*
1259       Convert MIFF to CMYK raster pixels.
1260     */
1261     if (image->colorspace != CMYKColorspace)
1262       (void) TransformImageColorspace(image,CMYKColorspace,exception);
1263     quantum_type=CMYKQuantum;
1264     if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1265       {
1266         quantum_type=CMYKAQuantum;
1267         if (image->alpha_trait == UndefinedPixelTrait)
1268           (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1269       }
1270     quantum_info=AcquireQuantumInfo(image_info,image);
1271     if (quantum_info == (QuantumInfo *) NULL)
1272       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1273     pixels=GetQuantumPixels(quantum_info);
1274     switch (image_info->interlace)
1275     {
1276       case NoInterlace:
1277       default:
1278       {
1279         /*
1280           No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
1281         */
1282         for (y=0; y < (ssize_t) image->rows; y++)
1283         {
1284           register const Quantum
1285             *restrict p;
1286
1287           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1288           if (p == (const Quantum *) NULL)
1289             break;
1290           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1291             quantum_type,pixels,exception);
1292           count=WriteBlob(image,length,pixels);
1293           if (count != (ssize_t) length)
1294             break;
1295           if (image->previous == (Image *) NULL)
1296             {
1297               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1298                 image->rows);
1299               if (status == MagickFalse)
1300                 break;
1301             }
1302         }
1303         break;
1304       }
1305       case LineInterlace:
1306       {
1307         /*
1308           Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1309         */
1310         for (y=0; y < (ssize_t) image->rows; y++)
1311         {
1312           register const Quantum
1313             *restrict p;
1314
1315           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1316           if (p == (const Quantum *) NULL)
1317             break;
1318           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1319             CyanQuantum,pixels,exception);
1320           count=WriteBlob(image,length,pixels);
1321           if (count != (ssize_t) length)
1322             break;
1323           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1324             MagentaQuantum,pixels,exception);
1325           count=WriteBlob(image,length,pixels);
1326           if (count != (ssize_t) length)
1327             break;
1328           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1329             YellowQuantum,pixels,exception);
1330           count=WriteBlob(image,length,pixels);
1331           if (count != (ssize_t) length)
1332             break;
1333           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1334             BlackQuantum,pixels,exception);
1335           count=WriteBlob(image,length,pixels);
1336           if (count != (ssize_t) length)
1337             break;
1338           if (quantum_type == CMYKAQuantum)
1339             {
1340               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1341                 AlphaQuantum,pixels,exception);
1342               count=WriteBlob(image,length,pixels);
1343               if (count != (ssize_t) length)
1344                 break;
1345             }
1346           if (image->previous == (Image *) NULL)
1347             {
1348               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1349                 image->rows);
1350               if (status == MagickFalse)
1351                 break;
1352             }
1353         }
1354         break;
1355       }
1356       case PlaneInterlace:
1357       {
1358         /*
1359           Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1360         */
1361         for (y=0; y < (ssize_t) image->rows; y++)
1362         {
1363           register const Quantum
1364             *restrict p;
1365
1366           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1367           if (p == (const Quantum *) NULL)
1368             break;
1369           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1370             CyanQuantum,pixels,exception);
1371           count=WriteBlob(image,length,pixels);
1372           if (count != (ssize_t) length)
1373             break;
1374         }
1375         if (image->previous == (Image *) NULL)
1376           {
1377             status=SetImageProgress(image,SaveImageTag,1,6);
1378             if (status == MagickFalse)
1379               break;
1380           }
1381         for (y=0; y < (ssize_t) image->rows; y++)
1382         {
1383           register const Quantum
1384             *restrict p;
1385
1386           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1387           if (p == (const Quantum *) NULL)
1388             break;
1389           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1390             MagentaQuantum,pixels,exception);
1391           count=WriteBlob(image,length,pixels);
1392           if (count != (ssize_t) length)
1393             break;
1394         }
1395         if (image->previous == (Image *) NULL)
1396           {
1397             status=SetImageProgress(image,SaveImageTag,2,6);
1398             if (status == MagickFalse)
1399               break;
1400           }
1401         for (y=0; y < (ssize_t) image->rows; y++)
1402         {
1403           register const Quantum
1404             *restrict p;
1405
1406           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1407           if (p == (const Quantum *) NULL)
1408             break;
1409           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1410             YellowQuantum,pixels,exception);
1411           count=WriteBlob(image,length,pixels);
1412           if (count != (ssize_t) length)
1413             break;
1414         }
1415         if (image->previous == (Image *) NULL)
1416           {
1417             status=SetImageProgress(image,SaveImageTag,3,6);
1418             if (status == MagickFalse)
1419               break;
1420           }
1421         for (y=0; y < (ssize_t) image->rows; y++)
1422         {
1423           register const Quantum
1424             *restrict p;
1425
1426           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1427           if (p == (const Quantum *) NULL)
1428             break;
1429           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1430             BlackQuantum,pixels,exception);
1431           count=WriteBlob(image,length,pixels);
1432           if (count != (ssize_t) length)
1433             break;
1434         }
1435         if (image->previous == (Image *) NULL)
1436           {
1437             status=SetImageProgress(image,SaveImageTag,4,6);
1438             if (status == MagickFalse)
1439               break;
1440           }
1441         if (quantum_type == CMYKAQuantum)
1442           {
1443             for (y=0; y < (ssize_t) image->rows; y++)
1444             {
1445               register const Quantum
1446                 *restrict p;
1447
1448               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1449               if (p == (const Quantum *) NULL)
1450                 break;
1451               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1452                 AlphaQuantum,pixels,exception);
1453               count=WriteBlob(image,length,pixels);
1454               if (count != (ssize_t) length)
1455               break;
1456             }
1457             if (image->previous == (Image *) NULL)
1458               {
1459                 status=SetImageProgress(image,SaveImageTag,5,6);
1460                 if (status == MagickFalse)
1461                   break;
1462               }
1463           }
1464         if (image_info->interlace == PartitionInterlace)
1465           (void) CopyMagickString(image->filename,image_info->filename,
1466             MagickPathExtent);
1467         if (image->previous == (Image *) NULL)
1468           {
1469             status=SetImageProgress(image,SaveImageTag,6,6);
1470             if (status == MagickFalse)
1471               break;
1472           }
1473         break;
1474       }
1475       case PartitionInterlace:
1476       {
1477         /*
1478           Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1479         */
1480         AppendImageFormat("C",image->filename);
1481         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1482           AppendBinaryBlobMode,exception);
1483         if (status == MagickFalse)
1484           return(status);
1485         for (y=0; y < (ssize_t) image->rows; y++)
1486         {
1487           register const Quantum
1488             *restrict p;
1489
1490           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1491           if (p == (const Quantum *) NULL)
1492             break;
1493           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1494             CyanQuantum,pixels,exception);
1495           count=WriteBlob(image,length,pixels);
1496           if (count != (ssize_t) length)
1497             break;
1498         }
1499         if (image->previous == (Image *) NULL)
1500           {
1501             status=SetImageProgress(image,SaveImageTag,1,6);
1502             if (status == MagickFalse)
1503               break;
1504           }
1505         (void) CloseBlob(image);
1506         AppendImageFormat("M",image->filename);
1507         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1508           AppendBinaryBlobMode,exception);
1509         if (status == MagickFalse)
1510           return(status);
1511         for (y=0; y < (ssize_t) image->rows; y++)
1512         {
1513           register const Quantum
1514             *restrict p;
1515
1516           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1517           if (p == (const Quantum *) NULL)
1518             break;
1519           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1520             MagentaQuantum,pixels,exception);
1521           count=WriteBlob(image,length,pixels);
1522           if (count != (ssize_t) length)
1523             break;
1524         }
1525         if (image->previous == (Image *) NULL)
1526           {
1527             status=SetImageProgress(image,SaveImageTag,2,6);
1528             if (status == MagickFalse)
1529               break;
1530           }
1531         (void) CloseBlob(image);
1532         AppendImageFormat("Y",image->filename);
1533         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1534           AppendBinaryBlobMode,exception);
1535         if (status == MagickFalse)
1536           return(status);
1537         for (y=0; y < (ssize_t) image->rows; y++)
1538         {
1539           register const Quantum
1540             *restrict p;
1541
1542           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1543           if (p == (const Quantum *) NULL)
1544             break;
1545           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1546             YellowQuantum,pixels,exception);
1547           count=WriteBlob(image,length,pixels);
1548           if (count != (ssize_t) length)
1549             break;
1550         }
1551         if (image->previous == (Image *) NULL)
1552           {
1553             status=SetImageProgress(image,SaveImageTag,3,6);
1554             if (status == MagickFalse)
1555               break;
1556           }
1557         (void) CloseBlob(image);
1558         AppendImageFormat("K",image->filename);
1559         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1560           AppendBinaryBlobMode,exception);
1561         if (status == MagickFalse)
1562           return(status);
1563         for (y=0; y < (ssize_t) image->rows; y++)
1564         {
1565           register const Quantum
1566             *restrict p;
1567
1568           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1569           if (p == (const Quantum *) NULL)
1570             break;
1571           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1572             BlackQuantum,pixels,exception);
1573           count=WriteBlob(image,length,pixels);
1574           if (count != (ssize_t) length)
1575             break;
1576         }
1577         if (image->previous == (Image *) NULL)
1578           {
1579             status=SetImageProgress(image,SaveImageTag,4,6);
1580             if (status == MagickFalse)
1581               break;
1582           }
1583         if (quantum_type == CMYKAQuantum)
1584           {
1585             (void) CloseBlob(image);
1586             AppendImageFormat("A",image->filename);
1587             status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1588               AppendBinaryBlobMode,exception);
1589             if (status == MagickFalse)
1590               return(status);
1591             for (y=0; y < (ssize_t) image->rows; y++)
1592             {
1593               register const Quantum
1594                 *restrict p;
1595
1596               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1597               if (p == (const Quantum *) NULL)
1598                 break;
1599               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1600                 AlphaQuantum,pixels,exception);
1601               count=WriteBlob(image,length,pixels);
1602               if (count != (ssize_t) length)
1603                 break;
1604             }
1605             if (image->previous == (Image *) NULL)
1606               {
1607                 status=SetImageProgress(image,SaveImageTag,5,6);
1608                 if (status == MagickFalse)
1609                   break;
1610               }
1611           }
1612         (void) CloseBlob(image);
1613         (void) CopyMagickString(image->filename,image_info->filename,
1614           MagickPathExtent);
1615         if (image->previous == (Image *) NULL)
1616           {
1617             status=SetImageProgress(image,SaveImageTag,6,6);
1618             if (status == MagickFalse)
1619               break;
1620           }
1621         break;
1622       }
1623     }
1624     quantum_info=DestroyQuantumInfo(quantum_info);
1625     if (GetNextImageInList(image) == (Image *) NULL)
1626       break;
1627     image=SyncNextImageInList(image);
1628     status=SetImageProgress(image,SaveImagesTag,scene++,
1629       GetImageListLength(image));
1630     if (status == MagickFalse)
1631       break;
1632   } while (image_info->adjoin != MagickFalse);
1633   (void) CloseBlob(image);
1634   return(MagickTrue);
1635 }