2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write RAW CMYK Image Format %
20 % Copyright 1999-2011 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 *);
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);
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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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);
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 InheritException(&image->exception,&canvas_image->exception);
1065 canvas_image=DestroyImage(canvas_image);
1066 (void) CloseBlob(image);
1067 return(GetFirstImageInList(image));
1071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1075 % R e g i s t e r C M Y K I m a g e %
1079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1081 % RegisterCMYKImage() adds attributes for the CMYK image format to
1082 % the list of supported formats. The attributes include the image format
1083 % tag, a method to read and/or write the format, whether the format
1084 % supports the saving of more than one frame to the same file or blob,
1085 % whether the format supports native in-memory I/O, and a brief
1086 % description of the format.
1088 % The format of the RegisterCMYKImage method is:
1090 % size_t RegisterCMYKImage(void)
1093 ModuleExport size_t RegisterCMYKImage(void)
1098 entry=SetMagickInfo("CMYK");
1099 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1100 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1101 entry->raw=MagickTrue;
1102 entry->endian_support=MagickTrue;
1103 entry->description=ConstantString("Raw cyan, magenta, yellow, and black "
1105 entry->module=ConstantString("CMYK");
1106 (void) RegisterMagickInfo(entry);
1107 entry=SetMagickInfo("CMYKA");
1108 entry->decoder=(DecodeImageHandler *) ReadCMYKImage;
1109 entry->encoder=(EncodeImageHandler *) WriteCMYKImage;
1110 entry->raw=MagickTrue;
1111 entry->endian_support=MagickTrue;
1112 entry->description=ConstantString("Raw cyan, magenta, yellow, black, and "
1114 entry->module=ConstantString("CMYK");
1115 (void) RegisterMagickInfo(entry);
1116 return(MagickImageCoderSignature);
1120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1124 % U n r e g i s t e r C M Y K I m a g e %
1128 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1130 % UnregisterCMYKImage() removes format registrations made by the
1131 % CMYK module from the list of supported formats.
1133 % The format of the UnregisterCMYKImage method is:
1135 % UnregisterCMYKImage(void)
1138 ModuleExport void UnregisterCMYKImage(void)
1140 (void) UnregisterMagickInfo("CMYK");
1141 (void) UnregisterMagickInfo("CMYKA");
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149 % W r i t e C M Y K I m a g e %
1153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1155 % WriteCMYKImage() writes an image to a file in cyan, magenta, yellow, and
1156 % black,rasterfile format.
1158 % The format of the WriteCMYKImage method is:
1160 % MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1163 % A description of each parameter follows.
1165 % o image_info: the image info.
1167 % o image: The image.
1170 static MagickBooleanType WriteCMYKImage(const ImageInfo *image_info,
1196 Allocate memory for pixels.
1198 assert(image_info != (const ImageInfo *) NULL);
1199 assert(image_info->signature == MagickSignature);
1200 assert(image != (Image *) NULL);
1201 assert(image->signature == MagickSignature);
1202 if (image->debug != MagickFalse)
1203 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1204 if (image_info->interlace != PartitionInterlace)
1207 Open output image file.
1209 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1210 if (status == MagickFalse)
1213 quantum_type=CMYKQuantum;
1214 if (LocaleCompare(image_info->magick,"CMYKA") == 0)
1216 quantum_type=CMYKAQuantum;
1217 image->matte=MagickTrue;
1223 Convert MIFF to CMYK raster pixels.
1225 if (image->colorspace != CMYKColorspace)
1226 (void) TransformImageColorspace(image,CMYKColorspace);
1227 if ((LocaleCompare(image_info->magick,"CMYKA") == 0) &&
1228 (image->matte == MagickFalse))
1229 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,&image->exception);
1230 quantum_info=AcquireQuantumInfo(image_info,image);
1231 if (quantum_info == (QuantumInfo *) NULL)
1232 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1233 pixels=GetQuantumPixels(quantum_info);
1234 switch (image_info->interlace)
1240 No interlacing: CMYKCMYKCMYKCMYKCMYKCMYK...
1242 for (y=0; y < (ssize_t) image->rows; y++)
1244 register const Quantum
1247 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1248 if (p == (const Quantum *) NULL)
1250 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1251 quantum_type,pixels,&image->exception);
1252 count=WriteBlob(image,length,pixels);
1253 if (count != (ssize_t) length)
1255 if (image->previous == (Image *) NULL)
1257 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1259 if (status == MagickFalse)
1268 Line interlacing: CCC...MMM...YYY...KKK...CCC...MMM...YYY...KKK...
1270 for (y=0; y < (ssize_t) image->rows; y++)
1272 register const Quantum
1275 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1276 if (p == (const Quantum *) NULL)
1278 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1279 CyanQuantum,pixels,&image->exception);
1280 count=WriteBlob(image,length,pixels);
1281 if (count != (ssize_t) length)
1283 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1284 MagentaQuantum,pixels,&image->exception);
1285 count=WriteBlob(image,length,pixels);
1286 if (count != (ssize_t) length)
1288 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1289 YellowQuantum,pixels,&image->exception);
1290 count=WriteBlob(image,length,pixels);
1291 if (count != (ssize_t) length)
1293 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1294 BlackQuantum,pixels,&image->exception);
1295 count=WriteBlob(image,length,pixels);
1296 if (count != (ssize_t) length)
1298 if (quantum_type == CMYKAQuantum)
1300 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1301 AlphaQuantum,pixels,&image->exception);
1302 count=WriteBlob(image,length,pixels);
1303 if (count != (ssize_t) length)
1306 if (image->previous == (Image *) NULL)
1308 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1310 if (status == MagickFalse)
1316 case PlaneInterlace:
1319 Plane interlacing: CCCCCC...MMMMMM...YYYYYY...KKKKKK...
1321 for (y=0; y < (ssize_t) image->rows; y++)
1323 register const Quantum
1326 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1327 if (p == (const Quantum *) NULL)
1329 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1330 CyanQuantum,pixels,&image->exception);
1331 count=WriteBlob(image,length,pixels);
1332 if (count != (ssize_t) length)
1335 if (image->previous == (Image *) NULL)
1337 status=SetImageProgress(image,SaveImageTag,1,6);
1338 if (status == MagickFalse)
1341 for (y=0; y < (ssize_t) image->rows; y++)
1343 register const Quantum
1346 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1347 if (p == (const Quantum *) NULL)
1349 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1350 MagentaQuantum,pixels,&image->exception);
1351 count=WriteBlob(image,length,pixels);
1352 if (count != (ssize_t) length)
1355 if (image->previous == (Image *) NULL)
1357 status=SetImageProgress(image,SaveImageTag,2,6);
1358 if (status == MagickFalse)
1361 for (y=0; y < (ssize_t) image->rows; y++)
1363 register const Quantum
1366 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1367 if (p == (const Quantum *) NULL)
1369 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1370 YellowQuantum,pixels,&image->exception);
1371 count=WriteBlob(image,length,pixels);
1372 if (count != (ssize_t) length)
1375 if (image->previous == (Image *) NULL)
1377 status=SetImageProgress(image,SaveImageTag,3,6);
1378 if (status == MagickFalse)
1381 for (y=0; y < (ssize_t) image->rows; y++)
1383 register const Quantum
1386 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1387 if (p == (const Quantum *) NULL)
1389 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1390 BlackQuantum,pixels,&image->exception);
1391 count=WriteBlob(image,length,pixels);
1392 if (count != (ssize_t) length)
1395 if (image->previous == (Image *) NULL)
1397 status=SetImageProgress(image,SaveImageTag,4,6);
1398 if (status == MagickFalse)
1401 if (quantum_type == CMYKAQuantum)
1403 for (y=0; y < (ssize_t) image->rows; y++)
1405 register const Quantum
1408 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1409 if (p == (const Quantum *) NULL)
1411 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1412 AlphaQuantum,pixels,&image->exception);
1413 count=WriteBlob(image,length,pixels);
1414 if (count != (ssize_t) length)
1417 if (image->previous == (Image *) NULL)
1419 status=SetImageProgress(image,SaveImageTag,5,6);
1420 if (status == MagickFalse)
1424 if (image_info->interlace == PartitionInterlace)
1425 (void) CopyMagickString(image->filename,image_info->filename,
1427 if (image->previous == (Image *) NULL)
1429 status=SetImageProgress(image,SaveImageTag,6,6);
1430 if (status == MagickFalse)
1435 case PartitionInterlace:
1438 Partition interlacing: CCCCCC..., MMMMMM..., YYYYYY..., KKKKKK...
1440 AppendImageFormat("C",image->filename);
1441 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1442 AppendBinaryBlobMode,&image->exception);
1443 if (status == MagickFalse)
1445 for (y=0; y < (ssize_t) image->rows; y++)
1447 register const Quantum
1450 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1451 if (p == (const Quantum *) NULL)
1453 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1454 CyanQuantum,pixels,&image->exception);
1455 count=WriteBlob(image,length,pixels);
1456 if (count != (ssize_t) length)
1459 if (image->previous == (Image *) NULL)
1461 status=SetImageProgress(image,SaveImageTag,1,6);
1462 if (status == MagickFalse)
1465 (void) CloseBlob(image);
1466 AppendImageFormat("M",image->filename);
1467 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1468 AppendBinaryBlobMode,&image->exception);
1469 if (status == MagickFalse)
1471 for (y=0; y < (ssize_t) image->rows; y++)
1473 register const Quantum
1476 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1477 if (p == (const Quantum *) NULL)
1479 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1480 MagentaQuantum,pixels,&image->exception);
1481 count=WriteBlob(image,length,pixels);
1482 if (count != (ssize_t) length)
1485 if (image->previous == (Image *) NULL)
1487 status=SetImageProgress(image,SaveImageTag,2,6);
1488 if (status == MagickFalse)
1491 (void) CloseBlob(image);
1492 AppendImageFormat("Y",image->filename);
1493 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1494 AppendBinaryBlobMode,&image->exception);
1495 if (status == MagickFalse)
1497 for (y=0; y < (ssize_t) image->rows; y++)
1499 register const Quantum
1502 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1503 if (p == (const Quantum *) NULL)
1505 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1506 YellowQuantum,pixels,&image->exception);
1507 count=WriteBlob(image,length,pixels);
1508 if (count != (ssize_t) length)
1511 if (image->previous == (Image *) NULL)
1513 status=SetImageProgress(image,SaveImageTag,3,6);
1514 if (status == MagickFalse)
1517 (void) CloseBlob(image);
1518 AppendImageFormat("K",image->filename);
1519 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1520 AppendBinaryBlobMode,&image->exception);
1521 if (status == MagickFalse)
1523 for (y=0; y < (ssize_t) image->rows; y++)
1525 register const Quantum
1528 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1529 if (p == (const Quantum *) NULL)
1531 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1532 BlackQuantum,pixels,&image->exception);
1533 count=WriteBlob(image,length,pixels);
1534 if (count != (ssize_t) length)
1537 if (image->previous == (Image *) NULL)
1539 status=SetImageProgress(image,SaveImageTag,4,6);
1540 if (status == MagickFalse)
1543 if (quantum_type == CMYKAQuantum)
1545 (void) CloseBlob(image);
1546 AppendImageFormat("A",image->filename);
1547 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1548 AppendBinaryBlobMode,&image->exception);
1549 if (status == MagickFalse)
1551 for (y=0; y < (ssize_t) image->rows; y++)
1553 register const Quantum
1556 p=GetVirtualPixels(image,0,y,image->columns,1,
1558 if (p == (const Quantum *) NULL)
1560 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1561 AlphaQuantum,pixels,&image->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);