]> 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-2012 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 *,ExceptionInfo *);
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,exception);
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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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 == (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,exception);
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   canvas_image=DestroyImage(canvas_image);
1065   (void) CloseBlob(image);
1066   return(GetFirstImageInList(image));
1067 }
1068 \f
1069 /*
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1071 %                                                                             %
1072 %                                                                             %
1073 %                                                                             %
1074 %   R e g i s t e r C M Y K I m a g e                                         %
1075 %                                                                             %
1076 %                                                                             %
1077 %                                                                             %
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 %
1080 %  RegisterCMYKImage() adds attributes for the CMYK image format to
1081 %  the list of supported formats.  The attributes include the image format
1082 %  tag, a method to read and/or write the format, whether the format
1083 %  supports the saving of more than one frame to the same file or blob,
1084 %  whether the format supports native in-memory I/O, and a brief
1085 %  description of the format.
1086 %
1087 %  The format of the RegisterCMYKImage method is:
1088 %
1089 %      size_t RegisterCMYKImage(void)
1090 %
1091 */
1092 ModuleExport size_t RegisterCMYKImage(void)
1093 {
1094   MagickInfo
1095     *entry;
1096
1097   entry=SetMagickInfo("CMYK");
1098   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1099   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1100   entry->raw=MagickTrue;
1101   entry->endian_support=MagickTrue;
1102   entry->description=ConstantString("Raw cyan, magenta, yellow, and black "
1103     "samples");
1104   entry->module=ConstantString("CMYK");
1105   (void) RegisterMagickInfo(entry);
1106   entry=SetMagickInfo("CMYKA");
1107   entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1108   entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1109   entry->raw=MagickTrue;
1110   entry->endian_support=MagickTrue;
1111   entry->description=ConstantString("Raw cyan, magenta, yellow, black, and "
1112     "alpha samples");
1113   entry->module=ConstantString("CMYK");
1114   (void) RegisterMagickInfo(entry);
1115   return(MagickImageCoderSignature);
1116 }
1117 \f
1118 /*
1119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120 %                                                                             %
1121 %                                                                             %
1122 %                                                                             %
1123 %   U n r e g i s t e r C M Y K I m a g e                                     %
1124 %                                                                             %
1125 %                                                                             %
1126 %                                                                             %
1127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1128 %
1129 %  UnregisterCMYKImage() removes format registrations made by the
1130 %  CMYK module from the list of supported formats.
1131 %
1132 %  The format of the UnregisterCMYKImage method is:
1133 %
1134 %      UnregisterCMYKImage(void)
1135 %
1136 */
1137 ModuleExport void UnregisterCMYKImage(void)
1138 {
1139   (void) UnregisterMagickInfo("CMYK");
1140   (void) UnregisterMagickInfo("CMYKA");
1141 }
1142 \f
1143 /*
1144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1145 %                                                                             %
1146 %                                                                             %
1147 %                                                                             %
1148 %   W r i t e C M Y K I m a g e                                               %
1149 %                                                                             %
1150 %                                                                             %
1151 %                                                                             %
1152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1153 %
1154 %  WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1155 %  black,rasterfile format.
1156 %
1157 %  The format of the WriteCMYKImage method is:
1158 %
1159 %      MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1160 %        Image *image,ExceptionInfo *exception)
1161 %
1162 %  A description of each parameter follows.
1163 %
1164 %    o image_info: the image info.
1165 %
1166 %    o image:  The image.
1167 %
1168 %    o exception: return any errors or warnings in this structure.
1169 %
1170 */
1171 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1172   Image *image,ExceptionInfo *exception)
1173 {
1174   MagickBooleanType
1175     status;
1176
1177   MagickOffsetType
1178     scene;
1179
1180   QuantumInfo
1181     *quantum_info;
1182
1183   QuantumType
1184     quantum_type;
1185
1186   size_t
1187     length;
1188
1189   ssize_t
1190     count,
1191     y;
1192
1193   unsigned char
1194     *pixels;
1195
1196   /*
1197     Allocate memory for pixels.
1198   */
1199   assert(image_info != (const ImageInfo *) NULL);
1200   assert(image_info->signature == MagickSignature);
1201   assert(image != (Image *) NULL);
1202   assert(image->signature == MagickSignature);
1203   if (image->debug != MagickFalse)
1204     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1205   if (image_info->interlace != PartitionInterlace)
1206     {
1207       /*
1208         Open output image file.
1209       */
1210       status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1211       if (status == MagickFalse)
1212         return(status);
1213     }
1214   quantum_type=CMYKQuantum;
1215   if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1216     {
1217       quantum_type=CMYKAQuantum;
1218       image->matte=MagickTrue;
1219     }
1220   scene=0;
1221   do
1222   {
1223     /*
1224       Convert MIFF to CMYK raster pixels.
1225     */
1226     if (image->colorspace != CMYKColorspace)
1227       (void) TransformImageColorspace(image,CMYKColorspace,exception);
1228     if ((LocaleCompare(image_info->magick,"CMYKA") == 0) &&
1229         (image->matte == MagickFalse))
1230       (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1231     quantum_info=AcquireQuantumInfo(image_info,image);
1232     if (quantum_info == (QuantumInfo *) NULL)
1233       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1234     pixels=GetQuantumPixels(quantum_info);
1235     switch (image_info->interlace)
1236     {
1237       case NoInterlace:
1238       default:
1239       {
1240         /*
1241           No interlacing:  CMYKCMYKCMYKCMYKCMYKCMYK...
1242         */
1243         for (y=0; y < (ssize_t) image->rows; y++)
1244         {
1245           register const Quantum
1246             *restrict p;
1247
1248           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1249           if (p == (const Quantum *) NULL)
1250             break;
1251           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1252             quantum_type,pixels,exception);
1253           count=WriteBlob(image,length,pixels);
1254           if (count != (ssize_t) length)
1255             break;
1256           if (image->previous == (Image *) NULL)
1257             {
1258               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1259                 image->rows);
1260               if (status == MagickFalse)
1261                 break;
1262             }
1263         }
1264         break;
1265       }
1266       case LineInterlace:
1267       {
1268         /*
1269           Line interlacing:  CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1270         */
1271         for (y=0; y < (ssize_t) image->rows; y++)
1272         {
1273           register const Quantum
1274             *restrict p;
1275
1276           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1277           if (p == (const Quantum *) NULL)
1278             break;
1279           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1280             CyanQuantum,pixels,exception);
1281           count=WriteBlob(image,length,pixels);
1282           if (count != (ssize_t) length)
1283             break;
1284           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1285             MagentaQuantum,pixels,exception);
1286           count=WriteBlob(image,length,pixels);
1287           if (count != (ssize_t) length)
1288             break;
1289           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1290             YellowQuantum,pixels,exception);
1291           count=WriteBlob(image,length,pixels);
1292           if (count != (ssize_t) length)
1293             break;
1294           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1295             BlackQuantum,pixels,exception);
1296           count=WriteBlob(image,length,pixels);
1297           if (count != (ssize_t) length)
1298             break;
1299           if (quantum_type == CMYKAQuantum)
1300             {
1301               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1302                 AlphaQuantum,pixels,exception);
1303               count=WriteBlob(image,length,pixels);
1304               if (count != (ssize_t) length)
1305                 break;
1306             }
1307           if (image->previous == (Image *) NULL)
1308             {
1309               status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1310                 image->rows);
1311               if (status == MagickFalse)
1312                 break;
1313             }
1314         }
1315         break;
1316       }
1317       case PlaneInterlace:
1318       {
1319         /*
1320           Plane interlacing:  CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1321         */
1322         for (y=0; y < (ssize_t) image->rows; y++)
1323         {
1324           register const Quantum
1325             *restrict p;
1326
1327           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1328           if (p == (const Quantum *) NULL)
1329             break;
1330           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1331             CyanQuantum,pixels,exception);
1332           count=WriteBlob(image,length,pixels);
1333           if (count != (ssize_t) length)
1334             break;
1335         }
1336         if (image->previous == (Image *) NULL)
1337           {
1338             status=SetImageProgress(image,SaveImageTag,1,6);
1339             if (status == MagickFalse)
1340               break;
1341           }
1342         for (y=0; y < (ssize_t) image->rows; y++)
1343         {
1344           register const Quantum
1345             *restrict p;
1346
1347           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1348           if (p == (const Quantum *) NULL)
1349             break;
1350           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1351             MagentaQuantum,pixels,exception);
1352           count=WriteBlob(image,length,pixels);
1353           if (count != (ssize_t) length)
1354             break;
1355         }
1356         if (image->previous == (Image *) NULL)
1357           {
1358             status=SetImageProgress(image,SaveImageTag,2,6);
1359             if (status == MagickFalse)
1360               break;
1361           }
1362         for (y=0; y < (ssize_t) image->rows; y++)
1363         {
1364           register const Quantum
1365             *restrict p;
1366
1367           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1368           if (p == (const Quantum *) NULL)
1369             break;
1370           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1371             YellowQuantum,pixels,exception);
1372           count=WriteBlob(image,length,pixels);
1373           if (count != (ssize_t) length)
1374             break;
1375         }
1376         if (image->previous == (Image *) NULL)
1377           {
1378             status=SetImageProgress(image,SaveImageTag,3,6);
1379             if (status == MagickFalse)
1380               break;
1381           }
1382         for (y=0; y < (ssize_t) image->rows; y++)
1383         {
1384           register const Quantum
1385             *restrict p;
1386
1387           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1388           if (p == (const Quantum *) NULL)
1389             break;
1390           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1391             BlackQuantum,pixels,exception);
1392           count=WriteBlob(image,length,pixels);
1393           if (count != (ssize_t) length)
1394             break;
1395         }
1396         if (image->previous == (Image *) NULL)
1397           {
1398             status=SetImageProgress(image,SaveImageTag,4,6);
1399             if (status == MagickFalse)
1400               break;
1401           }
1402         if (quantum_type == CMYKAQuantum)
1403           {
1404             for (y=0; y < (ssize_t) image->rows; y++)
1405             {
1406               register const Quantum
1407                 *restrict p;
1408
1409               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1410               if (p == (const Quantum *) NULL)
1411                 break;
1412               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1413                 AlphaQuantum,pixels,exception);
1414               count=WriteBlob(image,length,pixels);
1415               if (count != (ssize_t) length)
1416               break;
1417             }
1418             if (image->previous == (Image *) NULL)
1419               {
1420                 status=SetImageProgress(image,SaveImageTag,5,6);
1421                 if (status == MagickFalse)
1422                   break;
1423               }
1424           }
1425         if (image_info->interlace == PartitionInterlace)
1426           (void) CopyMagickString(image->filename,image_info->filename,
1427             MaxTextExtent);
1428         if (image->previous == (Image *) NULL)
1429           {
1430             status=SetImageProgress(image,SaveImageTag,6,6);
1431             if (status == MagickFalse)
1432               break;
1433           }
1434         break;
1435       }
1436       case PartitionInterlace:
1437       {
1438         /*
1439           Partition interlacing:  CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1440         */
1441         AppendImageFormat("C",image->filename);
1442         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1443           AppendBinaryBlobMode,exception);
1444         if (status == MagickFalse)
1445           return(status);
1446         for (y=0; y < (ssize_t) image->rows; y++)
1447         {
1448           register const Quantum
1449             *restrict p;
1450
1451           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1452           if (p == (const Quantum *) NULL)
1453             break;
1454           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1455             CyanQuantum,pixels,exception);
1456           count=WriteBlob(image,length,pixels);
1457           if (count != (ssize_t) length)
1458             break;
1459         }
1460         if (image->previous == (Image *) NULL)
1461           {
1462             status=SetImageProgress(image,SaveImageTag,1,6);
1463             if (status == MagickFalse)
1464               break;
1465           }
1466         (void) CloseBlob(image);
1467         AppendImageFormat("M",image->filename);
1468         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1469           AppendBinaryBlobMode,exception);
1470         if (status == MagickFalse)
1471           return(status);
1472         for (y=0; y < (ssize_t) image->rows; y++)
1473         {
1474           register const Quantum
1475             *restrict p;
1476
1477           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1478           if (p == (const Quantum *) NULL)
1479             break;
1480           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1481             MagentaQuantum,pixels,exception);
1482           count=WriteBlob(image,length,pixels);
1483           if (count != (ssize_t) length)
1484             break;
1485         }
1486         if (image->previous == (Image *) NULL)
1487           {
1488             status=SetImageProgress(image,SaveImageTag,2,6);
1489             if (status == MagickFalse)
1490               break;
1491           }
1492         (void) CloseBlob(image);
1493         AppendImageFormat("Y",image->filename);
1494         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1495           AppendBinaryBlobMode,exception);
1496         if (status == MagickFalse)
1497           return(status);
1498         for (y=0; y < (ssize_t) image->rows; y++)
1499         {
1500           register const Quantum
1501             *restrict p;
1502
1503           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1504           if (p == (const Quantum *) NULL)
1505             break;
1506           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1507             YellowQuantum,pixels,exception);
1508           count=WriteBlob(image,length,pixels);
1509           if (count != (ssize_t) length)
1510             break;
1511         }
1512         if (image->previous == (Image *) NULL)
1513           {
1514             status=SetImageProgress(image,SaveImageTag,3,6);
1515             if (status == MagickFalse)
1516               break;
1517           }
1518         (void) CloseBlob(image);
1519         AppendImageFormat("K",image->filename);
1520         status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1521           AppendBinaryBlobMode,exception);
1522         if (status == MagickFalse)
1523           return(status);
1524         for (y=0; y < (ssize_t) image->rows; y++)
1525         {
1526           register const Quantum
1527             *restrict p;
1528
1529           p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1530           if (p == (const Quantum *) NULL)
1531             break;
1532           length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1533             BlackQuantum,pixels,exception);
1534           count=WriteBlob(image,length,pixels);
1535           if (count != (ssize_t) length)
1536             break;
1537         }
1538         if (image->previous == (Image *) NULL)
1539           {
1540             status=SetImageProgress(image,SaveImageTag,4,6);
1541             if (status == MagickFalse)
1542               break;
1543           }
1544         if (quantum_type == CMYKAQuantum)
1545           {
1546             (void) CloseBlob(image);
1547             AppendImageFormat("A",image->filename);
1548             status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1549               AppendBinaryBlobMode,exception);
1550             if (status == MagickFalse)
1551               return(status);
1552             for (y=0; y < (ssize_t) image->rows; y++)
1553             {
1554               register const Quantum
1555                 *restrict p;
1556
1557               p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1558               if (p == (const Quantum *) NULL)
1559                 break;
1560               length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1561                 AlphaQuantum,pixels,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 }