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);
162 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
163 if (quantum_info == (QuantumInfo *) NULL)
164 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
165 pixels=GetQuantumPixels(quantum_info);
166 quantum_type=CMYKQuantum;
167 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
169 quantum_type=CMYKAQuantum;
170 image->matte=MagickTrue;
172 if (image_info->number_scenes != 0)
173 while (image->scene < image_info->scene)
179 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
180 for (y=0; y < (ssize_t) image->rows; y++)
182 count=ReadBlob(image,length,pixels);
183 if (count != (ssize_t) length)
193 Read pixels to virtual canvas image then push to image.
195 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
196 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
198 image->colorspace=CMYKColorspace;
199 switch (image_info->interlace)
205 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
209 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
210 count=ReadBlob(image,length,pixels);
212 for (y=0; y < (ssize_t) image->extract_info.height; y++)
214 register const Quantum
223 if (count != (ssize_t) length)
225 ThrowFileException(exception,CorruptImageError,
226 "UnexpectedEndOfFile",image->filename);
229 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
231 if (q == (Quantum *) NULL)
233 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
234 quantum_info,quantum_type,pixels,exception);
235 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
237 if (((y-image->extract_info.y) >= 0) &&
238 ((y-image->extract_info.y) < (ssize_t) image->rows))
240 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
241 canvas_image->columns,1,exception);
242 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
243 image->columns,1,exception);
244 if ((p == (const Quantum *) NULL) ||
245 (q == (Quantum *) NULL))
247 for (x=0; x < (ssize_t) image->columns; x++)
249 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
250 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
251 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
252 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
253 SetPixelAlpha(image,OpaqueAlpha,q);
254 if (image->matte != MagickFalse)
255 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
256 p+=GetPixelChannels(canvas_image);
257 q+=GetPixelChannels(image);
259 if (SyncAuthenticPixels(image,exception) == MagickFalse)
262 if (image->previous == (Image *) NULL)
264 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
266 if (status == MagickFalse)
269 count=ReadBlob(image,length,pixels);
286 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
290 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
291 count=ReadBlob(image,length,pixels);
293 for (y=0; y < (ssize_t) image->extract_info.height; y++)
295 register const Quantum
304 if (count != (ssize_t) length)
306 ThrowFileException(exception,CorruptImageError,
307 "UnexpectedEndOfFile",image->filename);
310 for (i=0; i < (image->matte != MagickFalse ? 5 : 4); i++)
312 quantum_type=quantum_types[i];
313 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
315 if (q == (Quantum *) NULL)
317 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
318 quantum_info,quantum_type,pixels,exception);
319 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
321 if (((y-image->extract_info.y) >= 0) &&
322 ((y-image->extract_info.y) < (ssize_t) image->rows))
324 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
325 0,canvas_image->columns,1,exception);
326 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
327 image->columns,1,exception);
328 if ((p == (const Quantum *) NULL) ||
329 (q == (Quantum *) NULL))
331 for (x=0; x < (ssize_t) image->columns; x++)
333 switch (quantum_type)
337 SetPixelCyan(image,GetPixelCyan(canvas_image,p),q);
342 SetPixelMagenta(image,GetPixelMagenta(canvas_image,p),q);
347 SetPixelYellow(image,GetPixelYellow(canvas_image,p),q);
352 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
357 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
363 p+=GetPixelChannels(canvas_image);
364 q+=GetPixelChannels(image);
366 if (SyncAuthenticPixels(image,exception) == MagickFalse)
369 count=ReadBlob(image,length,pixels);
371 if (image->previous == (Image *) NULL)
373 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
375 if (status == MagickFalse)
384 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
388 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
389 count=ReadBlob(image,length,pixels);
391 for (y=0; y < (ssize_t) image->extract_info.height; y++)
393 register const Quantum
402 if (count != (ssize_t) length)
404 ThrowFileException(exception,CorruptImageError,
405 "UnexpectedEndOfFile",image->filename);
408 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
410 if (q == (Quantum *) NULL)
412 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
413 quantum_info,CyanQuantum,pixels,exception);
414 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
416 if (((y-image->extract_info.y) >= 0) &&
417 ((y-image->extract_info.y) < (ssize_t) image->rows))
419 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
420 canvas_image->columns,1,exception);
421 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
422 image->columns,1,exception);
423 if ((p == (const Quantum *) NULL) ||
424 (q == (Quantum *) NULL))
426 for (x=0; x < (ssize_t) image->columns; x++)
428 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
429 p+=GetPixelChannels(canvas_image);
430 q+=GetPixelChannels(image);
432 if (SyncAuthenticPixels(image,exception) == MagickFalse)
435 count=ReadBlob(image,length,pixels);
437 if (image->previous == (Image *) NULL)
439 status=SetImageProgress(image,LoadImageTag,1,6);
440 if (status == MagickFalse)
443 for (y=0; y < (ssize_t) image->extract_info.height; y++)
445 register const Quantum
454 if (count != (ssize_t) length)
456 ThrowFileException(exception,CorruptImageError,
457 "UnexpectedEndOfFile",image->filename);
460 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
462 if (q == (Quantum *) NULL)
464 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
465 quantum_info,MagentaQuantum,pixels,exception);
466 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
468 if (((y-image->extract_info.y) >= 0) &&
469 ((y-image->extract_info.y) < (ssize_t) image->rows))
471 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
472 canvas_image->columns,1,exception);
473 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
474 image->columns,1,exception);
475 if ((p == (const Quantum *) NULL) ||
476 (q == (Quantum *) NULL))
478 for (x=0; x < (ssize_t) image->columns; x++)
480 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
481 p+=GetPixelChannels(canvas_image);
482 q+=GetPixelChannels(image);
484 if (SyncAuthenticPixels(image,exception) == MagickFalse)
487 count=ReadBlob(image,length,pixels);
489 if (image->previous == (Image *) NULL)
491 status=SetImageProgress(image,LoadImageTag,2,6);
492 if (status == MagickFalse)
495 for (y=0; y < (ssize_t) image->extract_info.height; y++)
497 register const Quantum
506 if (count != (ssize_t) length)
508 ThrowFileException(exception,CorruptImageError,
509 "UnexpectedEndOfFile",image->filename);
512 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
514 if (q == (Quantum *) NULL)
516 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
517 quantum_info,YellowQuantum,pixels,exception);
518 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
520 if (((y-image->extract_info.y) >= 0) &&
521 ((y-image->extract_info.y) < (ssize_t) image->rows))
523 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
524 canvas_image->columns,1,exception);
525 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
526 image->columns,1,exception);
527 if ((p == (const Quantum *) NULL) ||
528 (q == (Quantum *) NULL))
530 for (x=0; x < (ssize_t) image->columns; x++)
532 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
533 p+=GetPixelChannels(canvas_image);
534 q+=GetPixelChannels(image);
536 if (SyncAuthenticPixels(image,exception) == MagickFalse)
539 count=ReadBlob(image,length,pixels);
541 if (image->previous == (Image *) NULL)
543 status=SetImageProgress(image,LoadImageTag,3,6);
544 if (status == MagickFalse)
547 for (y=0; y < (ssize_t) image->extract_info.height; y++)
549 register const Quantum
558 if (count != (ssize_t) length)
560 ThrowFileException(exception,CorruptImageError,
561 "UnexpectedEndOfFile",image->filename);
564 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
566 if (q == (Quantum *) NULL)
568 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
569 quantum_info,BlackQuantum,pixels,exception);
570 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
572 if (((y-image->extract_info.y) >= 0) &&
573 ((y-image->extract_info.y) < (ssize_t) image->rows))
575 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
576 canvas_image->columns,1,exception);
577 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
578 image->columns,1,exception);
579 if ((p == (const Quantum *) NULL) ||
580 (q == (Quantum *) NULL))
582 for (x=0; x < (ssize_t) image->columns; x++)
584 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
585 p+=GetPixelChannels(canvas_image);
586 q+=GetPixelChannels(image);
588 if (SyncAuthenticPixels(image,exception) == MagickFalse)
591 count=ReadBlob(image,length,pixels);
593 if (image->previous == (Image *) NULL)
595 status=SetImageProgress(image,LoadImageTag,4,6);
596 if (status == MagickFalse)
599 if (image->matte != MagickFalse)
601 for (y=0; y < (ssize_t) image->extract_info.height; y++)
603 register const Quantum
612 if (count != (ssize_t) length)
614 ThrowFileException(exception,CorruptImageError,
615 "UnexpectedEndOfFile",image->filename);
618 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
620 if (q == (Quantum *) NULL)
622 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
623 quantum_info,AlphaQuantum,pixels,exception);
624 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
626 if (((y-image->extract_info.y) >= 0) &&
627 ((y-image->extract_info.y) < (ssize_t) image->rows))
629 p=GetVirtualPixels(canvas_image,
630 canvas_image->extract_info.x,0,canvas_image->columns,1,
632 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
633 image->columns,1,exception);
634 if ((p == (const Quantum *) NULL) ||
635 (q == (Quantum *) NULL))
637 for (x=0; x < (ssize_t) image->columns; x++)
639 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
640 p+=GetPixelChannels(canvas_image);
641 q+=GetPixelChannels(image);
643 if (SyncAuthenticPixels(image,exception) == MagickFalse)
646 count=ReadBlob(image,length,pixels);
648 if (image->previous == (Image *) NULL)
650 status=SetImageProgress(image,LoadImageTag,5,6);
651 if (status == MagickFalse)
655 if (image->previous == (Image *) NULL)
657 status=SetImageProgress(image,LoadImageTag,6,6);
658 if (status == MagickFalse)
663 case PartitionInterlace:
666 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
668 AppendImageFormat("C",image->filename);
669 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
670 if (status == MagickFalse)
672 canvas_image=DestroyImageList(canvas_image);
673 image=DestroyImageList(image);
674 return((Image *) NULL);
676 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
677 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
679 length=GetQuantumExtent(canvas_image,quantum_info,CyanQuantum);
680 for (i=0; i < (ssize_t) scene; i++)
681 for (y=0; y < (ssize_t) image->extract_info.height; y++)
682 if (ReadBlob(image,length,pixels) != (ssize_t) length)
684 ThrowFileException(exception,CorruptImageError,
685 "UnexpectedEndOfFile",image->filename);
688 count=ReadBlob(image,length,pixels);
689 for (y=0; y < (ssize_t) image->extract_info.height; y++)
691 register const Quantum
700 if (count != (ssize_t) length)
702 ThrowFileException(exception,CorruptImageError,
703 "UnexpectedEndOfFile",image->filename);
706 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
708 if (q == (Quantum *) NULL)
710 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
711 quantum_info,CyanQuantum,pixels,exception);
712 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
714 if (((y-image->extract_info.y) >= 0) &&
715 ((y-image->extract_info.y) < (ssize_t) image->rows))
717 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
718 canvas_image->columns,1,exception);
719 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
720 image->columns,1,exception);
721 if ((p == (const Quantum *) NULL) ||
722 (q == (Quantum *) NULL))
724 for (x=0; x < (ssize_t) image->columns; x++)
726 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
727 p+=GetPixelChannels(canvas_image);
728 q+=GetPixelChannels(image);
730 if (SyncAuthenticPixels(image,exception) == MagickFalse)
733 count=ReadBlob(image,length,pixels);
735 if (image->previous == (Image *) NULL)
737 status=SetImageProgress(image,LoadImageTag,1,5);
738 if (status == MagickFalse)
741 (void) CloseBlob(image);
742 AppendImageFormat("M",image->filename);
743 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
744 if (status == MagickFalse)
746 canvas_image=DestroyImageList(canvas_image);
747 image=DestroyImageList(image);
748 return((Image *) NULL);
750 length=GetQuantumExtent(canvas_image,quantum_info,MagentaQuantum);
751 for (i=0; i < (ssize_t) scene; i++)
752 for (y=0; y < (ssize_t) image->extract_info.height; y++)
753 if (ReadBlob(image,length,pixels) != (ssize_t) length)
755 ThrowFileException(exception,CorruptImageError,
756 "UnexpectedEndOfFile",image->filename);
759 count=ReadBlob(image,length,pixels);
760 for (y=0; y < (ssize_t) image->extract_info.height; y++)
762 register const Quantum
771 if (count != (ssize_t) length)
773 ThrowFileException(exception,CorruptImageError,
774 "UnexpectedEndOfFile",image->filename);
777 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
779 if (q == (Quantum *) NULL)
781 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
782 quantum_info,MagentaQuantum,pixels,exception);
783 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
785 if (((y-image->extract_info.y) >= 0) &&
786 ((y-image->extract_info.y) < (ssize_t) image->rows))
788 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
789 canvas_image->columns,1,exception);
790 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
791 image->columns,1,exception);
792 if ((p == (const Quantum *) NULL) ||
793 (q == (Quantum *) NULL))
795 for (x=0; x < (ssize_t) image->columns; x++)
797 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
798 p+=GetPixelChannels(canvas_image);
799 q+=GetPixelChannels(image);
801 if (SyncAuthenticPixels(image,exception) == MagickFalse)
804 count=ReadBlob(image,length,pixels);
806 if (image->previous == (Image *) NULL)
808 status=SetImageProgress(image,LoadImageTag,2,5);
809 if (status == MagickFalse)
812 (void) CloseBlob(image);
813 AppendImageFormat("Y",image->filename);
814 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
815 if (status == MagickFalse)
817 canvas_image=DestroyImageList(canvas_image);
818 image=DestroyImageList(image);
819 return((Image *) NULL);
821 length=GetQuantumExtent(canvas_image,quantum_info,YellowQuantum);
822 for (i=0; i < (ssize_t) scene; i++)
823 for (y=0; y < (ssize_t) image->extract_info.height; y++)
824 if (ReadBlob(image,length,pixels) != (ssize_t) length)
826 ThrowFileException(exception,CorruptImageError,
827 "UnexpectedEndOfFile",image->filename);
830 count=ReadBlob(image,length,pixels);
831 for (y=0; y < (ssize_t) image->extract_info.height; y++)
833 register const Quantum
842 if (count != (ssize_t) length)
844 ThrowFileException(exception,CorruptImageError,
845 "UnexpectedEndOfFile",image->filename);
848 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
850 if (q == (Quantum *) NULL)
852 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
853 quantum_info,YellowQuantum,pixels,exception);
854 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
856 if (((y-image->extract_info.y) >= 0) &&
857 ((y-image->extract_info.y) < (ssize_t) image->rows))
859 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
860 canvas_image->columns,1,exception);
861 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
862 image->columns,1,exception);
863 if ((p == (const Quantum *) NULL) ||
864 (q == (Quantum *) NULL))
866 for (x=0; x < (ssize_t) image->columns; x++)
868 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
869 p+=GetPixelChannels(canvas_image);
870 q+=GetPixelChannels(image);
872 if (SyncAuthenticPixels(image,exception) == MagickFalse)
875 count=ReadBlob(image,length,pixels);
877 if (image->previous == (Image *) NULL)
879 status=SetImageProgress(image,LoadImageTag,3,5);
880 if (status == MagickFalse)
883 (void) CloseBlob(image);
884 AppendImageFormat("K",image->filename);
885 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
886 if (status == MagickFalse)
888 canvas_image=DestroyImageList(canvas_image);
889 image=DestroyImageList(image);
890 return((Image *) NULL);
892 length=GetQuantumExtent(canvas_image,quantum_info,BlackQuantum);
893 for (i=0; i < (ssize_t) scene; i++)
894 for (y=0; y < (ssize_t) image->extract_info.height; y++)
895 if (ReadBlob(image,length,pixels) != (ssize_t) length)
897 ThrowFileException(exception,CorruptImageError,
898 "UnexpectedEndOfFile",image->filename);
901 count=ReadBlob(image,length,pixels);
902 for (y=0; y < (ssize_t) image->extract_info.height; y++)
904 register const Quantum
913 if (count != (ssize_t) length)
915 ThrowFileException(exception,CorruptImageError,
916 "UnexpectedEndOfFile",image->filename);
919 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
921 if (q == (Quantum *) NULL)
923 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
924 quantum_info,BlackQuantum,pixels,exception);
925 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
927 if (((y-image->extract_info.y) >= 0) &&
928 ((y-image->extract_info.y) < (ssize_t) image->rows))
930 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
931 canvas_image->columns,1,exception);
932 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
933 image->columns,1,exception);
934 if ((p == (const Quantum *) NULL) ||
935 (q == (Quantum *) NULL))
937 for (x=0; x < (ssize_t) image->columns; x++)
939 SetPixelBlack(image,GetPixelBlack(canvas_image,p),q);
940 p+=GetPixelChannels(canvas_image);
941 q+=GetPixelChannels(image);
943 if (SyncAuthenticPixels(image,exception) == MagickFalse)
946 count=ReadBlob(image,length,pixels);
948 if (image->previous == (Image *) NULL)
950 status=SetImageProgress(image,LoadImageTag,3,5);
951 if (status == MagickFalse)
954 if (image->matte != MagickFalse)
956 (void) CloseBlob(image);
957 AppendImageFormat("A",image->filename);
958 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
959 if (status == MagickFalse)
961 canvas_image=DestroyImageList(canvas_image);
962 image=DestroyImageList(image);
963 return((Image *) NULL);
965 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
966 for (i=0; i < (ssize_t) scene; i++)
967 for (y=0; y < (ssize_t) image->extract_info.height; y++)
968 if (ReadBlob(image,length,pixels) != (ssize_t) length)
970 ThrowFileException(exception,CorruptImageError,
971 "UnexpectedEndOfFile",image->filename);
974 count=ReadBlob(image,length,pixels);
975 for (y=0; y < (ssize_t) image->extract_info.height; y++)
977 register const Quantum
986 if (count != (ssize_t) length)
988 ThrowFileException(exception,CorruptImageError,
989 "UnexpectedEndOfFile",image->filename);
992 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
994 if (q == (Quantum *) NULL)
996 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
997 quantum_info,YellowQuantum,pixels,exception);
998 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
1000 if (((y-image->extract_info.y) >= 0) &&
1001 ((y-image->extract_info.y) < (ssize_t) image->rows))
1003 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
1004 0,canvas_image->columns,1,exception);
1005 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
1006 image->columns,1,exception);
1007 if ((p == (const Quantum *) NULL) ||
1008 (q == (Quantum *) NULL))
1010 for (x=0; x < (ssize_t) image->columns; x++)
1012 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
1013 p+=GetPixelChannels(canvas_image);
1014 q+=GetPixelChannels(image);
1016 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1019 count=ReadBlob(image,length,pixels);
1021 if (image->previous == (Image *) NULL)
1023 status=SetImageProgress(image,LoadImageTag,4,5);
1024 if (status == MagickFalse)
1028 if (image->previous == (Image *) NULL)
1030 status=SetImageProgress(image,LoadImageTag,5,5);
1031 if (status == MagickFalse)
1037 SetQuantumImageType(image,quantum_type);
1039 Proceed to next image.
1041 if (image_info->number_scenes != 0)
1042 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1044 if (count == (ssize_t) length)
1047 Allocate next image structure.
1049 AcquireNextImage(image_info,image,exception);
1050 if (GetNextImageInList(image) == (Image *) NULL)
1052 image=DestroyImageList(image);
1053 return((Image *) NULL);
1055 image=SyncNextImageInList(image);
1056 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1057 GetBlobSize(image));
1058 if (status == MagickFalse)
1062 } while (count == (ssize_t) length);
1063 quantum_info=DestroyQuantumInfo(quantum_info);
1064 canvas_image=DestroyImage(canvas_image);
1065 (void) CloseBlob(image);
1066 return(GetFirstImageInList(image));
1070 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1074 % R e g i s t e r C M Y K I m a g e %
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 % RegisterCMYKImage() adds attributes for the CMYK image format to
1081 % the list of supported formats. The attributes include the image format
1082 % tag, a method to read and/or write the format, whether the format
1083 % supports the saving of more than one frame to the same file or blob,
1084 % whether the format supports native in-memory I/O, and a brief
1085 % description of the format.
1087 % The format of the RegisterCMYKImage method is:
1089 % size_t RegisterCMYKImage(void)
1092 ModuleExport size_t RegisterCMYKImage(void)
1097 entry=SetMagickInfo("CMYK");
1098 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1099 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1100 entry->raw=MagickTrue;
1101 entry->endian_support=MagickTrue;
1102 entry->description=ConstantString("Raw cyan, magenta, yellow, and black "
1104 entry->module=ConstantString("CMYK");
1105 (void) RegisterMagickInfo(entry);
1106 entry=SetMagickInfo("CMYKA");
1107 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1108 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1109 entry->raw=MagickTrue;
1110 entry->endian_support=MagickTrue;
1111 entry->description=ConstantString("Raw cyan, magenta, yellow, black, and "
1113 entry->module=ConstantString("CMYK");
1114 (void) RegisterMagickInfo(entry);
1115 return(MagickImageCoderSignature);
1119 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1123 % U n r e g i s t e r C M Y K I m a g e %
1127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1129 % UnregisterCMYKImage() removes format registrations made by the
1130 % CMYK module from the list of supported formats.
1132 % The format of the UnregisterCMYKImage method is:
1134 % UnregisterCMYKImage(void)
1137 ModuleExport void UnregisterCMYKImage(void)
1139 (void) UnregisterMagickInfo("CMYK");
1140 (void) UnregisterMagickInfo("CMYKA");
1144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1148 % W r i t e C M Y K I m a g e %
1152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1154 % WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1155 % black,rasterfile format.
1157 % The format of the WriteCMYKImage method is:
1159 % MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1160 % Image *image,ExceptionInfo *exception)
1162 % A description of each parameter follows.
1164 % o image_info: the image info.
1166 % o image: The image.
1168 % o exception: return any errors or warnings in this structure.
1171 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1172 Image *image,ExceptionInfo *exception)
1197 Allocate memory for pixels.
1199 assert(image_info != (const ImageInfo *) NULL);
1200 assert(image_info->signature == MagickSignature);
1201 assert(image != (Image *) NULL);
1202 assert(image->signature == MagickSignature);
1203 if (image->debug != MagickFalse)
1204 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1205 if (image_info->interlace != PartitionInterlace)
1208 Open output image file.
1210 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1211 if (status == MagickFalse)
1214 quantum_type=CMYKQuantum;
1215 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1217 quantum_type=CMYKAQuantum;
1218 image->matte=MagickTrue;
1224 Convert MIFF to CMYK raster pixels.
1226 if (image->colorspace != CMYKColorspace)
1227 (void) TransformImageColorspace(image,CMYKColorspace,exception);
1228 if ((LocaleCompare(image_info->magick,"CMYKA") == 0) &&
1229 (image->matte == MagickFalse))
1230 (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);