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