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