2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write RAW CMYK Image Format %
20 % Copyright 1999-2018 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 % https://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 == 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)
150 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
151 if (status == MagickFalse)
153 image=DestroyImageList(image);
154 return((Image *) NULL);
156 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
157 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
161 Create virtual canvas to support cropping (i.e. image.cmyk[100x100+10+20]).
163 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
165 if (canvas_image == (Image *) NULL)
166 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
167 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
169 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
170 if (quantum_info == (QuantumInfo *) NULL)
172 canvas_image=DestroyImage(canvas_image);
173 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
175 quantum_type=CMYKQuantum;
176 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
178 quantum_type=CMYKAQuantum;
179 image->alpha_trait=BlendPixelTrait;
181 pixels=(const unsigned char *) NULL;
182 if (image_info->number_scenes != 0)
183 while (image->scene < image_info->scene)
189 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
190 for (y=0; y < (ssize_t) image->rows; y++)
192 pixels=(const unsigned char *) ReadBlobStream(image,length,
193 GetQuantumPixels(quantum_info),&count);
194 if (count != (ssize_t) length)
205 Read pixels to virtual canvas image then push to image.
207 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
208 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
210 status=SetImageExtent(image,image->columns,image->rows,exception);
211 if (status == MagickFalse)
213 if (SetImageColorspace(image,CMYKColorspace,exception) == MagickFalse)
215 switch (image_info->interlace)
221 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
225 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
226 pixels=(const unsigned char *) ReadBlobStream(image,length,
227 GetQuantumPixels(quantum_info),&count);
229 for (y=0; y < (ssize_t) image->extract_info.height; y++)
231 register const Quantum
240 if (count != (ssize_t) length)
243 ThrowFileException(exception,CorruptImageError,
244 "UnexpectedEndOfFile",image->filename);
247 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
249 if (q == (Quantum *) NULL)
251 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
252 quantum_info,quantum_type,pixels,exception);
253 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
255 if (((y-image->extract_info.y) >= 0) &&
256 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
264 for (x=0; x < (ssize_t) image->columns; x++)
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);
276 if (SyncAuthenticPixels(image,exception) == MagickFalse)
279 if (image->previous == (Image *) NULL)
281 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
283 if (status == MagickFalse)
286 pixels=(const unsigned char *) ReadBlobStream(image,length,
287 GetQuantumPixels(quantum_info),&count);
304 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
308 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
309 pixels=(const unsigned char *) ReadBlobStream(image,length,
310 GetQuantumPixels(quantum_info),&count);
312 for (y=0; y < (ssize_t) image->extract_info.height; y++)
314 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 5 : 4); i++)
316 register const Quantum
325 if (count != (ssize_t) length)
328 ThrowFileException(exception,CorruptImageError,
329 "UnexpectedEndOfFile",image->filename);
332 quantum_type=quantum_types[i];
333 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
335 if (q == (Quantum *) NULL)
337 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
338 quantum_info,quantum_type,pixels,exception);
339 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
341 if (((y-image->extract_info.y) >= 0) &&
342 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
350 for (x=0; x < (ssize_t) image->columns; x++)
352 switch (quantum_type)
356 SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
361 SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
366 SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
371 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
376 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
382 p+=GetPixelChannels(canvas_image);
383 q+=GetPixelChannels(image);
385 if (SyncAuthenticPixels(image,exception) == MagickFalse)
388 pixels=(const unsigned char *) ReadBlobStream(image,length,
389 GetQuantumPixels(quantum_info),&count);
391 if (image->previous == (Image *) NULL)
393 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
395 if (status == MagickFalse)
404 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
408 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
409 pixels=(const unsigned char *) ReadBlobStream(image,length,
410 GetQuantumPixels(quantum_info),&count);
412 for (y=0; y < (ssize_t) image->extract_info.height; y++)
414 register const Quantum
423 if (count != (ssize_t) length)
426 ThrowFileException(exception,CorruptImageError,
427 "UnexpectedEndOfFile",image->filename);
430 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
432 if (q == (Quantum *) NULL)
434 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
435 quantum_info,CyanQuantum,pixels,exception);
436 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
438 if (((y-image->extract_info.y) >= 0) &&
439 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
447 for (x=0; x < (ssize_t) image->columns; x++)
449 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
450 p+=GetPixelChannels(canvas_image);
451 q+=GetPixelChannels(image);
453 if (SyncAuthenticPixels(image,exception) == MagickFalse)
456 pixels=(const unsigned char *) ReadBlobStream(image,length,
457 GetQuantumPixels(quantum_info),&count);
459 if (image->previous == (Image *) NULL)
461 status=SetImageProgress(image,LoadImageTag,1,6);
462 if (status == MagickFalse)
465 for (y=0; y < (ssize_t) image->extract_info.height; y++)
467 register const Quantum
476 if (count != (ssize_t) length)
479 ThrowFileException(exception,CorruptImageError,
480 "UnexpectedEndOfFile",image->filename);
483 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
485 if (q == (Quantum *) NULL)
487 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
488 quantum_info,MagentaQuantum,pixels,exception);
489 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
491 if (((y-image->extract_info.y) >= 0) &&
492 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
500 for (x=0; x < (ssize_t) image->columns; x++)
502 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
503 p+=GetPixelChannels(canvas_image);
504 q+=GetPixelChannels(image);
506 if (SyncAuthenticPixels(image,exception) == MagickFalse)
509 pixels=(const unsigned char *) ReadBlobStream(image,length,
510 GetQuantumPixels(quantum_info),&count);
512 if (image->previous == (Image *) NULL)
514 status=SetImageProgress(image,LoadImageTag,2,6);
515 if (status == MagickFalse)
518 for (y=0; y < (ssize_t) image->extract_info.height; y++)
520 register const Quantum
529 if (count != (ssize_t) length)
532 ThrowFileException(exception,CorruptImageError,
533 "UnexpectedEndOfFile",image->filename);
536 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
538 if (q == (Quantum *) NULL)
540 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
541 quantum_info,YellowQuantum,pixels,exception);
542 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
544 if (((y-image->extract_info.y) >= 0) &&
545 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
553 for (x=0; x < (ssize_t) image->columns; x++)
555 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
556 p+=GetPixelChannels(canvas_image);
557 q+=GetPixelChannels(image);
559 if (SyncAuthenticPixels(image,exception) == MagickFalse)
562 pixels=(const unsigned char *) ReadBlobStream(image,length,
563 GetQuantumPixels(quantum_info),&count);
565 if (image->previous == (Image *) NULL)
567 status=SetImageProgress(image,LoadImageTag,3,6);
568 if (status == MagickFalse)
571 for (y=0; y < (ssize_t) image->extract_info.height; y++)
573 register const Quantum
582 if (count != (ssize_t) length)
585 ThrowFileException(exception,CorruptImageError,
586 "UnexpectedEndOfFile",image->filename);
589 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
591 if (q == (Quantum *) NULL)
593 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
594 quantum_info,BlackQuantum,pixels,exception);
595 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
597 if (((y-image->extract_info.y) >= 0) &&
598 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
606 for (x=0; x < (ssize_t) image->columns; x++)
608 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
609 p+=GetPixelChannels(canvas_image);
610 q+=GetPixelChannels(image);
612 if (SyncAuthenticPixels(image,exception) == MagickFalse)
615 pixels=(const unsigned char *) ReadBlobStream(image,length,
616 GetQuantumPixels(quantum_info),&count);
618 if (image->previous == (Image *) NULL)
620 status=SetImageProgress(image,LoadImageTag,4,6);
621 if (status == MagickFalse)
624 if (image->alpha_trait != UndefinedPixelTrait)
626 for (y=0; y < (ssize_t) image->extract_info.height; y++)
628 register const Quantum
637 if (count != (ssize_t) length)
640 ThrowFileException(exception,CorruptImageError,
641 "UnexpectedEndOfFile",image->filename);
644 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
646 if (q == (Quantum *) NULL)
648 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
649 quantum_info,AlphaQuantum,pixels,exception);
650 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
652 if (((y-image->extract_info.y) >= 0) &&
653 ((y-image->extract_info.y) < (ssize_t) image->rows))
655 p=GetVirtualPixels(canvas_image,
656 canvas_image->extract_info.x,0,canvas_image->columns,1,
658 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
659 image->columns,1,exception);
660 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
662 for (x=0; x < (ssize_t) image->columns; x++)
664 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
665 p+=GetPixelChannels(canvas_image);
666 q+=GetPixelChannels(image);
668 if (SyncAuthenticPixels(image,exception) == MagickFalse)
671 pixels=(const unsigned char *) ReadBlobStream(image,length,
672 GetQuantumPixels(quantum_info),&count);
674 if (image->previous == (Image *) NULL)
676 status=SetImageProgress(image,LoadImageTag,5,6);
677 if (status == MagickFalse)
681 if (image->previous == (Image *) NULL)
683 status=SetImageProgress(image,LoadImageTag,6,6);
684 if (status == MagickFalse)
689 case PartitionInterlace:
692 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
694 AppendImageFormat("C",image->filename);
695 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
696 if (status == MagickFalse)
698 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
701 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
705 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
706 for (i=0; i < (ssize_t) scene; i++)
708 for (y=0; y < (ssize_t) image->extract_info.height; y++)
710 pixels=(const unsigned char *) ReadBlobStream(image,length,
711 GetQuantumPixels(quantum_info),&count);
712 if (count != (ssize_t) length)
715 if (count != (ssize_t) length)
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++)
722 register const Quantum
731 if (count != (ssize_t) length)
734 ThrowFileException(exception,CorruptImageError,
735 "UnexpectedEndOfFile",image->filename);
738 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
740 if (q == (Quantum *) NULL)
742 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
743 quantum_info,CyanQuantum,pixels,exception);
744 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
746 if (((y-image->extract_info.y) >= 0) &&
747 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
755 for (x=0; x < (ssize_t) image->columns; x++)
757 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
758 p+=GetPixelChannels(canvas_image);
759 q+=GetPixelChannels(image);
761 if (SyncAuthenticPixels(image,exception) == MagickFalse)
764 pixels=(const unsigned char *) ReadBlobStream(image,length,
765 GetQuantumPixels(quantum_info),&count);
767 if (image->previous == (Image *) NULL)
769 status=SetImageProgress(image,LoadImageTag,1,5);
770 if (status == MagickFalse)
773 (void) CloseBlob(image);
774 AppendImageFormat("M",image->filename);
775 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
776 if (status == MagickFalse)
778 length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
779 for (i=0; i < (ssize_t) scene; i++)
781 for (y=0; y < (ssize_t) image->extract_info.height; y++)
783 pixels=(const unsigned char *) ReadBlobStream(image,length,
784 GetQuantumPixels(quantum_info),&count);
785 if (count != (ssize_t) length)
788 if (count != (ssize_t) length)
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++)
795 register const Quantum
804 if (count != (ssize_t) length)
807 ThrowFileException(exception,CorruptImageError,
808 "UnexpectedEndOfFile",image->filename);
811 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
813 if (q == (Quantum *) NULL)
815 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
816 quantum_info,MagentaQuantum,pixels,exception);
817 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
819 if (((y-image->extract_info.y) >= 0) &&
820 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
828 for (x=0; x < (ssize_t) image->columns; x++)
830 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
831 p+=GetPixelChannels(canvas_image);
832 q+=GetPixelChannels(image);
834 if (SyncAuthenticPixels(image,exception) == MagickFalse)
837 pixels=(const unsigned char *) ReadBlobStream(image,length,
838 GetQuantumPixels(quantum_info),&count);
840 if (image->previous == (Image *) NULL)
842 status=SetImageProgress(image,LoadImageTag,2,5);
843 if (status == MagickFalse)
846 (void) CloseBlob(image);
847 AppendImageFormat("Y",image->filename);
848 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
849 if (status == MagickFalse)
851 length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
852 for (i=0; i < (ssize_t) scene; i++)
854 for (y=0; y < (ssize_t) image->extract_info.height; y++)
856 pixels=(const unsigned char *) ReadBlobStream(image,length,
857 GetQuantumPixels(quantum_info),&count);
858 if (count != (ssize_t) length)
861 if (count != (ssize_t) length)
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++)
868 register const Quantum
877 if (count != (ssize_t) length)
880 ThrowFileException(exception,CorruptImageError,
881 "UnexpectedEndOfFile",image->filename);
884 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
886 if (q == (Quantum *) NULL)
888 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
889 quantum_info,YellowQuantum,pixels,exception);
890 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
892 if (((y-image->extract_info.y) >= 0) &&
893 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
902 for (x=0; x < (ssize_t) image->columns; x++)
904 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
905 p+=GetPixelChannels(canvas_image);
906 q+=GetPixelChannels(image);
908 if (SyncAuthenticPixels(image,exception) == MagickFalse)
911 pixels=(const unsigned char *) ReadBlobStream(image,length,
912 GetQuantumPixels(quantum_info),&count);
914 if (image->previous == (Image *) NULL)
916 status=SetImageProgress(image,LoadImageTag,3,5);
917 if (status == MagickFalse)
920 (void) CloseBlob(image);
921 AppendImageFormat("K",image->filename);
922 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
923 if (status == MagickFalse)
925 length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
926 for (i=0; i < (ssize_t) scene; i++)
928 for (y=0; y < (ssize_t) image->extract_info.height; y++)
930 pixels=(const unsigned char *) ReadBlobStream(image,length,
931 GetQuantumPixels(quantum_info),&count);
932 if (count != (ssize_t) length)
935 if (count != (ssize_t) length)
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++)
942 register const Quantum
951 if (count != (ssize_t) length)
954 ThrowFileException(exception,CorruptImageError,
955 "UnexpectedEndOfFile",image->filename);
958 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
960 if (q == (Quantum *) NULL)
962 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
963 quantum_info,BlackQuantum,pixels,exception);
964 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
966 if (((y-image->extract_info.y) >= 0) &&
967 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
976 for (x=0; x < (ssize_t) image->columns; x++)
978 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
979 p+=GetPixelChannels(canvas_image);
980 q+=GetPixelChannels(image);
982 if (SyncAuthenticPixels(image,exception) == MagickFalse)
985 pixels=(const unsigned char *) ReadBlobStream(image,length,
986 GetQuantumPixels(quantum_info),&count);
988 if (image->previous == (Image *) NULL)
990 status=SetImageProgress(image,LoadImageTag,3,5);
991 if (status == MagickFalse)
994 if (image->alpha_trait != UndefinedPixelTrait)
996 (void) CloseBlob(image);
997 AppendImageFormat("A",image->filename);
998 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
999 if (status == MagickFalse)
1001 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
1002 for (i=0; i < (ssize_t) scene; i++)
1004 for (y=0; y < (ssize_t) image->extract_info.height; y++)
1006 pixels=(const unsigned char *) ReadBlobStream(image,length,
1007 GetQuantumPixels(quantum_info),&count);
1008 if (count != (ssize_t) length)
1011 if (count != (ssize_t) length)
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++)
1018 register const Quantum
1027 if (count != (ssize_t) length)
1030 ThrowFileException(exception,CorruptImageError,
1031 "UnexpectedEndOfFile",image->filename);
1034 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
1036 if (q == (Quantum *) NULL)
1038 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
1039 quantum_info,YellowQuantum,pixels,exception);
1040 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1042 if (((y-image->extract_info.y) >= 0) &&
1043 ((y-image->extract_info.y) < (ssize_t) image->rows))
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))
1052 for (x=0; x < (ssize_t) image->columns; x++)
1054 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1055 p+=GetPixelChannels(canvas_image);
1056 q+=GetPixelChannels(image);
1058 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1061 pixels=(const unsigned char *) ReadBlobStream(image,length,
1062 GetQuantumPixels(quantum_info),&count);
1064 if (image->previous == (Image *) NULL)
1066 status=SetImageProgress(image,LoadImageTag,4,5);
1067 if (status == MagickFalse)
1071 if (image->previous == (Image *) NULL)
1073 status=SetImageProgress(image,LoadImageTag,5,5);
1074 if (status == MagickFalse)
1080 if (status == MagickFalse)
1082 SetQuantumImageType(image,quantum_type);
1084 Proceed to next image.
1086 if (image_info->number_scenes != 0)
1087 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1089 if (count == (ssize_t) length)
1092 Allocate next image structure.
1094 AcquireNextImage(image_info,image,exception);
1095 if (GetNextImageInList(image) == (Image *) NULL)
1100 image=SyncNextImageInList(image);
1101 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1102 GetBlobSize(image));
1103 if (status == MagickFalse)
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));
1117 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1121 % R e g i s t e r C M Y K I m a g e %
1125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
1134 % The format of the RegisterCMYKImage method is:
1136 % size_t RegisterCMYKImage(void)
1139 ModuleExport size_t RegisterCMYKImage(void)
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);
1162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1166 % U n r e g i s t e r C M Y K I m a g e %
1170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1172 % UnregisterCMYKImage() removes format registrations made by the
1173 % CMYK module from the list of supported formats.
1175 % The format of the UnregisterCMYKImage method is:
1177 % UnregisterCMYKImage(void)
1180 ModuleExport void UnregisterCMYKImage(void)
1182 (void) UnregisterMagickInfo("CMYK");
1183 (void) UnregisterMagickInfo("CMYKA");
1187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191 % W r i t e C M Y K I m a g e %
1195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197 % WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1198 % black,rasterfile format.
1200 % The format of the WriteCMYKImage method is:
1202 % MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1203 % Image *image,ExceptionInfo *exception)
1205 % A description of each parameter follows.
1207 % o image_info: the image info.
1209 % o image: The image.
1211 % o exception: return any errors or warnings in this structure.
1214 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1215 Image *image,ExceptionInfo *exception)
1241 Allocate memory for pixels.
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)
1252 Open output image file.
1254 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1255 if (status == MagickFalse)
1259 imageListLength=GetImageListLength(image);
1263 Convert MIFF to CMYK raster pixels.
1265 if (image->colorspace != CMYKColorspace)
1266 (void) TransformImageColorspace(image,CMYKColorspace,exception);
1267 quantum_type=CMYKQuantum;
1268 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1270 quantum_type=CMYKAQuantum;
1271 if (image->alpha_trait == UndefinedPixelTrait)
1272 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
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)
1284 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
1286 for (y=0; y < (ssize_t) image->rows; y++)
1288 register const Quantum
1291 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1292 if (p == (const Quantum *) NULL)
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)
1299 if (image->previous == (Image *) NULL)
1301 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1303 if (status == MagickFalse)
1312 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1314 for (y=0; y < (ssize_t) image->rows; y++)
1316 register const Quantum
1319 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1320 if (p == (const Quantum *) NULL)
1322 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1323 CyanQuantum,pixels,exception);
1324 count=WriteBlob(image,length,pixels);
1325 if (count != (ssize_t) length)
1327 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1328 MagentaQuantum,pixels,exception);
1329 count=WriteBlob(image,length,pixels);
1330 if (count != (ssize_t) length)
1332 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1333 YellowQuantum,pixels,exception);
1334 count=WriteBlob(image,length,pixels);
1335 if (count != (ssize_t) length)
1337 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1338 BlackQuantum,pixels,exception);
1339 count=WriteBlob(image,length,pixels);
1340 if (count != (ssize_t) length)
1342 if (quantum_type == CMYKAQuantum)
1344 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1345 AlphaQuantum,pixels,exception);
1346 count=WriteBlob(image,length,pixels);
1347 if (count != (ssize_t) length)
1350 if (image->previous == (Image *) NULL)
1352 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1354 if (status == MagickFalse)
1360 case PlaneInterlace:
1363 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1365 for (y=0; y < (ssize_t) image->rows; y++)
1367 register const Quantum
1370 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1371 if (p == (const Quantum *) NULL)
1373 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1374 CyanQuantum,pixels,exception);
1375 count=WriteBlob(image,length,pixels);
1376 if (count != (ssize_t) length)
1379 if (image->previous == (Image *) NULL)
1381 status=SetImageProgress(image,SaveImageTag,1,6);
1382 if (status == MagickFalse)
1385 for (y=0; y < (ssize_t) image->rows; y++)
1387 register const Quantum
1390 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1391 if (p == (const Quantum *) NULL)
1393 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1394 MagentaQuantum,pixels,exception);
1395 count=WriteBlob(image,length,pixels);
1396 if (count != (ssize_t) length)
1399 if (image->previous == (Image *) NULL)
1401 status=SetImageProgress(image,SaveImageTag,2,6);
1402 if (status == MagickFalse)
1405 for (y=0; y < (ssize_t) image->rows; y++)
1407 register const Quantum
1410 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1411 if (p == (const Quantum *) NULL)
1413 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1414 YellowQuantum,pixels,exception);
1415 count=WriteBlob(image,length,pixels);
1416 if (count != (ssize_t) length)
1419 if (image->previous == (Image *) NULL)
1421 status=SetImageProgress(image,SaveImageTag,3,6);
1422 if (status == MagickFalse)
1425 for (y=0; y < (ssize_t) image->rows; y++)
1427 register const Quantum
1430 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1431 if (p == (const Quantum *) NULL)
1433 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1434 BlackQuantum,pixels,exception);
1435 count=WriteBlob(image,length,pixels);
1436 if (count != (ssize_t) length)
1439 if (image->previous == (Image *) NULL)
1441 status=SetImageProgress(image,SaveImageTag,4,6);
1442 if (status == MagickFalse)
1445 if (quantum_type == CMYKAQuantum)
1447 for (y=0; y < (ssize_t) image->rows; y++)
1449 register const Quantum
1452 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1453 if (p == (const Quantum *) NULL)
1455 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1456 AlphaQuantum,pixels,exception);
1457 count=WriteBlob(image,length,pixels);
1458 if (count != (ssize_t) length)
1461 if (image->previous == (Image *) NULL)
1463 status=SetImageProgress(image,SaveImageTag,5,6);
1464 if (status == MagickFalse)
1468 if (image_info->interlace == PartitionInterlace)
1469 (void) CopyMagickString(image->filename,image_info->filename,
1471 if (image->previous == (Image *) NULL)
1473 status=SetImageProgress(image,SaveImageTag,6,6);
1474 if (status == MagickFalse)
1479 case PartitionInterlace:
1482 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1484 AppendImageFormat("C",image->filename);
1485 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1486 AppendBinaryBlobMode,exception);
1487 if (status == MagickFalse)
1489 for (y=0; y < (ssize_t) image->rows; y++)
1491 register const Quantum
1494 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1495 if (p == (const Quantum *) NULL)
1497 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1498 CyanQuantum,pixels,exception);
1499 count=WriteBlob(image,length,pixels);
1500 if (count != (ssize_t) length)
1503 if (image->previous == (Image *) NULL)
1505 status=SetImageProgress(image,SaveImageTag,1,6);
1506 if (status == MagickFalse)
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)
1515 for (y=0; y < (ssize_t) image->rows; y++)
1517 register const Quantum
1520 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1521 if (p == (const Quantum *) NULL)
1523 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1524 MagentaQuantum,pixels,exception);
1525 count=WriteBlob(image,length,pixels);
1526 if (count != (ssize_t) length)
1529 if (image->previous == (Image *) NULL)
1531 status=SetImageProgress(image,SaveImageTag,2,6);
1532 if (status == MagickFalse)
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)
1541 for (y=0; y < (ssize_t) image->rows; y++)
1543 register const Quantum
1546 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1547 if (p == (const Quantum *) NULL)
1549 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1550 YellowQuantum,pixels,exception);
1551 count=WriteBlob(image,length,pixels);
1552 if (count != (ssize_t) length)
1555 if (image->previous == (Image *) NULL)
1557 status=SetImageProgress(image,SaveImageTag,3,6);
1558 if (status == MagickFalse)
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)
1567 for (y=0; y < (ssize_t) image->rows; y++)
1569 register const Quantum
1572 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1573 if (p == (const Quantum *) NULL)
1575 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1576 BlackQuantum,pixels,exception);
1577 count=WriteBlob(image,length,pixels);
1578 if (count != (ssize_t) length)
1581 if (image->previous == (Image *) NULL)
1583 status=SetImageProgress(image,SaveImageTag,4,6);
1584 if (status == MagickFalse)
1587 if (quantum_type == CMYKAQuantum)
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)
1595 for (y=0; y < (ssize_t) image->rows; y++)
1597 register const Quantum
1600 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1601 if (p == (const Quantum *) NULL)
1603 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1604 AlphaQuantum,pixels,exception);
1605 count=WriteBlob(image,length,pixels);
1606 if (count != (ssize_t) length)
1609 if (image->previous == (Image *) NULL)
1611 status=SetImageProgress(image,SaveImageTag,5,6);
1612 if (status == MagickFalse)
1616 (void) CloseBlob(image);
1617 (void) CopyMagickString(image->filename,image_info->filename,
1619 if (image->previous == (Image *) NULL)
1621 status=SetImageProgress(image,SaveImageTag,6,6);
1622 if (status == MagickFalse)
1628 quantum_info=DestroyQuantumInfo(quantum_info);
1629 if (GetNextImageInList(image) == (Image *) NULL)
1631 image=SyncNextImageInList(image);
1632 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
1633 if (status == MagickFalse)
1635 } while (image_info->adjoin != MagickFalse);
1636 (void) CloseBlob(image);