2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw RGB 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://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/colorspace-private.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/magick.h"
56 #include "MagickCore/memory_.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/statistic.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/utility.h"
70 static MagickBooleanType
71 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % R e a d R G B I m a g e %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
85 % it. It allocates the memory necessary for the new Image structure and
86 % returns a pointer to the new image.
88 % The format of the ReadRGBImage method is:
90 % Image *ReadRGBImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
93 % A description of each parameter follows:
95 % o image_info: the image info.
97 % o exception: return any errors or warnings in this structure.
100 static Image *ReadRGBImage(const ImageInfo *image_info,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 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,(MagickSizeType) image->offset) == MagickFalse)
153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
157 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
159 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
161 if(canvas_image == (Image *) NULL)
162 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
163 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
165 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
166 if (quantum_info == (QuantumInfo *) NULL)
168 canvas_image=DestroyImage(canvas_image);
169 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
171 quantum_type=RGBQuantum;
172 if (LocaleCompare(image_info->magick,"RGBA") == 0)
174 quantum_type=RGBAQuantum;
175 image->alpha_trait=BlendPixelTrait;
176 canvas_image->alpha_trait=BlendPixelTrait;
178 if (LocaleCompare(image_info->magick,"RGBO") == 0)
180 quantum_type=RGBOQuantum;
181 image->alpha_trait=BlendPixelTrait;
182 canvas_image->alpha_trait=BlendPixelTrait;
184 pixels=(const unsigned char *) NULL;
185 if (image_info->number_scenes != 0)
186 while (image->scene < image_info->scene)
192 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
193 for (y=0; y < (ssize_t) image->rows; y++)
195 pixels=(const unsigned char *) ReadBlobStream(image,length,
196 GetQuantumPixels(quantum_info),&count);
197 if (count != (ssize_t) length)
208 Read pixels to virtual canvas image then push to image.
210 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
211 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
213 status=SetImageExtent(image,image->columns,image->rows,exception);
214 if (status == MagickFalse)
216 switch (image_info->interlace)
222 No interlacing: RGBRGBRGBRGBRGBRGB...
226 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
227 pixels=(const unsigned char *) ReadBlobStream(image,length,
228 GetQuantumPixels(quantum_info),&count);
230 for (y=0; y < (ssize_t) image->extract_info.height; y++)
232 register const Quantum
241 if (count != (ssize_t) length)
244 ThrowFileException(exception,CorruptImageError,
245 "UnexpectedEndOfFile",image->filename);
248 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
250 if (q == (Quantum *) NULL)
252 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
253 quantum_info,quantum_type,pixels,exception);
254 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
256 if (((y-image->extract_info.y) >= 0) &&
257 ((y-image->extract_info.y) < (ssize_t) image->rows))
259 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
260 canvas_image->columns,1,exception);
261 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
262 image->columns,1,exception);
263 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
265 for (x=0; x < (ssize_t) image->columns; x++)
267 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
268 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
269 SetPixelBlue(image,GetPixelBlue(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);
303 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
305 if (LocaleCompare(image_info->magick,"RGBO") == 0)
306 quantum_types[3]=OpacityQuantum;
309 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
310 pixels=(const unsigned char *) ReadBlobStream(image,length,
311 GetQuantumPixels(quantum_info),&count);
313 for (y=0; y < (ssize_t) image->extract_info.height; y++)
315 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
317 register const Quantum
326 if (count != (ssize_t) length)
329 ThrowFileException(exception,CorruptImageError,
330 "UnexpectedEndOfFile",image->filename);
333 quantum_type=quantum_types[i];
334 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
336 if (q == (Quantum *) NULL)
338 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
339 quantum_info,quantum_type,pixels,exception);
340 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
342 if (((y-image->extract_info.y) >= 0) &&
343 ((y-image->extract_info.y) < (ssize_t) image->rows))
345 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
346 0,canvas_image->columns,1,exception);
347 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
348 image->columns,1,exception);
349 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
351 for (x=0; x < (ssize_t) image->columns; x++)
353 switch (quantum_type)
357 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
362 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
367 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
372 SetPixelOpacity(image,GetPixelOpacity(canvas_image,p),q);
377 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
383 p+=GetPixelChannels(canvas_image);
384 q+=GetPixelChannels(image);
386 if (SyncAuthenticPixels(image,exception) == MagickFalse)
389 pixels=(const unsigned char *) ReadBlobStream(image,length,
390 GetQuantumPixels(quantum_info),&count);
392 if (image->previous == (Image *) NULL)
394 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
396 if (status == MagickFalse)
405 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
409 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
410 pixels=(const unsigned char *) ReadBlobStream(image,length,
411 GetQuantumPixels(quantum_info),&count);
413 for (y=0; y < (ssize_t) image->extract_info.height; y++)
415 register const Quantum
424 if (count != (ssize_t) length)
427 ThrowFileException(exception,CorruptImageError,
428 "UnexpectedEndOfFile",image->filename);
431 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
433 if (q == (Quantum *) NULL)
435 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
436 quantum_info,RedQuantum,pixels,exception);
437 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
439 if (((y-image->extract_info.y) >= 0) &&
440 ((y-image->extract_info.y) < (ssize_t) image->rows))
442 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
443 canvas_image->columns,1,exception);
444 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
445 image->columns,1,exception);
446 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
448 for (x=0; x < (ssize_t) image->columns; x++)
450 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
451 p+=GetPixelChannels(canvas_image);
452 q+=GetPixelChannels(image);
454 if (SyncAuthenticPixels(image,exception) == MagickFalse)
457 pixels=(const unsigned char *) ReadBlobStream(image,length,
458 GetQuantumPixels(quantum_info),&count);
460 if (image->previous == (Image *) NULL)
462 status=SetImageProgress(image,LoadImageTag,1,6);
463 if (status == MagickFalse)
466 for (y=0; y < (ssize_t) image->extract_info.height; y++)
468 register const Quantum
477 if (count != (ssize_t) length)
480 ThrowFileException(exception,CorruptImageError,
481 "UnexpectedEndOfFile",image->filename);
484 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
486 if (q == (Quantum *) NULL)
488 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
489 quantum_info,GreenQuantum,pixels,exception);
490 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
492 if (((y-image->extract_info.y) >= 0) &&
493 ((y-image->extract_info.y) < (ssize_t) image->rows))
495 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
496 canvas_image->columns,1,exception);
497 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
498 image->columns,1,exception);
499 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
501 for (x=0; x < (ssize_t) image->columns; x++)
503 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
504 p+=GetPixelChannels(canvas_image);
505 q+=GetPixelChannels(image);
507 if (SyncAuthenticPixels(image,exception) == MagickFalse)
510 pixels=(const unsigned char *) ReadBlobStream(image,length,
511 GetQuantumPixels(quantum_info),&count);
513 if (image->previous == (Image *) NULL)
515 status=SetImageProgress(image,LoadImageTag,2,6);
516 if (status == MagickFalse)
519 for (y=0; y < (ssize_t) image->extract_info.height; y++)
521 register const Quantum
530 if (count != (ssize_t) length)
533 ThrowFileException(exception,CorruptImageError,
534 "UnexpectedEndOfFile",image->filename);
537 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
539 if (q == (Quantum *) NULL)
541 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
542 quantum_info,BlueQuantum,pixels,exception);
543 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
545 if (((y-image->extract_info.y) >= 0) &&
546 ((y-image->extract_info.y) < (ssize_t) image->rows))
548 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
549 canvas_image->columns,1,exception);
550 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
551 image->columns,1,exception);
552 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
554 for (x=0; x < (ssize_t) image->columns; x++)
556 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
557 p+=GetPixelChannels(canvas_image);
558 q+=GetPixelChannels(image);
560 if (SyncAuthenticPixels(image,exception) == MagickFalse)
563 pixels=(const unsigned char *) ReadBlobStream(image,length,
564 GetQuantumPixels(quantum_info),&count);
566 if (image->previous == (Image *) NULL)
568 status=SetImageProgress(image,LoadImageTag,4,6);
569 if (status == MagickFalse)
572 if (image->alpha_trait != UndefinedPixelTrait)
574 for (y=0; y < (ssize_t) image->extract_info.height; y++)
576 register const Quantum
585 if (count != (ssize_t) length)
588 ThrowFileException(exception,CorruptImageError,
589 "UnexpectedEndOfFile",image->filename);
592 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
594 if (q == (Quantum *) NULL)
596 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
597 quantum_info,AlphaQuantum,pixels,exception);
598 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
600 if (((y-image->extract_info.y) >= 0) &&
601 ((y-image->extract_info.y) < (ssize_t) image->rows))
603 p=GetVirtualPixels(canvas_image,
604 canvas_image->extract_info.x,0,canvas_image->columns,1,
606 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
607 image->columns,1,exception);
608 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
610 for (x=0; x < (ssize_t) image->columns; x++)
612 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
613 p+=GetPixelChannels(canvas_image);
614 q+=GetPixelChannels(image);
616 if (SyncAuthenticPixels(image,exception) == MagickFalse)
619 pixels=(const unsigned char *) ReadBlobStream(image,length,
620 GetQuantumPixels(quantum_info),&count);
622 if (image->previous == (Image *) NULL)
624 status=SetImageProgress(image,LoadImageTag,5,6);
625 if (status == MagickFalse)
629 if (image->previous == (Image *) NULL)
631 status=SetImageProgress(image,LoadImageTag,6,6);
632 if (status == MagickFalse)
637 case PartitionInterlace:
640 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
642 AppendImageFormat("R",image->filename);
643 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
644 if (status == MagickFalse)
646 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
649 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
653 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
654 for (i=0; i < (ssize_t) scene; i++)
656 for (y=0; y < (ssize_t) image->extract_info.height; y++)
658 pixels=(const unsigned char *) ReadBlobStream(image,length,
659 GetQuantumPixels(quantum_info),&count);
660 if (count != (ssize_t) length)
663 if (count != (ssize_t) length)
666 pixels=(const unsigned char *) ReadBlobStream(image,length,
667 GetQuantumPixels(quantum_info),&count);
668 for (y=0; y < (ssize_t) image->extract_info.height; y++)
670 register const Quantum
679 if (count != (ssize_t) length)
682 ThrowFileException(exception,CorruptImageError,
683 "UnexpectedEndOfFile",image->filename);
686 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
688 if (q == (Quantum *) NULL)
690 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
691 quantum_info,RedQuantum,pixels,exception);
692 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
694 if (((y-image->extract_info.y) >= 0) &&
695 ((y-image->extract_info.y) < (ssize_t) image->rows))
697 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
698 canvas_image->columns,1,exception);
699 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
700 image->columns,1,exception);
701 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
703 for (x=0; x < (ssize_t) image->columns; x++)
705 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
706 p+=GetPixelChannels(canvas_image);
707 q+=GetPixelChannels(image);
709 if (SyncAuthenticPixels(image,exception) == MagickFalse)
712 pixels=(const unsigned char *) ReadBlobStream(image,length,
713 GetQuantumPixels(quantum_info),&count);
715 if (image->previous == (Image *) NULL)
717 status=SetImageProgress(image,LoadImageTag,1,5);
718 if (status == MagickFalse)
721 (void) CloseBlob(image);
722 AppendImageFormat("G",image->filename);
723 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
724 if (status == MagickFalse)
726 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
727 for (i=0; i < (ssize_t) scene; i++)
729 for (y=0; y < (ssize_t) image->extract_info.height; y++)
731 pixels=(const unsigned char *) ReadBlobStream(image,length,
732 GetQuantumPixels(quantum_info),&count);
733 if (count != (ssize_t) length)
736 if (count != (ssize_t) length)
739 pixels=(const unsigned char *) ReadBlobStream(image,length,
740 GetQuantumPixels(quantum_info),&count);
741 for (y=0; y < (ssize_t) image->extract_info.height; y++)
743 register const Quantum
752 if (count != (ssize_t) length)
755 ThrowFileException(exception,CorruptImageError,
756 "UnexpectedEndOfFile",image->filename);
759 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
761 if (q == (Quantum *) NULL)
763 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
764 quantum_info,GreenQuantum,pixels,exception);
765 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
767 if (((y-image->extract_info.y) >= 0) &&
768 ((y-image->extract_info.y) < (ssize_t) image->rows))
770 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
771 canvas_image->columns,1,exception);
772 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
773 image->columns,1,exception);
774 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
776 for (x=0; x < (ssize_t) image->columns; x++)
778 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
779 p+=GetPixelChannels(canvas_image);
780 q+=GetPixelChannels(image);
782 if (SyncAuthenticPixels(image,exception) == MagickFalse)
785 pixels=(const unsigned char *) ReadBlobStream(image,length,
786 GetQuantumPixels(quantum_info),&count);
788 if (image->previous == (Image *) NULL)
790 status=SetImageProgress(image,LoadImageTag,2,5);
791 if (status == MagickFalse)
794 (void) CloseBlob(image);
795 AppendImageFormat("B",image->filename);
796 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
797 if (status == MagickFalse)
799 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
800 for (i=0; i < (ssize_t) scene; i++)
802 for (y=0; y < (ssize_t) image->extract_info.height; y++)
804 pixels=(const unsigned char *) ReadBlobStream(image,length,
805 GetQuantumPixels(quantum_info),&count);
806 if (count != (ssize_t) length)
809 if (count != (ssize_t) length)
812 pixels=(const unsigned char *) ReadBlobStream(image,length,
813 GetQuantumPixels(quantum_info),&count);
814 for (y=0; y < (ssize_t) image->extract_info.height; y++)
816 register const Quantum
825 if (count != (ssize_t) length)
828 ThrowFileException(exception,CorruptImageError,
829 "UnexpectedEndOfFile",image->filename);
832 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
834 if (q == (Quantum *) NULL)
836 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
837 quantum_info,BlueQuantum,pixels,exception);
838 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
840 if (((y-image->extract_info.y) >= 0) &&
841 ((y-image->extract_info.y) < (ssize_t) image->rows))
843 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
844 canvas_image->columns,1,exception);
845 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
846 image->columns,1,exception);
847 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
849 for (x=0; x < (ssize_t) image->columns; x++)
851 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
852 p+=GetPixelChannels(canvas_image);
853 q+=GetPixelChannels(image);
855 if (SyncAuthenticPixels(image,exception) == MagickFalse)
858 pixels=(const unsigned char *) ReadBlobStream(image,length,
859 GetQuantumPixels(quantum_info),&count);
861 if (image->previous == (Image *) NULL)
863 status=SetImageProgress(image,LoadImageTag,3,5);
864 if (status == MagickFalse)
867 if (image->alpha_trait != UndefinedPixelTrait)
869 (void) CloseBlob(image);
870 AppendImageFormat("A",image->filename);
871 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
872 if (status == MagickFalse)
874 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
875 for (i=0; i < (ssize_t) scene; i++)
877 for (y=0; y < (ssize_t) image->extract_info.height; y++)
879 pixels=(const unsigned char *) ReadBlobStream(image,length,
880 GetQuantumPixels(quantum_info),&count);
881 if (count != (ssize_t) length)
884 if (count != (ssize_t) length)
887 pixels=(const unsigned char *) ReadBlobStream(image,length,
888 GetQuantumPixels(quantum_info),&count);
889 for (y=0; y < (ssize_t) image->extract_info.height; y++)
891 register const Quantum
900 if (count != (ssize_t) length)
903 ThrowFileException(exception,CorruptImageError,
904 "UnexpectedEndOfFile",image->filename);
907 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
909 if (q == (Quantum *) NULL)
911 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
912 quantum_info,BlueQuantum,pixels,exception);
913 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
915 if (((y-image->extract_info.y) >= 0) &&
916 ((y-image->extract_info.y) < (ssize_t) image->rows))
918 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
919 0,canvas_image->columns,1,exception);
920 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
921 image->columns,1,exception);
922 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
924 for (x=0; x < (ssize_t) image->columns; x++)
926 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
927 p+=GetPixelChannels(canvas_image);
928 q+=GetPixelChannels(image);
930 if (SyncAuthenticPixels(image,exception) == MagickFalse)
933 pixels=(const unsigned char *) ReadBlobStream(image,length,
934 GetQuantumPixels(quantum_info),&count);
936 if (image->previous == (Image *) NULL)
938 status=SetImageProgress(image,LoadImageTag,4,5);
939 if (status == MagickFalse)
943 (void) CloseBlob(image);
944 if (image->previous == (Image *) NULL)
946 status=SetImageProgress(image,LoadImageTag,5,5);
947 if (status == MagickFalse)
953 if (status == MagickFalse)
955 SetQuantumImageType(image,quantum_type);
957 Proceed to next image.
959 if (image_info->number_scenes != 0)
960 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
962 if (count == (ssize_t) length)
965 Allocate next image structure.
967 AcquireNextImage(image_info,image,exception);
968 if (GetNextImageInList(image) == (Image *) NULL)
973 image=SyncNextImageInList(image);
974 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
976 if (status == MagickFalse)
980 } while (count == (ssize_t) length);
981 quantum_info=DestroyQuantumInfo(quantum_info);
982 canvas_image=DestroyImage(canvas_image);
983 (void) CloseBlob(image);
984 if (status == MagickFalse)
985 return(DestroyImageList(image));
986 return(GetFirstImageInList(image));
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
994 % R e g i s t e r R G B I m a g e %
998 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000 % RegisterRGBImage() adds attributes for the RGB image format to
1001 % the list of supported formats. The attributes include the image format
1002 % tag, a method to read and/or write the format, whether the format
1003 % supports the saving of more than one frame to the same file or blob,
1004 % whether the format supports native in-memory I/O, and a brief
1005 % description of the format.
1007 % The format of the RegisterRGBImage method is:
1009 % size_t RegisterRGBImage(void)
1012 ModuleExport size_t RegisterRGBImage(void)
1017 entry=AcquireMagickInfo("RGB","RGB",
1018 "Raw red, green, and blue samples");
1019 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1020 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1021 entry->flags|=CoderRawSupportFlag;
1022 entry->flags|=CoderEndianSupportFlag;
1023 (void) RegisterMagickInfo(entry);
1024 entry=AcquireMagickInfo("RGB","RGBA",
1025 "Raw red, green, blue, and alpha samples");
1026 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1027 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1028 entry->flags|=CoderRawSupportFlag;
1029 entry->flags|=CoderEndianSupportFlag;
1030 (void) RegisterMagickInfo(entry);
1031 entry=AcquireMagickInfo("RGB","RGBO",
1032 "Raw red, green, blue, and opacity samples");
1033 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1034 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1035 entry->flags|=CoderRawSupportFlag;
1036 entry->flags|=CoderEndianSupportFlag;
1037 (void) RegisterMagickInfo(entry);
1038 return(MagickImageCoderSignature);
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 % U n r e g i s t e r R G B I m a g e %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052 % UnregisterRGBImage() removes format registrations made by the RGB module
1053 % from the list of supported formats.
1055 % The format of the UnregisterRGBImage method is:
1057 % UnregisterRGBImage(void)
1060 ModuleExport void UnregisterRGBImage(void)
1062 (void) UnregisterMagickInfo("RGBO");
1063 (void) UnregisterMagickInfo("RGBA");
1064 (void) UnregisterMagickInfo("RGB");
1068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1072 % W r i t e R G B I m a g e %
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1078 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1079 % rasterfile format.
1081 % The format of the WriteRGBImage method is:
1083 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1084 % Image *image,ExceptionInfo *exception)
1086 % A description of each parameter follows.
1088 % o image_info: the image info.
1090 % o image: The image.
1092 % o exception: return any errors or warnings in this structure.
1095 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1096 Image *image,ExceptionInfo *exception)
1122 Allocate memory for pixels.
1124 assert(image_info != (const ImageInfo *) NULL);
1125 assert(image_info->signature == MagickCoreSignature);
1126 assert(image != (Image *) NULL);
1127 assert(image->signature == MagickCoreSignature);
1128 if (image->debug != MagickFalse)
1129 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1130 if (image_info->interlace != PartitionInterlace)
1133 Open output image file.
1135 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1136 if (status == MagickFalse)
1139 quantum_type=RGBQuantum;
1140 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1141 quantum_type=RGBAQuantum;
1142 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1143 quantum_type=RGBOQuantum;
1145 imageListLength=GetImageListLength(image);
1149 Convert MIFF to RGB raster pixels.
1151 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1152 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1153 (image->alpha_trait == UndefinedPixelTrait))
1154 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1155 quantum_info=AcquireQuantumInfo(image_info,image);
1156 if (quantum_info == (QuantumInfo *) NULL)
1157 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1158 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1159 switch (image_info->interlace)
1165 No interlacing: RGBRGBRGBRGBRGBRGB...
1167 for (y=0; y < (ssize_t) image->rows; y++)
1169 register const Quantum
1172 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1173 if (p == (const Quantum *) NULL)
1175 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1176 quantum_type,pixels,exception);
1177 count=WriteBlob(image,length,pixels);
1178 if (count != (ssize_t) length)
1180 if (image->previous == (Image *) NULL)
1182 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1184 if (status == MagickFalse)
1193 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1195 for (y=0; y < (ssize_t) image->rows; y++)
1197 register const Quantum
1200 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1201 if (p == (const Quantum *) NULL)
1203 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1204 RedQuantum,pixels,exception);
1205 count=WriteBlob(image,length,pixels);
1206 if (count != (ssize_t) length)
1208 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1209 GreenQuantum,pixels,exception);
1210 count=WriteBlob(image,length,pixels);
1211 if (count != (ssize_t) length)
1213 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1214 BlueQuantum,pixels,exception);
1215 count=WriteBlob(image,length,pixels);
1216 if (count != (ssize_t) length)
1218 if (quantum_type == RGBAQuantum)
1220 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1221 AlphaQuantum,pixels,exception);
1222 count=WriteBlob(image,length,pixels);
1223 if (count != (ssize_t) length)
1226 if (quantum_type == RGBOQuantum)
1228 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1229 OpacityQuantum,pixels,exception);
1230 count=WriteBlob(image,length,pixels);
1231 if (count != (ssize_t) length)
1234 if (image->previous == (Image *) NULL)
1236 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1238 if (status == MagickFalse)
1244 case PlaneInterlace:
1247 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1249 for (y=0; y < (ssize_t) image->rows; y++)
1251 register const Quantum
1254 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1255 if (p == (const Quantum *) NULL)
1257 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1258 RedQuantum,pixels,exception);
1259 count=WriteBlob(image,length,pixels);
1260 if (count != (ssize_t) length)
1263 if (image->previous == (Image *) NULL)
1265 status=SetImageProgress(image,SaveImageTag,1,6);
1266 if (status == MagickFalse)
1269 for (y=0; y < (ssize_t) image->rows; y++)
1271 register const Quantum
1274 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1275 if (p == (const Quantum *) NULL)
1277 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1278 GreenQuantum,pixels,exception);
1279 count=WriteBlob(image,length,pixels);
1280 if (count != (ssize_t) length)
1283 if (image->previous == (Image *) NULL)
1285 status=SetImageProgress(image,SaveImageTag,2,6);
1286 if (status == MagickFalse)
1289 for (y=0; y < (ssize_t) image->rows; y++)
1291 register const Quantum
1294 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1295 if (p == (const Quantum *) NULL)
1297 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1298 BlueQuantum,pixels,exception);
1299 count=WriteBlob(image,length,pixels);
1300 if (count != (ssize_t) length)
1303 if (image->previous == (Image *) NULL)
1305 status=SetImageProgress(image,SaveImageTag,3,6);
1306 if (status == MagickFalse)
1309 if (quantum_type == RGBAQuantum)
1311 for (y=0; y < (ssize_t) image->rows; y++)
1313 register const Quantum
1316 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1317 if (p == (const Quantum *) NULL)
1319 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1320 AlphaQuantum,pixels,exception);
1321 count=WriteBlob(image,length,pixels);
1322 if (count != (ssize_t) length)
1325 if (image->previous == (Image *) NULL)
1327 status=SetImageProgress(image,SaveImageTag,5,6);
1328 if (status == MagickFalse)
1332 if (image_info->interlace == PartitionInterlace)
1333 (void) CopyMagickString(image->filename,image_info->filename,
1335 if (image->previous == (Image *) NULL)
1337 status=SetImageProgress(image,SaveImageTag,6,6);
1338 if (status == MagickFalse)
1343 case PartitionInterlace:
1346 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1348 AppendImageFormat("R",image->filename);
1349 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1350 AppendBinaryBlobMode,exception);
1351 if (status == MagickFalse)
1353 for (y=0; y < (ssize_t) image->rows; y++)
1355 register const Quantum
1358 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1359 if (p == (const Quantum *) NULL)
1361 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1362 RedQuantum,pixels,exception);
1363 count=WriteBlob(image,length,pixels);
1364 if (count != (ssize_t) length)
1367 if (image->previous == (Image *) NULL)
1369 status=SetImageProgress(image,SaveImageTag,1,6);
1370 if (status == MagickFalse)
1373 (void) CloseBlob(image);
1374 AppendImageFormat("G",image->filename);
1375 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1376 AppendBinaryBlobMode,exception);
1377 if (status == MagickFalse)
1379 for (y=0; y < (ssize_t) image->rows; y++)
1381 register const Quantum
1384 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1385 if (p == (const Quantum *) NULL)
1387 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1388 GreenQuantum,pixels,exception);
1389 count=WriteBlob(image,length,pixels);
1390 if (count != (ssize_t) length)
1393 if (image->previous == (Image *) NULL)
1395 status=SetImageProgress(image,SaveImageTag,2,6);
1396 if (status == MagickFalse)
1399 (void) CloseBlob(image);
1400 AppendImageFormat("B",image->filename);
1401 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1402 AppendBinaryBlobMode,exception);
1403 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 BlueQuantum,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 if (quantum_type == RGBAQuantum)
1427 (void) CloseBlob(image);
1428 AppendImageFormat("A",image->filename);
1429 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1430 AppendBinaryBlobMode,exception);
1431 if (status == MagickFalse)
1433 for (y=0; y < (ssize_t) image->rows; y++)
1435 register const Quantum
1438 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1439 if (p == (const Quantum *) NULL)
1441 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1442 AlphaQuantum,pixels,exception);
1443 count=WriteBlob(image,length,pixels);
1444 if (count != (ssize_t) length)
1447 if (image->previous == (Image *) NULL)
1449 status=SetImageProgress(image,SaveImageTag,5,6);
1450 if (status == MagickFalse)
1454 (void) CloseBlob(image);
1455 (void) CopyMagickString(image->filename,image_info->filename,
1457 if (image->previous == (Image *) NULL)
1459 status=SetImageProgress(image,SaveImageTag,6,6);
1460 if (status == MagickFalse)
1466 quantum_info=DestroyQuantumInfo(quantum_info);
1467 if (GetNextImageInList(image) == (Image *) NULL)
1469 image=SyncNextImageInList(image);
1470 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
1471 if (status == MagickFalse)
1473 } while (image_info->adjoin != MagickFalse);
1474 (void) CloseBlob(image);