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://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/channel.h"
47 #include "MagickCore/colorspace.h"
48 #include "MagickCore/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,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)
167 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
168 quantum_type=RGBQuantum;
169 if (LocaleCompare(image_info->magick,"RGBA") == 0)
171 quantum_type=RGBAQuantum;
172 image->alpha_trait=BlendPixelTrait;
173 canvas_image->alpha_trait=BlendPixelTrait;
175 if (LocaleCompare(image_info->magick,"RGBO") == 0)
177 quantum_type=RGBOQuantum;
178 image->alpha_trait=BlendPixelTrait;
179 canvas_image->alpha_trait=BlendPixelTrait;
181 pixels=(const unsigned char *) NULL;
182 if (image_info->number_scenes != 0)
183 while (image->scene < image_info->scene)
189 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
190 for (y=0; y < (ssize_t) image->rows; y++)
192 pixels=(const unsigned char *) ReadBlobStream(image,length,
193 GetQuantumPixels(quantum_info),&count);
194 if (count != (ssize_t) length)
204 Read pixels to virtual canvas image then push to image.
206 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
207 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
209 status=SetImageExtent(image,image->columns,image->rows,exception);
210 if (status == MagickFalse)
211 return(DestroyImageList(image));
212 switch (image_info->interlace)
218 No interlacing: RGBRGBRGBRGBRGBRGB...
222 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
223 pixels=(const unsigned char *) ReadBlobStream(image,length,
224 GetQuantumPixels(quantum_info),&count);
225 if (count != (ssize_t) length)
228 for (y=0; y < (ssize_t) image->extract_info.height; y++)
230 register const Quantum
239 if (count != (ssize_t) length)
241 ThrowFileException(exception,CorruptImageError,
242 "UnexpectedEndOfFile",image->filename);
245 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
247 if (q == (Quantum *) NULL)
249 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
250 quantum_info,quantum_type,pixels,exception);
251 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
253 if (((y-image->extract_info.y) >= 0) &&
254 ((y-image->extract_info.y) < (ssize_t) image->rows))
256 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
257 canvas_image->columns,1,exception);
258 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
259 image->columns,1,exception);
260 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
262 for (x=0; x < (ssize_t) image->columns; x++)
264 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
265 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
266 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
267 SetPixelAlpha(image,OpaqueAlpha,q);
268 if (image->alpha_trait != UndefinedPixelTrait)
269 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
270 p+=GetPixelChannels(canvas_image);
271 q+=GetPixelChannels(image);
273 if (SyncAuthenticPixels(image,exception) == MagickFalse)
276 if (image->previous == (Image *) NULL)
278 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
280 if (status == MagickFalse)
283 pixels=(const unsigned char *) ReadBlobStream(image,length,
284 GetQuantumPixels(quantum_info),&count);
285 if (count != (ssize_t) length)
302 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
304 if (LocaleCompare(image_info->magick,"RGBO") == 0)
305 quantum_types[3]=OpacityQuantum;
308 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
309 pixels=(const unsigned char *) ReadBlobStream(image,length,
310 GetQuantumPixels(quantum_info),&count);
311 if (count != (ssize_t) length)
314 for (y=0; y < (ssize_t) image->extract_info.height; y++)
316 register const Quantum
325 if (count != (ssize_t) length)
327 ThrowFileException(exception,CorruptImageError,
328 "UnexpectedEndOfFile",image->filename);
331 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
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 SetPixelAlpha(image,GetPixelAlpha(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);
391 if (count != (ssize_t) length)
394 if (image->previous == (Image *) NULL)
396 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
398 if (status == MagickFalse)
407 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
411 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
412 pixels=(const unsigned char *) ReadBlobStream(image,length,
413 GetQuantumPixels(quantum_info),&count);
414 if (count != (ssize_t) length)
417 for (y=0; y < (ssize_t) image->extract_info.height; y++)
419 register const Quantum
428 if (count != (ssize_t) length)
430 ThrowFileException(exception,CorruptImageError,
431 "UnexpectedEndOfFile",image->filename);
434 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
436 if (q == (Quantum *) NULL)
438 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
439 quantum_info,RedQuantum,pixels,exception);
440 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
442 if (((y-image->extract_info.y) >= 0) &&
443 ((y-image->extract_info.y) < (ssize_t) image->rows))
445 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
446 canvas_image->columns,1,exception);
447 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
448 image->columns,1,exception);
449 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
451 for (x=0; x < (ssize_t) image->columns; x++)
453 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
454 p+=GetPixelChannels(canvas_image);
455 q+=GetPixelChannels(image);
457 if (SyncAuthenticPixels(image,exception) == MagickFalse)
460 pixels=(const unsigned char *) ReadBlobStream(image,length,
461 GetQuantumPixels(quantum_info),&count);
462 if (count != (ssize_t) length)
465 if (image->previous == (Image *) NULL)
467 status=SetImageProgress(image,LoadImageTag,1,6);
468 if (status == MagickFalse)
471 for (y=0; y < (ssize_t) image->extract_info.height; y++)
473 register const Quantum
482 if (count != (ssize_t) length)
484 ThrowFileException(exception,CorruptImageError,
485 "UnexpectedEndOfFile",image->filename);
488 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
490 if (q == (Quantum *) NULL)
492 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
493 quantum_info,GreenQuantum,pixels,exception);
494 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
496 if (((y-image->extract_info.y) >= 0) &&
497 ((y-image->extract_info.y) < (ssize_t) image->rows))
499 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
500 canvas_image->columns,1,exception);
501 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
502 image->columns,1,exception);
503 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
505 for (x=0; x < (ssize_t) image->columns; x++)
507 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
508 p+=GetPixelChannels(canvas_image);
509 q+=GetPixelChannels(image);
511 if (SyncAuthenticPixels(image,exception) == MagickFalse)
514 pixels=(const unsigned char *) ReadBlobStream(image,length,
515 GetQuantumPixels(quantum_info),&count);
516 if (count != (ssize_t) length)
519 if (image->previous == (Image *) NULL)
521 status=SetImageProgress(image,LoadImageTag,2,6);
522 if (status == MagickFalse)
525 for (y=0; y < (ssize_t) image->extract_info.height; y++)
527 register const Quantum
536 if (count != (ssize_t) length)
538 ThrowFileException(exception,CorruptImageError,
539 "UnexpectedEndOfFile",image->filename);
542 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
544 if (q == (Quantum *) NULL)
546 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
547 quantum_info,BlueQuantum,pixels,exception);
548 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
550 if (((y-image->extract_info.y) >= 0) &&
551 ((y-image->extract_info.y) < (ssize_t) image->rows))
553 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
554 canvas_image->columns,1,exception);
555 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
556 image->columns,1,exception);
557 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
559 for (x=0; x < (ssize_t) image->columns; x++)
561 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
562 p+=GetPixelChannels(canvas_image);
563 q+=GetPixelChannels(image);
565 if (SyncAuthenticPixels(image,exception) == MagickFalse)
568 pixels=(const unsigned char *) ReadBlobStream(image,length,
569 GetQuantumPixels(quantum_info),&count);
570 if (count != (ssize_t) length)
573 if (image->previous == (Image *) NULL)
575 status=SetImageProgress(image,LoadImageTag,3,6);
576 if (status == MagickFalse)
579 if (image->previous == (Image *) NULL)
581 status=SetImageProgress(image,LoadImageTag,4,6);
582 if (status == MagickFalse)
585 if (image->alpha_trait != UndefinedPixelTrait)
587 for (y=0; y < (ssize_t) image->extract_info.height; y++)
589 register const Quantum
598 if (count != (ssize_t) length)
600 ThrowFileException(exception,CorruptImageError,
601 "UnexpectedEndOfFile",image->filename);
604 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
606 if (q == (Quantum *) NULL)
608 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
609 quantum_info,AlphaQuantum,pixels,exception);
610 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
612 if (((y-image->extract_info.y) >= 0) &&
613 ((y-image->extract_info.y) < (ssize_t) image->rows))
615 p=GetVirtualPixels(canvas_image,
616 canvas_image->extract_info.x,0,canvas_image->columns,1,
618 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
619 image->columns,1,exception);
620 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
622 for (x=0; x < (ssize_t) image->columns; x++)
624 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
625 p+=GetPixelChannels(canvas_image);
626 q+=GetPixelChannels(image);
628 if (SyncAuthenticPixels(image,exception) == MagickFalse)
631 pixels=(const unsigned char *) ReadBlobStream(image,length,
632 GetQuantumPixels(quantum_info),&count);
633 if (count != (ssize_t) length)
636 if (image->previous == (Image *) NULL)
638 status=SetImageProgress(image,LoadImageTag,5,6);
639 if (status == MagickFalse)
643 if (image->previous == (Image *) NULL)
645 status=SetImageProgress(image,LoadImageTag,6,6);
646 if (status == MagickFalse)
651 case PartitionInterlace:
654 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
656 AppendImageFormat("R",image->filename);
657 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
658 if (status == MagickFalse)
660 canvas_image=DestroyImageList(canvas_image);
661 image=DestroyImageList(image);
662 return((Image *) NULL);
664 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
665 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
667 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
668 for (i=0; i < (ssize_t) scene; i++)
669 for (y=0; y < (ssize_t) image->extract_info.height; y++)
671 pixels=(const unsigned char *) ReadBlobStream(image,length,
672 GetQuantumPixels(quantum_info),&count);
673 if (count != (ssize_t) length)
675 ThrowFileException(exception,CorruptImageError,
676 "UnexpectedEndOfFile",image->filename);
680 pixels=(const unsigned char *) ReadBlobStream(image,length,
681 GetQuantumPixels(quantum_info),&count);
682 if (count != (ssize_t) length)
684 for (y=0; y < (ssize_t) image->extract_info.height; y++)
686 register const Quantum
695 if (count != (ssize_t) length)
697 ThrowFileException(exception,CorruptImageError,
698 "UnexpectedEndOfFile",image->filename);
701 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
703 if (q == (Quantum *) NULL)
705 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
706 quantum_info,RedQuantum,pixels,exception);
707 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
709 if (((y-image->extract_info.y) >= 0) &&
710 ((y-image->extract_info.y) < (ssize_t) image->rows))
712 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
713 canvas_image->columns,1,exception);
714 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
715 image->columns,1,exception);
716 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
718 for (x=0; x < (ssize_t) image->columns; x++)
720 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
721 p+=GetPixelChannels(canvas_image);
722 q+=GetPixelChannels(image);
724 if (SyncAuthenticPixels(image,exception) == MagickFalse)
727 pixels=(const unsigned char *) ReadBlobStream(image,length,
728 GetQuantumPixels(quantum_info),&count);
729 if (count != (ssize_t) length)
732 if (image->previous == (Image *) NULL)
734 status=SetImageProgress(image,LoadImageTag,1,5);
735 if (status == MagickFalse)
738 (void) CloseBlob(image);
739 AppendImageFormat("G",image->filename);
740 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
741 if (status == MagickFalse)
743 canvas_image=DestroyImageList(canvas_image);
744 image=DestroyImageList(image);
745 return((Image *) NULL);
747 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
748 for (i=0; i < (ssize_t) scene; i++)
749 for (y=0; y < (ssize_t) image->extract_info.height; y++)
751 pixels=(const unsigned char *) ReadBlobStream(image,length,
752 GetQuantumPixels(quantum_info),&count);
753 if (count != (ssize_t) length)
755 ThrowFileException(exception,CorruptImageError,
756 "UnexpectedEndOfFile",image->filename);
760 pixels=(const unsigned char *) ReadBlobStream(image,length,
761 GetQuantumPixels(quantum_info),&count);
762 if (count != (ssize_t) length)
764 for (y=0; y < (ssize_t) image->extract_info.height; y++)
766 register const Quantum
775 if (count != (ssize_t) length)
777 ThrowFileException(exception,CorruptImageError,
778 "UnexpectedEndOfFile",image->filename);
781 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
783 if (q == (Quantum *) NULL)
785 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
786 quantum_info,GreenQuantum,pixels,exception);
787 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
789 if (((y-image->extract_info.y) >= 0) &&
790 ((y-image->extract_info.y) < (ssize_t) image->rows))
792 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
793 canvas_image->columns,1,exception);
794 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
795 image->columns,1,exception);
796 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
798 for (x=0; x < (ssize_t) image->columns; x++)
800 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
801 p+=GetPixelChannels(canvas_image);
802 q+=GetPixelChannels(image);
804 if (SyncAuthenticPixels(image,exception) == MagickFalse)
807 pixels=(const unsigned char *) ReadBlobStream(image,length,
808 GetQuantumPixels(quantum_info),&count);
809 if (count != (ssize_t) length)
812 if (image->previous == (Image *) NULL)
814 status=SetImageProgress(image,LoadImageTag,2,5);
815 if (status == MagickFalse)
818 (void) CloseBlob(image);
819 AppendImageFormat("B",image->filename);
820 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
821 if (status == MagickFalse)
823 canvas_image=DestroyImageList(canvas_image);
824 image=DestroyImageList(image);
825 return((Image *) NULL);
827 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
828 for (i=0; i < (ssize_t) scene; i++)
829 for (y=0; y < (ssize_t) image->extract_info.height; y++)
831 pixels=(const unsigned char *) ReadBlobStream(image,length,
832 GetQuantumPixels(quantum_info),&count);
833 if (count != (ssize_t) length)
835 ThrowFileException(exception,CorruptImageError,
836 "UnexpectedEndOfFile",image->filename);
840 pixels=(const unsigned char *) ReadBlobStream(image,length,
841 GetQuantumPixels(quantum_info),&count);
842 if (count != (ssize_t) length)
844 for (y=0; y < (ssize_t) image->extract_info.height; y++)
846 register const Quantum
855 if (count != (ssize_t) length)
857 ThrowFileException(exception,CorruptImageError,
858 "UnexpectedEndOfFile",image->filename);
861 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
863 if (q == (Quantum *) NULL)
865 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
866 quantum_info,BlueQuantum,pixels,exception);
867 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
869 if (((y-image->extract_info.y) >= 0) &&
870 ((y-image->extract_info.y) < (ssize_t) image->rows))
872 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
873 canvas_image->columns,1,exception);
874 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
875 image->columns,1,exception);
876 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
878 for (x=0; x < (ssize_t) image->columns; x++)
880 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
881 p+=GetPixelChannels(canvas_image);
882 q+=GetPixelChannels(image);
884 if (SyncAuthenticPixels(image,exception) == MagickFalse)
887 pixels=(const unsigned char *) ReadBlobStream(image,length,
888 GetQuantumPixels(quantum_info),&count);
889 if (count != (ssize_t) length)
892 if (image->previous == (Image *) NULL)
894 status=SetImageProgress(image,LoadImageTag,3,5);
895 if (status == MagickFalse)
898 if (image->alpha_trait != UndefinedPixelTrait)
900 (void) CloseBlob(image);
901 AppendImageFormat("A",image->filename);
902 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
903 if (status == MagickFalse)
905 canvas_image=DestroyImageList(canvas_image);
906 image=DestroyImageList(image);
907 return((Image *) NULL);
909 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
910 for (i=0; i < (ssize_t) scene; i++)
911 for (y=0; y < (ssize_t) image->extract_info.height; y++)
913 pixels=(const unsigned char *) ReadBlobStream(image,length,
914 GetQuantumPixels(quantum_info),&count);
915 if (count != (ssize_t) length)
917 ThrowFileException(exception,CorruptImageError,
918 "UnexpectedEndOfFile",image->filename);
922 pixels=(const unsigned char *) ReadBlobStream(image,length,
923 GetQuantumPixels(quantum_info),&count);
924 if (count != (ssize_t) length)
926 for (y=0; y < (ssize_t) image->extract_info.height; y++)
928 register const Quantum
937 if (count != (ssize_t) length)
939 ThrowFileException(exception,CorruptImageError,
940 "UnexpectedEndOfFile",image->filename);
943 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
945 if (q == (Quantum *) NULL)
947 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
948 quantum_info,BlueQuantum,pixels,exception);
949 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
951 if (((y-image->extract_info.y) >= 0) &&
952 ((y-image->extract_info.y) < (ssize_t) image->rows))
954 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
955 0,canvas_image->columns,1,exception);
956 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
957 image->columns,1,exception);
958 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
960 for (x=0; x < (ssize_t) image->columns; x++)
962 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
963 p+=GetPixelChannels(canvas_image);
964 q+=GetPixelChannels(image);
966 if (SyncAuthenticPixels(image,exception) == MagickFalse)
969 pixels=(const unsigned char *) ReadBlobStream(image,length,
970 GetQuantumPixels(quantum_info),&count);
971 if (count != (ssize_t) length)
974 if (image->previous == (Image *) NULL)
976 status=SetImageProgress(image,LoadImageTag,4,5);
977 if (status == MagickFalse)
981 (void) CloseBlob(image);
982 if (image->previous == (Image *) NULL)
984 status=SetImageProgress(image,LoadImageTag,5,5);
985 if (status == MagickFalse)
991 SetQuantumImageType(image,quantum_type);
993 Proceed to next image.
995 if (image_info->number_scenes != 0)
996 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
998 if (count == (ssize_t) length)
1001 Allocate next image structure.
1003 AcquireNextImage(image_info,image,exception);
1004 if (GetNextImageInList(image) == (Image *) NULL)
1006 image=DestroyImageList(image);
1007 return((Image *) NULL);
1009 image=SyncNextImageInList(image);
1010 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1011 GetBlobSize(image));
1012 if (status == MagickFalse)
1016 } while (count == (ssize_t) length);
1017 quantum_info=DestroyQuantumInfo(quantum_info);
1018 canvas_image=DestroyImage(canvas_image);
1019 (void) CloseBlob(image);
1020 return(GetFirstImageInList(image));
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1028 % R e g i s t e r R G B I m a g e %
1032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034 % RegisterRGBImage() adds attributes for the RGB image format to
1035 % the list of supported formats. The attributes include the image format
1036 % tag, a method to read and/or write the format, whether the format
1037 % supports the saving of more than one frame to the same file or blob,
1038 % whether the format supports native in-memory I/O, and a brief
1039 % description of the format.
1041 % The format of the RegisterRGBImage method is:
1043 % size_t RegisterRGBImage(void)
1046 ModuleExport size_t RegisterRGBImage(void)
1051 entry=AcquireMagickInfo("RGB","RGB",
1052 "Raw red, green, and blue samples");
1053 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1054 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1055 entry->flags|=CoderRawSupportFlag;
1056 entry->flags|=CoderEndianSupportFlag;
1057 (void) RegisterMagickInfo(entry);
1058 entry=AcquireMagickInfo("RGB","RGBA",
1059 "Raw red, green, blue, and alpha samples");
1060 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1061 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1062 entry->flags|=CoderRawSupportFlag;
1063 entry->flags|=CoderEndianSupportFlag;
1064 (void) RegisterMagickInfo(entry);
1065 entry=AcquireMagickInfo("RGB","RGBO",
1066 "Raw red, green, blue, and opacity samples");
1067 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1068 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1069 entry->flags|=CoderRawSupportFlag;
1070 entry->flags|=CoderEndianSupportFlag;
1071 (void) RegisterMagickInfo(entry);
1072 return(MagickImageCoderSignature);
1076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1080 % U n r e g i s t e r R G B I m a g e %
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1086 % UnregisterRGBImage() removes format registrations made by the RGB module
1087 % from the list of supported formats.
1089 % The format of the UnregisterRGBImage method is:
1091 % UnregisterRGBImage(void)
1094 ModuleExport void UnregisterRGBImage(void)
1096 (void) UnregisterMagickInfo("RGBO");
1097 (void) UnregisterMagickInfo("RGBA");
1098 (void) UnregisterMagickInfo("RGB");
1102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1106 % W r i t e R G B I m a g e %
1110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1112 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1113 % rasterfile format.
1115 % The format of the WriteRGBImage method is:
1117 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1118 % Image *image,ExceptionInfo *exception)
1120 % A description of each parameter follows.
1122 % o image_info: the image info.
1124 % o image: The image.
1126 % o exception: return any errors or warnings in this structure.
1129 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1130 Image *image,ExceptionInfo *exception)
1155 Allocate memory for pixels.
1157 assert(image_info != (const ImageInfo *) NULL);
1158 assert(image_info->signature == MagickCoreSignature);
1159 assert(image != (Image *) NULL);
1160 assert(image->signature == MagickCoreSignature);
1161 if (image->debug != MagickFalse)
1162 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1163 if (image_info->interlace != PartitionInterlace)
1166 Open output image file.
1168 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1169 if (status == MagickFalse)
1172 quantum_type=RGBQuantum;
1173 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1174 quantum_type=RGBAQuantum;
1175 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1176 quantum_type=RGBOQuantum;
1181 Convert MIFF to RGB raster pixels.
1183 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1184 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1185 (image->alpha_trait == UndefinedPixelTrait))
1186 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1187 quantum_info=AcquireQuantumInfo(image_info,image);
1188 if (quantum_info == (QuantumInfo *) NULL)
1189 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1190 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1191 switch (image_info->interlace)
1197 No interlacing: RGBRGBRGBRGBRGBRGB...
1199 for (y=0; y < (ssize_t) image->rows; y++)
1201 register const Quantum
1204 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1205 if (p == (const Quantum *) NULL)
1207 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1208 quantum_type,pixels,exception);
1209 count=WriteBlob(image,length,pixels);
1210 if (count != (ssize_t) length)
1212 if (image->previous == (Image *) NULL)
1214 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1216 if (status == MagickFalse)
1225 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1227 for (y=0; y < (ssize_t) image->rows; y++)
1229 register const Quantum
1232 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1233 if (p == (const Quantum *) NULL)
1235 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1236 RedQuantum,pixels,exception);
1237 count=WriteBlob(image,length,pixels);
1238 if (count != (ssize_t) length)
1240 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1241 GreenQuantum,pixels,exception);
1242 count=WriteBlob(image,length,pixels);
1243 if (count != (ssize_t) length)
1245 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1246 BlueQuantum,pixels,exception);
1247 count=WriteBlob(image,length,pixels);
1248 if (count != (ssize_t) length)
1250 if (quantum_type == RGBAQuantum)
1252 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1253 AlphaQuantum,pixels,exception);
1254 count=WriteBlob(image,length,pixels);
1255 if (count != (ssize_t) length)
1258 if (quantum_type == RGBOQuantum)
1260 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1261 OpacityQuantum,pixels,exception);
1262 count=WriteBlob(image,length,pixels);
1263 if (count != (ssize_t) length)
1266 if (image->previous == (Image *) NULL)
1268 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1270 if (status == MagickFalse)
1276 case PlaneInterlace:
1279 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1281 for (y=0; y < (ssize_t) image->rows; y++)
1283 register const Quantum
1286 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1287 if (p == (const Quantum *) NULL)
1289 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1290 RedQuantum,pixels,exception);
1291 count=WriteBlob(image,length,pixels);
1292 if (count != (ssize_t) length)
1295 if (image->previous == (Image *) NULL)
1297 status=SetImageProgress(image,SaveImageTag,1,6);
1298 if (status == MagickFalse)
1301 for (y=0; y < (ssize_t) image->rows; y++)
1303 register const Quantum
1306 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1307 if (p == (const Quantum *) NULL)
1309 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1310 GreenQuantum,pixels,exception);
1311 count=WriteBlob(image,length,pixels);
1312 if (count != (ssize_t) length)
1315 if (image->previous == (Image *) NULL)
1317 status=SetImageProgress(image,SaveImageTag,2,6);
1318 if (status == MagickFalse)
1321 for (y=0; y < (ssize_t) image->rows; y++)
1323 register const Quantum
1326 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1327 if (p == (const Quantum *) NULL)
1329 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1330 BlueQuantum,pixels,exception);
1331 count=WriteBlob(image,length,pixels);
1332 if (count != (ssize_t) length)
1335 if (image->previous == (Image *) NULL)
1337 status=SetImageProgress(image,SaveImageTag,3,6);
1338 if (status == MagickFalse)
1341 if (quantum_type == RGBAQuantum)
1343 for (y=0; y < (ssize_t) image->rows; y++)
1345 register const Quantum
1348 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1349 if (p == (const Quantum *) NULL)
1351 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1352 AlphaQuantum,pixels,exception);
1353 count=WriteBlob(image,length,pixels);
1354 if (count != (ssize_t) length)
1357 if (image->previous == (Image *) NULL)
1359 status=SetImageProgress(image,SaveImageTag,5,6);
1360 if (status == MagickFalse)
1364 if (image_info->interlace == PartitionInterlace)
1365 (void) CopyMagickString(image->filename,image_info->filename,
1367 if (image->previous == (Image *) NULL)
1369 status=SetImageProgress(image,SaveImageTag,6,6);
1370 if (status == MagickFalse)
1375 case PartitionInterlace:
1378 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1380 AppendImageFormat("R",image->filename);
1381 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1382 AppendBinaryBlobMode,exception);
1383 if (status == MagickFalse)
1385 for (y=0; y < (ssize_t) image->rows; y++)
1387 register const Quantum
1390 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1391 if (p == (const Quantum *) NULL)
1393 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1394 RedQuantum,pixels,exception);
1395 count=WriteBlob(image,length,pixels);
1396 if (count != (ssize_t) length)
1399 if (image->previous == (Image *) NULL)
1401 status=SetImageProgress(image,SaveImageTag,1,6);
1402 if (status == MagickFalse)
1405 (void) CloseBlob(image);
1406 AppendImageFormat("G",image->filename);
1407 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1408 AppendBinaryBlobMode,exception);
1409 if (status == MagickFalse)
1411 for (y=0; y < (ssize_t) image->rows; y++)
1413 register const Quantum
1416 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1417 if (p == (const Quantum *) NULL)
1419 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1420 GreenQuantum,pixels,exception);
1421 count=WriteBlob(image,length,pixels);
1422 if (count != (ssize_t) length)
1425 if (image->previous == (Image *) NULL)
1427 status=SetImageProgress(image,SaveImageTag,2,6);
1428 if (status == MagickFalse)
1431 (void) CloseBlob(image);
1432 AppendImageFormat("B",image->filename);
1433 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1434 AppendBinaryBlobMode,exception);
1435 if (status == MagickFalse)
1437 for (y=0; y < (ssize_t) image->rows; y++)
1439 register const Quantum
1442 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1443 if (p == (const Quantum *) NULL)
1445 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1446 BlueQuantum,pixels,exception);
1447 count=WriteBlob(image,length,pixels);
1448 if (count != (ssize_t) length)
1451 if (image->previous == (Image *) NULL)
1453 status=SetImageProgress(image,SaveImageTag,3,6);
1454 if (status == MagickFalse)
1457 if (quantum_type == RGBAQuantum)
1459 (void) CloseBlob(image);
1460 AppendImageFormat("A",image->filename);
1461 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1462 AppendBinaryBlobMode,exception);
1463 if (status == MagickFalse)
1465 for (y=0; y < (ssize_t) image->rows; y++)
1467 register const Quantum
1470 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1471 if (p == (const Quantum *) NULL)
1473 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1474 AlphaQuantum,pixels,exception);
1475 count=WriteBlob(image,length,pixels);
1476 if (count != (ssize_t) length)
1479 if (image->previous == (Image *) NULL)
1481 status=SetImageProgress(image,SaveImageTag,5,6);
1482 if (status == MagickFalse)
1486 (void) CloseBlob(image);
1487 (void) CopyMagickString(image->filename,image_info->filename,
1489 if (image->previous == (Image *) NULL)
1491 status=SetImageProgress(image,SaveImageTag,6,6);
1492 if (status == MagickFalse)
1498 quantum_info=DestroyQuantumInfo(quantum_info);
1499 if (GetNextImageInList(image) == (Image *) NULL)
1501 image=SyncNextImageInList(image);
1502 status=SetImageProgress(image,SaveImagesTag,scene++,
1503 GetImageListLength(image));
1504 if (status == MagickFalse)
1506 } while (image_info->adjoin != MagickFalse);
1507 (void) CloseBlob(image);