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