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