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