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