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