2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write RAW CMYK Image Format %
20 % Copyright 1999-2013 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/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"
69 static MagickBooleanType
70 WriteCMYKImage(const ImageInfo *,Image *,ExceptionInfo *);
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 % R e a d C M Y K I m a g e %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
87 % The format of the ReadCMYKImage method is:
89 % Image *ReadCMYKImage(const ImageInfo *image_info,
90 % ExceptionInfo *exception)
92 % A description of each parameter follows:
94 % o image_info: the image info.
96 % o exception: return any errors or warnings in this structure.
99 static Image *ReadCMYKImage(const ImageInfo *image_info,
100 ExceptionInfo *exception)
134 assert(image_info != (const ImageInfo *) NULL);
135 assert(image_info->signature == MagickSignature);
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 == MagickSignature);
141 image=AcquireImage(image_info,exception);
142 if ((image->columns == 0) || (image->rows == 0))
143 ThrowReaderException(OptionError,"MustSpecifyImageSize");
144 SetImageColorspace(image,CMYKColorspace,exception);
145 if (image_info->interlace != PartitionInterlace)
147 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
148 if (status == MagickFalse)
150 image=DestroyImageList(image);
151 return((Image *) NULL);
153 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
154 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
158 Create virtual canvas to support cropping (i.e. image.cmyk[100x100+10+20]).
160 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
162 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
164 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
165 if (quantum_info == (QuantumInfo *) NULL)
166 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
167 pixels=GetQuantumPixels(quantum_info);
168 quantum_type=CMYKQuantum;
169 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
171 quantum_type=CMYKAQuantum;
172 image->alpha_trait=BlendPixelTrait;
174 if (image_info->number_scenes != 0)
175 while (image->scene < image_info->scene)
181 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
182 for (y=0; y < (ssize_t) image->rows; y++)
184 count=ReadBlob(image,length,pixels);
185 if (count != (ssize_t) length)
195 Read pixels to virtual canvas image then push to image.
197 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
198 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
200 SetImageColorspace(image,CMYKColorspace,exception);
201 switch (image_info->interlace)
207 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
211 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
212 count=ReadBlob(image,length,pixels);
214 for (y=0; y < (ssize_t) image->extract_info.height; y++)
216 register const Quantum
225 if (count != (ssize_t) length)
227 ThrowFileException(exception,CorruptImageError,
228 "UnexpectedEndOfFile",image->filename);
231 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
233 if (q == (Quantum *) NULL)
235 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
236 quantum_info,quantum_type,pixels,exception);
237 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
239 if (((y-image->extract_info.y) >= 0) &&
240 ((y-image->extract_info.y) < (ssize_t) image->rows))
242 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
243 canvas_image->columns,1,exception);
244 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
245 image->columns,1,exception);
246 if ((p == (const Quantum *) NULL) ||
247 (q == (Quantum *) NULL))
249 for (x=0; x < (ssize_t) image->columns; x++)
251 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
252 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
253 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
254 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
255 SetPixelAlpha(image,OpaqueAlpha,q);
256 if (image->alpha_trait == BlendPixelTrait)
257 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
258 p+=GetPixelChannels(canvas_image);
259 q+=GetPixelChannels(image);
261 if (SyncAuthenticPixels(image,exception) == MagickFalse)
264 if (image->previous == (Image *) NULL)
266 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
268 if (status == MagickFalse)
271 count=ReadBlob(image,length,pixels);
288 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
292 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
293 count=ReadBlob(image,length,pixels);
295 for (y=0; y < (ssize_t) image->extract_info.height; y++)
297 register const Quantum
306 if (count != (ssize_t) length)
308 ThrowFileException(exception,CorruptImageError,
309 "UnexpectedEndOfFile",image->filename);
312 for (i=0; i < (image->alpha_trait == BlendPixelTrait ? 5 : 4); i++)
314 quantum_type=quantum_types[i];
315 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
317 if (q == (Quantum *) NULL)
319 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
320 quantum_info,quantum_type,pixels,exception);
321 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
323 if (((y-image->extract_info.y) >= 0) &&
324 ((y-image->extract_info.y) < (ssize_t) image->rows))
326 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
327 0,canvas_image->columns,1,exception);
328 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
329 image->columns,1,exception);
330 if ((p == (const Quantum *) NULL) ||
331 (q == (Quantum *) NULL))
333 for (x=0; x < (ssize_t) image->columns; x++)
335 switch (quantum_type)
339 SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
344 SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
349 SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
354 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
359 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
365 p+=GetPixelChannels(canvas_image);
366 q+=GetPixelChannels(image);
368 if (SyncAuthenticPixels(image,exception) == MagickFalse)
371 count=ReadBlob(image,length,pixels);
373 if (image->previous == (Image *) NULL)
375 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
377 if (status == MagickFalse)
386 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
390 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
391 count=ReadBlob(image,length,pixels);
393 for (y=0; y < (ssize_t) image->extract_info.height; y++)
395 register const Quantum
404 if (count != (ssize_t) length)
406 ThrowFileException(exception,CorruptImageError,
407 "UnexpectedEndOfFile",image->filename);
410 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
412 if (q == (Quantum *) NULL)
414 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
415 quantum_info,CyanQuantum,pixels,exception);
416 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
418 if (((y-image->extract_info.y) >= 0) &&
419 ((y-image->extract_info.y) < (ssize_t) image->rows))
421 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
422 canvas_image->columns,1,exception);
423 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
424 image->columns,1,exception);
425 if ((p == (const Quantum *) NULL) ||
426 (q == (Quantum *) NULL))
428 for (x=0; x < (ssize_t) image->columns; x++)
430 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
431 p+=GetPixelChannels(canvas_image);
432 q+=GetPixelChannels(image);
434 if (SyncAuthenticPixels(image,exception) == MagickFalse)
437 count=ReadBlob(image,length,pixels);
439 if (image->previous == (Image *) NULL)
441 status=SetImageProgress(image,LoadImageTag,1,6);
442 if (status == MagickFalse)
445 for (y=0; y < (ssize_t) image->extract_info.height; y++)
447 register const Quantum
456 if (count != (ssize_t) length)
458 ThrowFileException(exception,CorruptImageError,
459 "UnexpectedEndOfFile",image->filename);
462 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
464 if (q == (Quantum *) NULL)
466 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
467 quantum_info,MagentaQuantum,pixels,exception);
468 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
470 if (((y-image->extract_info.y) >= 0) &&
471 ((y-image->extract_info.y) < (ssize_t) image->rows))
473 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
474 canvas_image->columns,1,exception);
475 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
476 image->columns,1,exception);
477 if ((p == (const Quantum *) NULL) ||
478 (q == (Quantum *) NULL))
480 for (x=0; x < (ssize_t) image->columns; x++)
482 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
483 p+=GetPixelChannels(canvas_image);
484 q+=GetPixelChannels(image);
486 if (SyncAuthenticPixels(image,exception) == MagickFalse)
489 count=ReadBlob(image,length,pixels);
491 if (image->previous == (Image *) NULL)
493 status=SetImageProgress(image,LoadImageTag,2,6);
494 if (status == MagickFalse)
497 for (y=0; y < (ssize_t) image->extract_info.height; y++)
499 register const Quantum
508 if (count != (ssize_t) length)
510 ThrowFileException(exception,CorruptImageError,
511 "UnexpectedEndOfFile",image->filename);
514 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
516 if (q == (Quantum *) NULL)
518 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
519 quantum_info,YellowQuantum,pixels,exception);
520 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
522 if (((y-image->extract_info.y) >= 0) &&
523 ((y-image->extract_info.y) < (ssize_t) image->rows))
525 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
526 canvas_image->columns,1,exception);
527 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
528 image->columns,1,exception);
529 if ((p == (const Quantum *) NULL) ||
530 (q == (Quantum *) NULL))
532 for (x=0; x < (ssize_t) image->columns; x++)
534 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
535 p+=GetPixelChannels(canvas_image);
536 q+=GetPixelChannels(image);
538 if (SyncAuthenticPixels(image,exception) == MagickFalse)
541 count=ReadBlob(image,length,pixels);
543 if (image->previous == (Image *) NULL)
545 status=SetImageProgress(image,LoadImageTag,3,6);
546 if (status == MagickFalse)
549 for (y=0; y < (ssize_t) image->extract_info.height; y++)
551 register const Quantum
560 if (count != (ssize_t) length)
562 ThrowFileException(exception,CorruptImageError,
563 "UnexpectedEndOfFile",image->filename);
566 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
568 if (q == (Quantum *) NULL)
570 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
571 quantum_info,BlackQuantum,pixels,exception);
572 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
574 if (((y-image->extract_info.y) >= 0) &&
575 ((y-image->extract_info.y) < (ssize_t) image->rows))
577 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
578 canvas_image->columns,1,exception);
579 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
580 image->columns,1,exception);
581 if ((p == (const Quantum *) NULL) ||
582 (q == (Quantum *) NULL))
584 for (x=0; x < (ssize_t) image->columns; x++)
586 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
587 p+=GetPixelChannels(canvas_image);
588 q+=GetPixelChannels(image);
590 if (SyncAuthenticPixels(image,exception) == MagickFalse)
593 count=ReadBlob(image,length,pixels);
595 if (image->previous == (Image *) NULL)
597 status=SetImageProgress(image,LoadImageTag,4,6);
598 if (status == MagickFalse)
601 if (image->alpha_trait == BlendPixelTrait)
603 for (y=0; y < (ssize_t) image->extract_info.height; y++)
605 register const Quantum
614 if (count != (ssize_t) length)
616 ThrowFileException(exception,CorruptImageError,
617 "UnexpectedEndOfFile",image->filename);
620 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
622 if (q == (Quantum *) NULL)
624 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
625 quantum_info,AlphaQuantum,pixels,exception);
626 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
628 if (((y-image->extract_info.y) >= 0) &&
629 ((y-image->extract_info.y) < (ssize_t) image->rows))
631 p=GetVirtualPixels(canvas_image,
632 canvas_image->extract_info.x,0,canvas_image->columns,1,
634 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
635 image->columns,1,exception);
636 if ((p == (const Quantum *) NULL) ||
637 (q == (Quantum *) NULL))
639 for (x=0; x < (ssize_t) image->columns; x++)
641 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
642 p+=GetPixelChannels(canvas_image);
643 q+=GetPixelChannels(image);
645 if (SyncAuthenticPixels(image,exception) == MagickFalse)
648 count=ReadBlob(image,length,pixels);
650 if (image->previous == (Image *) NULL)
652 status=SetImageProgress(image,LoadImageTag,5,6);
653 if (status == MagickFalse)
657 if (image->previous == (Image *) NULL)
659 status=SetImageProgress(image,LoadImageTag,6,6);
660 if (status == MagickFalse)
665 case PartitionInterlace:
668 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
670 AppendImageFormat("C",image->filename);
671 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
672 if (status == MagickFalse)
674 canvas_image=DestroyImageList(canvas_image);
675 image=DestroyImageList(image);
676 return((Image *) NULL);
678 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
679 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
681 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
682 for (i=0; i < (ssize_t) scene; i++)
683 for (y=0; y < (ssize_t) image->extract_info.height; y++)
684 if (ReadBlob(image,length,pixels) != (ssize_t) length)
686 ThrowFileException(exception,CorruptImageError,
687 "UnexpectedEndOfFile",image->filename);
690 count=ReadBlob(image,length,pixels);
691 for (y=0; y < (ssize_t) image->extract_info.height; y++)
693 register const Quantum
702 if (count != (ssize_t) length)
704 ThrowFileException(exception,CorruptImageError,
705 "UnexpectedEndOfFile",image->filename);
708 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
710 if (q == (Quantum *) NULL)
712 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
713 quantum_info,CyanQuantum,pixels,exception);
714 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
716 if (((y-image->extract_info.y) >= 0) &&
717 ((y-image->extract_info.y) < (ssize_t) image->rows))
719 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
720 canvas_image->columns,1,exception);
721 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
722 image->columns,1,exception);
723 if ((p == (const Quantum *) NULL) ||
724 (q == (Quantum *) NULL))
726 for (x=0; x < (ssize_t) image->columns; x++)
728 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
729 p+=GetPixelChannels(canvas_image);
730 q+=GetPixelChannels(image);
732 if (SyncAuthenticPixels(image,exception) == MagickFalse)
735 count=ReadBlob(image,length,pixels);
737 if (image->previous == (Image *) NULL)
739 status=SetImageProgress(image,LoadImageTag,1,5);
740 if (status == MagickFalse)
743 (void) CloseBlob(image);
744 AppendImageFormat("M",image->filename);
745 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
746 if (status == MagickFalse)
748 canvas_image=DestroyImageList(canvas_image);
749 image=DestroyImageList(image);
750 return((Image *) NULL);
752 length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
753 for (i=0; i < (ssize_t) scene; i++)
754 for (y=0; y < (ssize_t) image->extract_info.height; y++)
755 if (ReadBlob(image,length,pixels) != (ssize_t) length)
757 ThrowFileException(exception,CorruptImageError,
758 "UnexpectedEndOfFile",image->filename);
761 count=ReadBlob(image,length,pixels);
762 for (y=0; y < (ssize_t) image->extract_info.height; y++)
764 register const Quantum
773 if (count != (ssize_t) length)
775 ThrowFileException(exception,CorruptImageError,
776 "UnexpectedEndOfFile",image->filename);
779 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
781 if (q == (Quantum *) NULL)
783 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
784 quantum_info,MagentaQuantum,pixels,exception);
785 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
787 if (((y-image->extract_info.y) >= 0) &&
788 ((y-image->extract_info.y) < (ssize_t) image->rows))
790 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
791 canvas_image->columns,1,exception);
792 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
793 image->columns,1,exception);
794 if ((p == (const Quantum *) NULL) ||
795 (q == (Quantum *) NULL))
797 for (x=0; x < (ssize_t) image->columns; x++)
799 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
800 p+=GetPixelChannels(canvas_image);
801 q+=GetPixelChannels(image);
803 if (SyncAuthenticPixels(image,exception) == MagickFalse)
806 count=ReadBlob(image,length,pixels);
808 if (image->previous == (Image *) NULL)
810 status=SetImageProgress(image,LoadImageTag,2,5);
811 if (status == MagickFalse)
814 (void) CloseBlob(image);
815 AppendImageFormat("Y",image->filename);
816 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
817 if (status == MagickFalse)
819 canvas_image=DestroyImageList(canvas_image);
820 image=DestroyImageList(image);
821 return((Image *) NULL);
823 length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
824 for (i=0; i < (ssize_t) scene; i++)
825 for (y=0; y < (ssize_t) image->extract_info.height; y++)
826 if (ReadBlob(image,length,pixels) != (ssize_t) length)
828 ThrowFileException(exception,CorruptImageError,
829 "UnexpectedEndOfFile",image->filename);
832 count=ReadBlob(image,length,pixels);
833 for (y=0; y < (ssize_t) image->extract_info.height; y++)
835 register const Quantum
844 if (count != (ssize_t) length)
846 ThrowFileException(exception,CorruptImageError,
847 "UnexpectedEndOfFile",image->filename);
850 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
852 if (q == (Quantum *) NULL)
854 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
855 quantum_info,YellowQuantum,pixels,exception);
856 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
858 if (((y-image->extract_info.y) >= 0) &&
859 ((y-image->extract_info.y) < (ssize_t) image->rows))
861 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
862 canvas_image->columns,1,exception);
863 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
864 image->columns,1,exception);
865 if ((p == (const Quantum *) NULL) ||
866 (q == (Quantum *) NULL))
868 for (x=0; x < (ssize_t) image->columns; x++)
870 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
871 p+=GetPixelChannels(canvas_image);
872 q+=GetPixelChannels(image);
874 if (SyncAuthenticPixels(image,exception) == MagickFalse)
877 count=ReadBlob(image,length,pixels);
879 if (image->previous == (Image *) NULL)
881 status=SetImageProgress(image,LoadImageTag,3,5);
882 if (status == MagickFalse)
885 (void) CloseBlob(image);
886 AppendImageFormat("K",image->filename);
887 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
888 if (status == MagickFalse)
890 canvas_image=DestroyImageList(canvas_image);
891 image=DestroyImageList(image);
892 return((Image *) NULL);
894 length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
895 for (i=0; i < (ssize_t) scene; i++)
896 for (y=0; y < (ssize_t) image->extract_info.height; y++)
897 if (ReadBlob(image,length,pixels) != (ssize_t) length)
899 ThrowFileException(exception,CorruptImageError,
900 "UnexpectedEndOfFile",image->filename);
903 count=ReadBlob(image,length,pixels);
904 for (y=0; y < (ssize_t) image->extract_info.height; y++)
906 register const Quantum
915 if (count != (ssize_t) length)
917 ThrowFileException(exception,CorruptImageError,
918 "UnexpectedEndOfFile",image->filename);
921 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
923 if (q == (Quantum *) NULL)
925 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
926 quantum_info,BlackQuantum,pixels,exception);
927 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
929 if (((y-image->extract_info.y) >= 0) &&
930 ((y-image->extract_info.y) < (ssize_t) image->rows))
932 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
933 canvas_image->columns,1,exception);
934 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
935 image->columns,1,exception);
936 if ((p == (const Quantum *) NULL) ||
937 (q == (Quantum *) NULL))
939 for (x=0; x < (ssize_t) image->columns; x++)
941 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
942 p+=GetPixelChannels(canvas_image);
943 q+=GetPixelChannels(image);
945 if (SyncAuthenticPixels(image,exception) == MagickFalse)
948 count=ReadBlob(image,length,pixels);
950 if (image->previous == (Image *) NULL)
952 status=SetImageProgress(image,LoadImageTag,3,5);
953 if (status == MagickFalse)
956 if (image->alpha_trait == BlendPixelTrait)
958 (void) CloseBlob(image);
959 AppendImageFormat("A",image->filename);
960 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
961 if (status == MagickFalse)
963 canvas_image=DestroyImageList(canvas_image);
964 image=DestroyImageList(image);
965 return((Image *) NULL);
967 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
968 for (i=0; i < (ssize_t) scene; i++)
969 for (y=0; y < (ssize_t) image->extract_info.height; y++)
970 if (ReadBlob(image,length,pixels) != (ssize_t) length)
972 ThrowFileException(exception,CorruptImageError,
973 "UnexpectedEndOfFile",image->filename);
976 count=ReadBlob(image,length,pixels);
977 for (y=0; y < (ssize_t) image->extract_info.height; y++)
979 register const Quantum
988 if (count != (ssize_t) length)
990 ThrowFileException(exception,CorruptImageError,
991 "UnexpectedEndOfFile",image->filename);
994 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
996 if (q == (Quantum *) NULL)
998 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
999 quantum_info,YellowQuantum,pixels,exception);
1000 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1002 if (((y-image->extract_info.y) >= 0) &&
1003 ((y-image->extract_info.y) < (ssize_t) image->rows))
1005 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
1006 0,canvas_image->columns,1,exception);
1007 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
1008 image->columns,1,exception);
1009 if ((p == (const Quantum *) NULL) ||
1010 (q == (Quantum *) NULL))
1012 for (x=0; x < (ssize_t) image->columns; x++)
1014 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1015 p+=GetPixelChannels(canvas_image);
1016 q+=GetPixelChannels(image);
1018 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1021 count=ReadBlob(image,length,pixels);
1023 if (image->previous == (Image *) NULL)
1025 status=SetImageProgress(image,LoadImageTag,4,5);
1026 if (status == MagickFalse)
1030 if (image->previous == (Image *) NULL)
1032 status=SetImageProgress(image,LoadImageTag,5,5);
1033 if (status == MagickFalse)
1039 SetQuantumImageType(image,quantum_type);
1041 Proceed to next image.
1043 if (image_info->number_scenes != 0)
1044 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1046 if (count == (ssize_t) length)
1049 Allocate next image structure.
1051 AcquireNextImage(image_info,image,exception);
1052 if (GetNextImageInList(image) == (Image *) NULL)
1054 image=DestroyImageList(image);
1055 return((Image *) NULL);
1057 image=SyncNextImageInList(image);
1058 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1059 GetBlobSize(image));
1060 if (status == MagickFalse)
1064 } while (count == (ssize_t) length);
1065 quantum_info=DestroyQuantumInfo(quantum_info);
1066 canvas_image=DestroyImage(canvas_image);
1067 (void) CloseBlob(image);
1068 return(GetFirstImageInList(image));
1072 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % R e g i s t e r C M Y K I m a g e %
1080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1082 % RegisterCMYKImage() adds attributes for the CMYK image format to
1083 % the list of supported formats. The attributes include the image format
1084 % tag, a method to read and/or write the format, whether the format
1085 % supports the saving of more than one frame to the same file or blob,
1086 % whether the format supports native in-memory I/O, and a brief
1087 % description of the format.
1089 % The format of the RegisterCMYKImage method is:
1091 % size_t RegisterCMYKImage(void)
1094 ModuleExport size_t RegisterCMYKImage(void)
1099 entry=SetMagickInfo("CMYK");
1100 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1101 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1102 entry->raw=MagickTrue;
1103 entry->endian_support=MagickTrue;
1104 entry->description=ConstantString("Raw cyan, magenta, yellow, and black "
1106 entry->module=ConstantString("CMYK");
1107 (void) RegisterMagickInfo(entry);
1108 entry=SetMagickInfo("CMYKA");
1109 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1110 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1111 entry->raw=MagickTrue;
1112 entry->endian_support=MagickTrue;
1113 entry->description=ConstantString("Raw cyan, magenta, yellow, black, and "
1115 entry->module=ConstantString("CMYK");
1116 (void) RegisterMagickInfo(entry);
1117 return(MagickImageCoderSignature);
1121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125 % U n r e g i s t e r C M Y K I m a g e %
1129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1131 % UnregisterCMYKImage() removes format registrations made by the
1132 % CMYK module from the list of supported formats.
1134 % The format of the UnregisterCMYKImage method is:
1136 % UnregisterCMYKImage(void)
1139 ModuleExport void UnregisterCMYKImage(void)
1141 (void) UnregisterMagickInfo("CMYK");
1142 (void) UnregisterMagickInfo("CMYKA");
1146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1150 % W r i t e C M Y K I m a g e %
1154 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1156 % WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1157 % black,rasterfile format.
1159 % The format of the WriteCMYKImage method is:
1161 % MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1162 % Image *image,ExceptionInfo *exception)
1164 % A description of each parameter follows.
1166 % o image_info: the image info.
1168 % o image: The image.
1170 % o exception: return any errors or warnings in this structure.
1173 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1174 Image *image,ExceptionInfo *exception)
1199 Allocate memory for pixels.
1201 assert(image_info != (const ImageInfo *) NULL);
1202 assert(image_info->signature == MagickSignature);
1203 assert(image != (Image *) NULL);
1204 assert(image->signature == MagickSignature);
1205 if (image->debug != MagickFalse)
1206 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1207 if (image_info->interlace != PartitionInterlace)
1210 Open output image file.
1212 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1213 if (status == MagickFalse)
1220 Convert MIFF to CMYK raster pixels.
1222 if (image->colorspace != CMYKColorspace)
1223 (void) TransformImageColorspace(image,CMYKColorspace,exception);
1224 quantum_type=CMYKQuantum;
1225 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1227 quantum_type=CMYKAQuantum;
1228 if (image->alpha_trait != BlendPixelTrait)
1229 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1231 quantum_info=AcquireQuantumInfo(image_info,image);
1232 if (quantum_info == (QuantumInfo *) NULL)
1233 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1234 pixels=GetQuantumPixels(quantum_info);
1235 switch (image_info->interlace)
1241 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
1243 for (y=0; y < (ssize_t) image->rows; y++)
1245 register const Quantum
1248 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1249 if (p == (const Quantum *) NULL)
1251 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1252 quantum_type,pixels,exception);
1253 count=WriteBlob(image,length,pixels);
1254 if (count != (ssize_t) length)
1256 if (image->previous == (Image *) NULL)
1258 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1260 if (status == MagickFalse)
1269 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1271 for (y=0; y < (ssize_t) image->rows; y++)
1273 register const Quantum
1276 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1277 if (p == (const Quantum *) NULL)
1279 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1280 CyanQuantum,pixels,exception);
1281 count=WriteBlob(image,length,pixels);
1282 if (count != (ssize_t) length)
1284 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1285 MagentaQuantum,pixels,exception);
1286 count=WriteBlob(image,length,pixels);
1287 if (count != (ssize_t) length)
1289 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1290 YellowQuantum,pixels,exception);
1291 count=WriteBlob(image,length,pixels);
1292 if (count != (ssize_t) length)
1294 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1295 BlackQuantum,pixels,exception);
1296 count=WriteBlob(image,length,pixels);
1297 if (count != (ssize_t) length)
1299 if (quantum_type == CMYKAQuantum)
1301 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1302 AlphaQuantum,pixels,exception);
1303 count=WriteBlob(image,length,pixels);
1304 if (count != (ssize_t) length)
1307 if (image->previous == (Image *) NULL)
1309 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1311 if (status == MagickFalse)
1317 case PlaneInterlace:
1320 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1322 for (y=0; y < (ssize_t) image->rows; y++)
1324 register const Quantum
1327 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1328 if (p == (const Quantum *) NULL)
1330 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1331 CyanQuantum,pixels,exception);
1332 count=WriteBlob(image,length,pixels);
1333 if (count != (ssize_t) length)
1336 if (image->previous == (Image *) NULL)
1338 status=SetImageProgress(image,SaveImageTag,1,6);
1339 if (status == MagickFalse)
1342 for (y=0; y < (ssize_t) image->rows; y++)
1344 register const Quantum
1347 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1348 if (p == (const Quantum *) NULL)
1350 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1351 MagentaQuantum,pixels,exception);
1352 count=WriteBlob(image,length,pixels);
1353 if (count != (ssize_t) length)
1356 if (image->previous == (Image *) NULL)
1358 status=SetImageProgress(image,SaveImageTag,2,6);
1359 if (status == MagickFalse)
1362 for (y=0; y < (ssize_t) image->rows; y++)
1364 register const Quantum
1367 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1368 if (p == (const Quantum *) NULL)
1370 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1371 YellowQuantum,pixels,exception);
1372 count=WriteBlob(image,length,pixels);
1373 if (count != (ssize_t) length)
1376 if (image->previous == (Image *) NULL)
1378 status=SetImageProgress(image,SaveImageTag,3,6);
1379 if (status == MagickFalse)
1382 for (y=0; y < (ssize_t) image->rows; y++)
1384 register const Quantum
1387 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1388 if (p == (const Quantum *) NULL)
1390 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1391 BlackQuantum,pixels,exception);
1392 count=WriteBlob(image,length,pixels);
1393 if (count != (ssize_t) length)
1396 if (image->previous == (Image *) NULL)
1398 status=SetImageProgress(image,SaveImageTag,4,6);
1399 if (status == MagickFalse)
1402 if (quantum_type == CMYKAQuantum)
1404 for (y=0; y < (ssize_t) image->rows; y++)
1406 register const Quantum
1409 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1410 if (p == (const Quantum *) NULL)
1412 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1413 AlphaQuantum,pixels,exception);
1414 count=WriteBlob(image,length,pixels);
1415 if (count != (ssize_t) length)
1418 if (image->previous == (Image *) NULL)
1420 status=SetImageProgress(image,SaveImageTag,5,6);
1421 if (status == MagickFalse)
1425 if (image_info->interlace == PartitionInterlace)
1426 (void) CopyMagickString(image->filename,image_info->filename,
1428 if (image->previous == (Image *) NULL)
1430 status=SetImageProgress(image,SaveImageTag,6,6);
1431 if (status == MagickFalse)
1436 case PartitionInterlace:
1439 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1441 AppendImageFormat("C",image->filename);
1442 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1443 AppendBinaryBlobMode,exception);
1444 if (status == MagickFalse)
1446 for (y=0; y < (ssize_t) image->rows; y++)
1448 register const Quantum
1451 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1452 if (p == (const Quantum *) NULL)
1454 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1455 CyanQuantum,pixels,exception);
1456 count=WriteBlob(image,length,pixels);
1457 if (count != (ssize_t) length)
1460 if (image->previous == (Image *) NULL)
1462 status=SetImageProgress(image,SaveImageTag,1,6);
1463 if (status == MagickFalse)
1466 (void) CloseBlob(image);
1467 AppendImageFormat("M",image->filename);
1468 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1469 AppendBinaryBlobMode,exception);
1470 if (status == MagickFalse)
1472 for (y=0; y < (ssize_t) image->rows; y++)
1474 register const Quantum
1477 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1478 if (p == (const Quantum *) NULL)
1480 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1481 MagentaQuantum,pixels,exception);
1482 count=WriteBlob(image,length,pixels);
1483 if (count != (ssize_t) length)
1486 if (image->previous == (Image *) NULL)
1488 status=SetImageProgress(image,SaveImageTag,2,6);
1489 if (status == MagickFalse)
1492 (void) CloseBlob(image);
1493 AppendImageFormat("Y",image->filename);
1494 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1495 AppendBinaryBlobMode,exception);
1496 if (status == MagickFalse)
1498 for (y=0; y < (ssize_t) image->rows; y++)
1500 register const Quantum
1503 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1504 if (p == (const Quantum *) NULL)
1506 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1507 YellowQuantum,pixels,exception);
1508 count=WriteBlob(image,length,pixels);
1509 if (count != (ssize_t) length)
1512 if (image->previous == (Image *) NULL)
1514 status=SetImageProgress(image,SaveImageTag,3,6);
1515 if (status == MagickFalse)
1518 (void) CloseBlob(image);
1519 AppendImageFormat("K",image->filename);
1520 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1521 AppendBinaryBlobMode,exception);
1522 if (status == MagickFalse)
1524 for (y=0; y < (ssize_t) image->rows; y++)
1526 register const Quantum
1529 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1530 if (p == (const Quantum *) NULL)
1532 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1533 BlackQuantum,pixels,exception);
1534 count=WriteBlob(image,length,pixels);
1535 if (count != (ssize_t) length)
1538 if (image->previous == (Image *) NULL)
1540 status=SetImageProgress(image,SaveImageTag,4,6);
1541 if (status == MagickFalse)
1544 if (quantum_type == CMYKAQuantum)
1546 (void) CloseBlob(image);
1547 AppendImageFormat("A",image->filename);
1548 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1549 AppendBinaryBlobMode,exception);
1550 if (status == MagickFalse)
1552 for (y=0; y < (ssize_t) image->rows; y++)
1554 register const Quantum
1557 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1558 if (p == (const Quantum *) NULL)
1560 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1561 AlphaQuantum,pixels,exception);
1562 count=WriteBlob(image,length,pixels);
1563 if (count != (ssize_t) length)
1566 if (image->previous == (Image *) NULL)
1568 status=SetImageProgress(image,SaveImageTag,5,6);
1569 if (status == MagickFalse)
1573 (void) CloseBlob(image);
1574 (void) CopyMagickString(image->filename,image_info->filename,
1576 if (image->previous == (Image *) NULL)
1578 status=SetImageProgress(image,SaveImageTag,6,6);
1579 if (status == MagickFalse)
1585 quantum_info=DestroyQuantumInfo(quantum_info);
1586 if (GetNextImageInList(image) == (Image *) NULL)
1588 image=SyncNextImageInList(image);
1589 status=SetImageProgress(image,SaveImagesTag,scene++,
1590 GetImageListLength(image));
1591 if (status == MagickFalse)
1593 } while (image_info->adjoin != MagickFalse);
1594 (void) CloseBlob(image);