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