2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write RAW CMYK Image Format %
20 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/colorspace.h"
47 #include "MagickCore/constitute.h"
48 #include "MagickCore/exception.h"
49 #include "MagickCore/exception-private.h"
50 #include "MagickCore/image.h"
51 #include "MagickCore/image-private.h"
52 #include "MagickCore/list.h"
53 #include "MagickCore/magick.h"
54 #include "MagickCore/memory_.h"
55 #include "MagickCore/monitor.h"
56 #include "MagickCore/monitor-private.h"
57 #include "MagickCore/pixel-accessor.h"
58 #include "MagickCore/quantum-private.h"
59 #include "MagickCore/static.h"
60 #include "MagickCore/statistic.h"
61 #include "MagickCore/string_.h"
62 #include "MagickCore/module.h"
63 #include "MagickCore/utility.h"
68 static MagickBooleanType
69 WriteCMYKImage(const ImageInfo *,Image *,ExceptionInfo *);
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 % R e a d C M Y K I m a g e %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 % ReadCMYKImage() reads an image of raw CMYK or CMYKA samples and returns it.
83 % It allocates the memory necessary for the new Image structure and returns a
84 % pointer to the new image.
86 % The format of the ReadCMYKImage method is:
88 % Image *ReadCMYKImage(const ImageInfo *image_info,
89 % ExceptionInfo *exception)
91 % A description of each parameter follows:
93 % o image_info: the image info.
95 % o exception: return any errors or warnings in this structure.
98 static Image *ReadCMYKImage(const ImageInfo *image_info,
99 ExceptionInfo *exception)
133 assert(image_info != (const ImageInfo *) NULL);
134 assert(image_info->signature == MagickSignature);
135 if (image_info->debug != MagickFalse)
136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
137 image_info->filename);
138 assert(exception != (ExceptionInfo *) NULL);
139 assert(exception->signature == MagickSignature);
140 image=AcquireImage(image_info,exception);
141 if ((image->columns == 0) || (image->rows == 0))
142 ThrowReaderException(OptionError,"MustSpecifyImageSize");
143 image->colorspace=CMYKColorspace;
144 if (image_info->interlace != PartitionInterlace)
146 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
147 if (status == MagickFalse)
149 image=DestroyImageList(image);
150 return((Image *) NULL);
152 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
157 Create virtual canvas to support cropping (i.e. image.cmyk[100x100+10+20]).
159 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
161 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
163 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
164 if (quantum_info == (QuantumInfo *) NULL)
165 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
166 pixels=GetQuantumPixels(quantum_info);
167 quantum_type=CMYKQuantum;
168 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
170 quantum_type=CMYKAQuantum;
171 image->matte=MagickTrue;
173 if (image_info->number_scenes != 0)
174 while (image->scene < image_info->scene)
180 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
181 for (y=0; y < (ssize_t) image->rows; y++)
183 count=ReadBlob(image,length,pixels);
184 if (count != (ssize_t) length)
194 Read pixels to virtual canvas image then push to image.
196 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
197 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
199 image->colorspace=CMYKColorspace;
200 switch (image_info->interlace)
206 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
210 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
211 count=ReadBlob(image,length,pixels);
213 for (y=0; y < (ssize_t) image->extract_info.height; y++)
215 register const Quantum
224 if (count != (ssize_t) length)
226 ThrowFileException(exception,CorruptImageError,
227 "UnexpectedEndOfFile",image->filename);
230 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
232 if (q == (Quantum *) NULL)
234 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
235 quantum_info,quantum_type,pixels,exception);
236 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
238 if (((y-image->extract_info.y) >= 0) &&
239 ((y-image->extract_info.y) < (ssize_t) image->rows))
241 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
242 canvas_image->columns,1,exception);
243 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
244 image->columns,1,exception);
245 if ((p == (const Quantum *) NULL) ||
246 (q == (Quantum *) NULL))
248 for (x=0; x < (ssize_t) image->columns; x++)
250 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
251 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
252 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
253 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
254 SetPixelAlpha(image,OpaqueAlpha,q);
255 if (image->matte != MagickFalse)
256 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
257 p+=GetPixelChannels(canvas_image);
258 q+=GetPixelChannels(image);
260 if (SyncAuthenticPixels(image,exception) == MagickFalse)
263 if (image->previous == (Image *) NULL)
265 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
267 if (status == MagickFalse)
270 count=ReadBlob(image,length,pixels);
287 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
291 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
292 count=ReadBlob(image,length,pixels);
294 for (y=0; y < (ssize_t) image->extract_info.height; y++)
296 register const Quantum
305 if (count != (ssize_t) length)
307 ThrowFileException(exception,CorruptImageError,
308 "UnexpectedEndOfFile",image->filename);
311 for (i=0; i < (image->matte != MagickFalse ? 5 : 4); i++)
313 quantum_type=quantum_types[i];
314 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
316 if (q == (Quantum *) NULL)
318 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
319 quantum_info,quantum_type,pixels,exception);
320 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
322 if (((y-image->extract_info.y) >= 0) &&
323 ((y-image->extract_info.y) < (ssize_t) image->rows))
325 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
326 0,canvas_image->columns,1,exception);
327 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
328 image->columns,1,exception);
329 if ((p == (const Quantum *) NULL) ||
330 (q == (Quantum *) NULL))
332 for (x=0; x < (ssize_t) image->columns; x++)
334 switch (quantum_type)
338 SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
343 SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
348 SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
353 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
358 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
364 p+=GetPixelChannels(canvas_image);
365 q+=GetPixelChannels(image);
367 if (SyncAuthenticPixels(image,exception) == MagickFalse)
370 count=ReadBlob(image,length,pixels);
372 if (image->previous == (Image *) NULL)
374 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
376 if (status == MagickFalse)
385 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
389 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
390 count=ReadBlob(image,length,pixels);
392 for (y=0; y < (ssize_t) image->extract_info.height; y++)
394 register const Quantum
403 if (count != (ssize_t) length)
405 ThrowFileException(exception,CorruptImageError,
406 "UnexpectedEndOfFile",image->filename);
409 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
411 if (q == (Quantum *) NULL)
413 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
414 quantum_info,CyanQuantum,pixels,exception);
415 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
417 if (((y-image->extract_info.y) >= 0) &&
418 ((y-image->extract_info.y) < (ssize_t) image->rows))
420 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
421 canvas_image->columns,1,exception);
422 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
423 image->columns,1,exception);
424 if ((p == (const Quantum *) NULL) ||
425 (q == (Quantum *) NULL))
427 for (x=0; x < (ssize_t) image->columns; x++)
429 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
430 p+=GetPixelChannels(canvas_image);
431 q+=GetPixelChannels(image);
433 if (SyncAuthenticPixels(image,exception) == MagickFalse)
436 count=ReadBlob(image,length,pixels);
438 if (image->previous == (Image *) NULL)
440 status=SetImageProgress(image,LoadImageTag,1,6);
441 if (status == MagickFalse)
444 for (y=0; y < (ssize_t) image->extract_info.height; y++)
446 register const Quantum
455 if (count != (ssize_t) length)
457 ThrowFileException(exception,CorruptImageError,
458 "UnexpectedEndOfFile",image->filename);
461 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
463 if (q == (Quantum *) NULL)
465 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
466 quantum_info,MagentaQuantum,pixels,exception);
467 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
469 if (((y-image->extract_info.y) >= 0) &&
470 ((y-image->extract_info.y) < (ssize_t) image->rows))
472 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
473 canvas_image->columns,1,exception);
474 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
475 image->columns,1,exception);
476 if ((p == (const Quantum *) NULL) ||
477 (q == (Quantum *) NULL))
479 for (x=0; x < (ssize_t) image->columns; x++)
481 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
482 p+=GetPixelChannels(canvas_image);
483 q+=GetPixelChannels(image);
485 if (SyncAuthenticPixels(image,exception) == MagickFalse)
488 count=ReadBlob(image,length,pixels);
490 if (image->previous == (Image *) NULL)
492 status=SetImageProgress(image,LoadImageTag,2,6);
493 if (status == MagickFalse)
496 for (y=0; y < (ssize_t) image->extract_info.height; y++)
498 register const Quantum
507 if (count != (ssize_t) length)
509 ThrowFileException(exception,CorruptImageError,
510 "UnexpectedEndOfFile",image->filename);
513 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
515 if (q == (Quantum *) NULL)
517 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
518 quantum_info,YellowQuantum,pixels,exception);
519 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
521 if (((y-image->extract_info.y) >= 0) &&
522 ((y-image->extract_info.y) < (ssize_t) image->rows))
524 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
525 canvas_image->columns,1,exception);
526 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
527 image->columns,1,exception);
528 if ((p == (const Quantum *) NULL) ||
529 (q == (Quantum *) NULL))
531 for (x=0; x < (ssize_t) image->columns; x++)
533 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
534 p+=GetPixelChannels(canvas_image);
535 q+=GetPixelChannels(image);
537 if (SyncAuthenticPixels(image,exception) == MagickFalse)
540 count=ReadBlob(image,length,pixels);
542 if (image->previous == (Image *) NULL)
544 status=SetImageProgress(image,LoadImageTag,3,6);
545 if (status == MagickFalse)
548 for (y=0; y < (ssize_t) image->extract_info.height; y++)
550 register const Quantum
559 if (count != (ssize_t) length)
561 ThrowFileException(exception,CorruptImageError,
562 "UnexpectedEndOfFile",image->filename);
565 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
567 if (q == (Quantum *) NULL)
569 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
570 quantum_info,BlackQuantum,pixels,exception);
571 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
573 if (((y-image->extract_info.y) >= 0) &&
574 ((y-image->extract_info.y) < (ssize_t) image->rows))
576 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
577 canvas_image->columns,1,exception);
578 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
579 image->columns,1,exception);
580 if ((p == (const Quantum *) NULL) ||
581 (q == (Quantum *) NULL))
583 for (x=0; x < (ssize_t) image->columns; x++)
585 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
586 p+=GetPixelChannels(canvas_image);
587 q+=GetPixelChannels(image);
589 if (SyncAuthenticPixels(image,exception) == MagickFalse)
592 count=ReadBlob(image,length,pixels);
594 if (image->previous == (Image *) NULL)
596 status=SetImageProgress(image,LoadImageTag,4,6);
597 if (status == MagickFalse)
600 if (image->matte != MagickFalse)
602 for (y=0; y < (ssize_t) image->extract_info.height; y++)
604 register const Quantum
613 if (count != (ssize_t) length)
615 ThrowFileException(exception,CorruptImageError,
616 "UnexpectedEndOfFile",image->filename);
619 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
621 if (q == (Quantum *) NULL)
623 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
624 quantum_info,AlphaQuantum,pixels,exception);
625 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
627 if (((y-image->extract_info.y) >= 0) &&
628 ((y-image->extract_info.y) < (ssize_t) image->rows))
630 p=GetVirtualPixels(canvas_image,
631 canvas_image->extract_info.x,0,canvas_image->columns,1,
633 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
634 image->columns,1,exception);
635 if ((p == (const Quantum *) NULL) ||
636 (q == (Quantum *) NULL))
638 for (x=0; x < (ssize_t) image->columns; x++)
640 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
641 p+=GetPixelChannels(canvas_image);
642 q+=GetPixelChannels(image);
644 if (SyncAuthenticPixels(image,exception) == MagickFalse)
647 count=ReadBlob(image,length,pixels);
649 if (image->previous == (Image *) NULL)
651 status=SetImageProgress(image,LoadImageTag,5,6);
652 if (status == MagickFalse)
656 if (image->previous == (Image *) NULL)
658 status=SetImageProgress(image,LoadImageTag,6,6);
659 if (status == MagickFalse)
664 case PartitionInterlace:
667 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
669 AppendImageFormat("C",image->filename);
670 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
671 if (status == MagickFalse)
673 canvas_image=DestroyImageList(canvas_image);
674 image=DestroyImageList(image);
675 return((Image *) NULL);
677 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
678 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
680 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
681 for (i=0; i < (ssize_t) scene; i++)
682 for (y=0; y < (ssize_t) image->extract_info.height; y++)
683 if (ReadBlob(image,length,pixels) != (ssize_t) length)
685 ThrowFileException(exception,CorruptImageError,
686 "UnexpectedEndOfFile",image->filename);
689 count=ReadBlob(image,length,pixels);
690 for (y=0; y < (ssize_t) image->extract_info.height; y++)
692 register const Quantum
701 if (count != (ssize_t) length)
703 ThrowFileException(exception,CorruptImageError,
704 "UnexpectedEndOfFile",image->filename);
707 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
709 if (q == (Quantum *) NULL)
711 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
712 quantum_info,CyanQuantum,pixels,exception);
713 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
715 if (((y-image->extract_info.y) >= 0) &&
716 ((y-image->extract_info.y) < (ssize_t) image->rows))
718 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
719 canvas_image->columns,1,exception);
720 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
721 image->columns,1,exception);
722 if ((p == (const Quantum *) NULL) ||
723 (q == (Quantum *) NULL))
725 for (x=0; x < (ssize_t) image->columns; x++)
727 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
728 p+=GetPixelChannels(canvas_image);
729 q+=GetPixelChannels(image);
731 if (SyncAuthenticPixels(image,exception) == MagickFalse)
734 count=ReadBlob(image,length,pixels);
736 if (image->previous == (Image *) NULL)
738 status=SetImageProgress(image,LoadImageTag,1,5);
739 if (status == MagickFalse)
742 (void) CloseBlob(image);
743 AppendImageFormat("M",image->filename);
744 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
745 if (status == MagickFalse)
747 canvas_image=DestroyImageList(canvas_image);
748 image=DestroyImageList(image);
749 return((Image *) NULL);
751 length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
752 for (i=0; i < (ssize_t) scene; i++)
753 for (y=0; y < (ssize_t) image->extract_info.height; y++)
754 if (ReadBlob(image,length,pixels) != (ssize_t) length)
756 ThrowFileException(exception,CorruptImageError,
757 "UnexpectedEndOfFile",image->filename);
760 count=ReadBlob(image,length,pixels);
761 for (y=0; y < (ssize_t) image->extract_info.height; y++)
763 register const Quantum
772 if (count != (ssize_t) length)
774 ThrowFileException(exception,CorruptImageError,
775 "UnexpectedEndOfFile",image->filename);
778 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
780 if (q == (Quantum *) NULL)
782 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
783 quantum_info,MagentaQuantum,pixels,exception);
784 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
786 if (((y-image->extract_info.y) >= 0) &&
787 ((y-image->extract_info.y) < (ssize_t) image->rows))
789 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
790 canvas_image->columns,1,exception);
791 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
792 image->columns,1,exception);
793 if ((p == (const Quantum *) NULL) ||
794 (q == (Quantum *) NULL))
796 for (x=0; x < (ssize_t) image->columns; x++)
798 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
799 p+=GetPixelChannels(canvas_image);
800 q+=GetPixelChannels(image);
802 if (SyncAuthenticPixels(image,exception) == MagickFalse)
805 count=ReadBlob(image,length,pixels);
807 if (image->previous == (Image *) NULL)
809 status=SetImageProgress(image,LoadImageTag,2,5);
810 if (status == MagickFalse)
813 (void) CloseBlob(image);
814 AppendImageFormat("Y",image->filename);
815 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
816 if (status == MagickFalse)
818 canvas_image=DestroyImageList(canvas_image);
819 image=DestroyImageList(image);
820 return((Image *) NULL);
822 length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
823 for (i=0; i < (ssize_t) scene; i++)
824 for (y=0; y < (ssize_t) image->extract_info.height; y++)
825 if (ReadBlob(image,length,pixels) != (ssize_t) length)
827 ThrowFileException(exception,CorruptImageError,
828 "UnexpectedEndOfFile",image->filename);
831 count=ReadBlob(image,length,pixels);
832 for (y=0; y < (ssize_t) image->extract_info.height; y++)
834 register const Quantum
843 if (count != (ssize_t) length)
845 ThrowFileException(exception,CorruptImageError,
846 "UnexpectedEndOfFile",image->filename);
849 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
851 if (q == (Quantum *) NULL)
853 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
854 quantum_info,YellowQuantum,pixels,exception);
855 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
857 if (((y-image->extract_info.y) >= 0) &&
858 ((y-image->extract_info.y) < (ssize_t) image->rows))
860 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
861 canvas_image->columns,1,exception);
862 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
863 image->columns,1,exception);
864 if ((p == (const Quantum *) NULL) ||
865 (q == (Quantum *) NULL))
867 for (x=0; x < (ssize_t) image->columns; x++)
869 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
870 p+=GetPixelChannels(canvas_image);
871 q+=GetPixelChannels(image);
873 if (SyncAuthenticPixels(image,exception) == MagickFalse)
876 count=ReadBlob(image,length,pixels);
878 if (image->previous == (Image *) NULL)
880 status=SetImageProgress(image,LoadImageTag,3,5);
881 if (status == MagickFalse)
884 (void) CloseBlob(image);
885 AppendImageFormat("K",image->filename);
886 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
887 if (status == MagickFalse)
889 canvas_image=DestroyImageList(canvas_image);
890 image=DestroyImageList(image);
891 return((Image *) NULL);
893 length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
894 for (i=0; i < (ssize_t) scene; i++)
895 for (y=0; y < (ssize_t) image->extract_info.height; y++)
896 if (ReadBlob(image,length,pixels) != (ssize_t) length)
898 ThrowFileException(exception,CorruptImageError,
899 "UnexpectedEndOfFile",image->filename);
902 count=ReadBlob(image,length,pixels);
903 for (y=0; y < (ssize_t) image->extract_info.height; y++)
905 register const Quantum
914 if (count != (ssize_t) length)
916 ThrowFileException(exception,CorruptImageError,
917 "UnexpectedEndOfFile",image->filename);
920 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
922 if (q == (Quantum *) NULL)
924 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
925 quantum_info,BlackQuantum,pixels,exception);
926 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
928 if (((y-image->extract_info.y) >= 0) &&
929 ((y-image->extract_info.y) < (ssize_t) image->rows))
931 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
932 canvas_image->columns,1,exception);
933 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
934 image->columns,1,exception);
935 if ((p == (const Quantum *) NULL) ||
936 (q == (Quantum *) NULL))
938 for (x=0; x < (ssize_t) image->columns; x++)
940 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
941 p+=GetPixelChannels(canvas_image);
942 q+=GetPixelChannels(image);
944 if (SyncAuthenticPixels(image,exception) == MagickFalse)
947 count=ReadBlob(image,length,pixels);
949 if (image->previous == (Image *) NULL)
951 status=SetImageProgress(image,LoadImageTag,3,5);
952 if (status == MagickFalse)
955 if (image->matte != MagickFalse)
957 (void) CloseBlob(image);
958 AppendImageFormat("A",image->filename);
959 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
960 if (status == MagickFalse)
962 canvas_image=DestroyImageList(canvas_image);
963 image=DestroyImageList(image);
964 return((Image *) NULL);
966 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
967 for (i=0; i < (ssize_t) scene; i++)
968 for (y=0; y < (ssize_t) image->extract_info.height; y++)
969 if (ReadBlob(image,length,pixels) != (ssize_t) length)
971 ThrowFileException(exception,CorruptImageError,
972 "UnexpectedEndOfFile",image->filename);
975 count=ReadBlob(image,length,pixels);
976 for (y=0; y < (ssize_t) image->extract_info.height; y++)
978 register const Quantum
987 if (count != (ssize_t) length)
989 ThrowFileException(exception,CorruptImageError,
990 "UnexpectedEndOfFile",image->filename);
993 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
995 if (q == (Quantum *) NULL)
997 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
998 quantum_info,YellowQuantum,pixels,exception);
999 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1001 if (((y-image->extract_info.y) >= 0) &&
1002 ((y-image->extract_info.y) < (ssize_t) image->rows))
1004 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
1005 0,canvas_image->columns,1,exception);
1006 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
1007 image->columns,1,exception);
1008 if ((p == (const Quantum *) NULL) ||
1009 (q == (Quantum *) NULL))
1011 for (x=0; x < (ssize_t) image->columns; x++)
1013 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1014 p+=GetPixelChannels(canvas_image);
1015 q+=GetPixelChannels(image);
1017 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1020 count=ReadBlob(image,length,pixels);
1022 if (image->previous == (Image *) NULL)
1024 status=SetImageProgress(image,LoadImageTag,4,5);
1025 if (status == MagickFalse)
1029 if (image->previous == (Image *) NULL)
1031 status=SetImageProgress(image,LoadImageTag,5,5);
1032 if (status == MagickFalse)
1038 SetQuantumImageType(image,quantum_type);
1040 Proceed to next image.
1042 if (image_info->number_scenes != 0)
1043 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1045 if (count == (ssize_t) length)
1048 Allocate next image structure.
1050 AcquireNextImage(image_info,image,exception);
1051 if (GetNextImageInList(image) == (Image *) NULL)
1053 image=DestroyImageList(image);
1054 return((Image *) NULL);
1056 image=SyncNextImageInList(image);
1057 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1058 GetBlobSize(image));
1059 if (status == MagickFalse)
1063 } while (count == (ssize_t) length);
1064 quantum_info=DestroyQuantumInfo(quantum_info);
1065 canvas_image=DestroyImage(canvas_image);
1066 (void) CloseBlob(image);
1067 return(GetFirstImageInList(image));
1071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1075 % R e g i s t e r C M Y K I m a g e %
1079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 % RegisterCMYKImage() adds attributes for the CMYK image format to
1082 % the list of supported formats. The attributes include the image format
1083 % tag, a method to read and/or write the format, whether the format
1084 % supports the saving of more than one frame to the same file or blob,
1085 % whether the format supports native in-memory I/O, and a brief
1086 % description of the format.
1088 % The format of the RegisterCMYKImage method is:
1090 % size_t RegisterCMYKImage(void)
1093 ModuleExport size_t RegisterCMYKImage(void)
1098 entry=SetMagickInfo("CMYK");
1099 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1100 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1101 entry->raw=MagickTrue;
1102 entry->endian_support=MagickTrue;
1103 entry->description=ConstantString("Raw cyan, magenta, yellow, and black "
1105 entry->module=ConstantString("CMYK");
1106 (void) RegisterMagickInfo(entry);
1107 entry=SetMagickInfo("CMYKA");
1108 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1109 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1110 entry->raw=MagickTrue;
1111 entry->endian_support=MagickTrue;
1112 entry->description=ConstantString("Raw cyan, magenta, yellow, black, and "
1114 entry->module=ConstantString("CMYK");
1115 (void) RegisterMagickInfo(entry);
1116 return(MagickImageCoderSignature);
1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 % U n r e g i s t e r C M Y K I m a g e %
1128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130 % UnregisterCMYKImage() removes format registrations made by the
1131 % CMYK module from the list of supported formats.
1133 % The format of the UnregisterCMYKImage method is:
1135 % UnregisterCMYKImage(void)
1138 ModuleExport void UnregisterCMYKImage(void)
1140 (void) UnregisterMagickInfo("CMYK");
1141 (void) UnregisterMagickInfo("CMYKA");
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149 % W r i t e C M Y K I m a g e %
1153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 % WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1156 % black,rasterfile format.
1158 % The format of the WriteCMYKImage method is:
1160 % MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1161 % Image *image,ExceptionInfo *exception)
1163 % A description of each parameter follows.
1165 % o image_info: the image info.
1167 % o image: The image.
1169 % o exception: return any errors or warnings in this structure.
1172 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1173 Image *image,ExceptionInfo *exception)
1198 Allocate memory for pixels.
1200 assert(image_info != (const ImageInfo *) NULL);
1201 assert(image_info->signature == MagickSignature);
1202 assert(image != (Image *) NULL);
1203 assert(image->signature == MagickSignature);
1204 if (image->debug != MagickFalse)
1205 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1206 if (image_info->interlace != PartitionInterlace)
1209 Open output image file.
1211 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1212 if (status == MagickFalse)
1219 Convert MIFF to CMYK raster pixels.
1221 if (image->colorspace != CMYKColorspace)
1222 (void) TransformImageColorspace(image,CMYKColorspace,exception);
1223 quantum_type=CMYKQuantum;
1224 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1226 quantum_type=CMYKAQuantum;
1227 if (image->matte == MagickFalse)
1228 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1230 quantum_info=AcquireQuantumInfo(image_info,image);
1231 if (quantum_info == (QuantumInfo *) NULL)
1232 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1233 pixels=GetQuantumPixels(quantum_info);
1234 switch (image_info->interlace)
1240 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
1242 for (y=0; y < (ssize_t) image->rows; y++)
1244 register const Quantum
1247 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1248 if (p == (const Quantum *) NULL)
1250 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1251 quantum_type,pixels,exception);
1252 count=WriteBlob(image,length,pixels);
1253 if (count != (ssize_t) length)
1255 if (image->previous == (Image *) NULL)
1257 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1259 if (status == MagickFalse)
1268 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1270 for (y=0; y < (ssize_t) image->rows; y++)
1272 register const Quantum
1275 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1276 if (p == (const Quantum *) NULL)
1278 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1279 CyanQuantum,pixels,exception);
1280 count=WriteBlob(image,length,pixels);
1281 if (count != (ssize_t) length)
1283 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1284 MagentaQuantum,pixels,exception);
1285 count=WriteBlob(image,length,pixels);
1286 if (count != (ssize_t) length)
1288 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1289 YellowQuantum,pixels,exception);
1290 count=WriteBlob(image,length,pixels);
1291 if (count != (ssize_t) length)
1293 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1294 BlackQuantum,pixels,exception);
1295 count=WriteBlob(image,length,pixels);
1296 if (count != (ssize_t) length)
1298 if (quantum_type == CMYKAQuantum)
1300 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1301 AlphaQuantum,pixels,exception);
1302 count=WriteBlob(image,length,pixels);
1303 if (count != (ssize_t) length)
1306 if (image->previous == (Image *) NULL)
1308 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1310 if (status == MagickFalse)
1316 case PlaneInterlace:
1319 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1321 for (y=0; y < (ssize_t) image->rows; y++)
1323 register const Quantum
1326 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1327 if (p == (const Quantum *) NULL)
1329 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1330 CyanQuantum,pixels,exception);
1331 count=WriteBlob(image,length,pixels);
1332 if (count != (ssize_t) length)
1335 if (image->previous == (Image *) NULL)
1337 status=SetImageProgress(image,SaveImageTag,1,6);
1338 if (status == MagickFalse)
1341 for (y=0; y < (ssize_t) image->rows; y++)
1343 register const Quantum
1346 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1347 if (p == (const Quantum *) NULL)
1349 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1350 MagentaQuantum,pixels,exception);
1351 count=WriteBlob(image,length,pixels);
1352 if (count != (ssize_t) length)
1355 if (image->previous == (Image *) NULL)
1357 status=SetImageProgress(image,SaveImageTag,2,6);
1358 if (status == MagickFalse)
1361 for (y=0; y < (ssize_t) image->rows; y++)
1363 register const Quantum
1366 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1367 if (p == (const Quantum *) NULL)
1369 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1370 YellowQuantum,pixels,exception);
1371 count=WriteBlob(image,length,pixels);
1372 if (count != (ssize_t) length)
1375 if (image->previous == (Image *) NULL)
1377 status=SetImageProgress(image,SaveImageTag,3,6);
1378 if (status == MagickFalse)
1381 for (y=0; y < (ssize_t) image->rows; y++)
1383 register const Quantum
1386 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1387 if (p == (const Quantum *) NULL)
1389 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1390 BlackQuantum,pixels,exception);
1391 count=WriteBlob(image,length,pixels);
1392 if (count != (ssize_t) length)
1395 if (image->previous == (Image *) NULL)
1397 status=SetImageProgress(image,SaveImageTag,4,6);
1398 if (status == MagickFalse)
1401 if (quantum_type == CMYKAQuantum)
1403 for (y=0; y < (ssize_t) image->rows; y++)
1405 register const Quantum
1408 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1409 if (p == (const Quantum *) NULL)
1411 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1412 AlphaQuantum,pixels,exception);
1413 count=WriteBlob(image,length,pixels);
1414 if (count != (ssize_t) length)
1417 if (image->previous == (Image *) NULL)
1419 status=SetImageProgress(image,SaveImageTag,5,6);
1420 if (status == MagickFalse)
1424 if (image_info->interlace == PartitionInterlace)
1425 (void) CopyMagickString(image->filename,image_info->filename,
1427 if (image->previous == (Image *) NULL)
1429 status=SetImageProgress(image,SaveImageTag,6,6);
1430 if (status == MagickFalse)
1435 case PartitionInterlace:
1438 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1440 AppendImageFormat("C",image->filename);
1441 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1442 AppendBinaryBlobMode,exception);
1443 if (status == MagickFalse)
1445 for (y=0; y < (ssize_t) image->rows; y++)
1447 register const Quantum
1450 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1451 if (p == (const Quantum *) NULL)
1453 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1454 CyanQuantum,pixels,exception);
1455 count=WriteBlob(image,length,pixels);
1456 if (count != (ssize_t) length)
1459 if (image->previous == (Image *) NULL)
1461 status=SetImageProgress(image,SaveImageTag,1,6);
1462 if (status == MagickFalse)
1465 (void) CloseBlob(image);
1466 AppendImageFormat("M",image->filename);
1467 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1468 AppendBinaryBlobMode,exception);
1469 if (status == MagickFalse)
1471 for (y=0; y < (ssize_t) image->rows; y++)
1473 register const Quantum
1476 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1477 if (p == (const Quantum *) NULL)
1479 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1480 MagentaQuantum,pixels,exception);
1481 count=WriteBlob(image,length,pixels);
1482 if (count != (ssize_t) length)
1485 if (image->previous == (Image *) NULL)
1487 status=SetImageProgress(image,SaveImageTag,2,6);
1488 if (status == MagickFalse)
1491 (void) CloseBlob(image);
1492 AppendImageFormat("Y",image->filename);
1493 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1494 AppendBinaryBlobMode,exception);
1495 if (status == MagickFalse)
1497 for (y=0; y < (ssize_t) image->rows; y++)
1499 register const Quantum
1502 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1503 if (p == (const Quantum *) NULL)
1505 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1506 YellowQuantum,pixels,exception);
1507 count=WriteBlob(image,length,pixels);
1508 if (count != (ssize_t) length)
1511 if (image->previous == (Image *) NULL)
1513 status=SetImageProgress(image,SaveImageTag,3,6);
1514 if (status == MagickFalse)
1517 (void) CloseBlob(image);
1518 AppendImageFormat("K",image->filename);
1519 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1520 AppendBinaryBlobMode,exception);
1521 if (status == MagickFalse)
1523 for (y=0; y < (ssize_t) image->rows; y++)
1525 register const Quantum
1528 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1529 if (p == (const Quantum *) NULL)
1531 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1532 BlackQuantum,pixels,exception);
1533 count=WriteBlob(image,length,pixels);
1534 if (count != (ssize_t) length)
1537 if (image->previous == (Image *) NULL)
1539 status=SetImageProgress(image,SaveImageTag,4,6);
1540 if (status == MagickFalse)
1543 if (quantum_type == CMYKAQuantum)
1545 (void) CloseBlob(image);
1546 AppendImageFormat("A",image->filename);
1547 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1548 AppendBinaryBlobMode,exception);
1549 if (status == MagickFalse)
1551 for (y=0; y < (ssize_t) image->rows; y++)
1553 register const Quantum
1556 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1557 if (p == (const Quantum *) NULL)
1559 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1560 AlphaQuantum,pixels,exception);
1561 count=WriteBlob(image,length,pixels);
1562 if (count != (ssize_t) length)
1565 if (image->previous == (Image *) NULL)
1567 status=SetImageProgress(image,SaveImageTag,5,6);
1568 if (status == MagickFalse)
1572 (void) CloseBlob(image);
1573 (void) CopyMagickString(image->filename,image_info->filename,
1575 if (image->previous == (Image *) NULL)
1577 status=SetImageProgress(image,SaveImageTag,6,6);
1578 if (status == MagickFalse)
1584 quantum_info=DestroyQuantumInfo(quantum_info);
1585 if (GetNextImageInList(image) == (Image *) NULL)
1587 image=SyncNextImageInList(image);
1588 status=SetImageProgress(image,SaveImagesTag,scene++,
1589 GetImageListLength(image));
1590 if (status == MagickFalse)
1592 } while (image_info->adjoin != MagickFalse);
1593 (void) CloseBlob(image);