2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw RGB Image Format %
20 % Copyright 1999-2015 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/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 == MagickSignature);
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 == MagickSignature);
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 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
163 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
164 if (quantum_info == (QuantumInfo *) NULL)
165 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
166 quantum_type=RGBQuantum;
167 if (LocaleCompare(image_info->magick,"RGBA") == 0)
169 quantum_type=RGBAQuantum;
170 image->alpha_trait=BlendPixelTrait;
171 canvas_image->alpha_trait=BlendPixelTrait;
173 if (LocaleCompare(image_info->magick,"RGBO") == 0)
175 quantum_type=RGBOQuantum;
176 image->alpha_trait=BlendPixelTrait;
177 canvas_image->alpha_trait=BlendPixelTrait;
179 pixels=(const void *) NULL;
180 if (image_info->number_scenes != 0)
181 while (image->scene < image_info->scene)
187 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
188 for (y=0; y < (ssize_t) image->rows; y++)
190 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
192 if (count != (ssize_t) length)
202 Read pixels to virtual canvas image then push to image.
204 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
205 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
207 status=SetImageExtent(image,image->columns,image->rows,exception);
208 if (status == MagickFalse)
209 return(DestroyImageList(image));
210 switch (image_info->interlace)
216 No interlacing: RGBRGBRGBRGBRGBRGB...
220 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
221 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
224 for (y=0; y < (ssize_t) image->extract_info.height; y++)
226 register const Quantum
235 if (count != (ssize_t) length)
237 ThrowFileException(exception,CorruptImageError,
238 "UnexpectedEndOfFile",image->filename);
241 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
243 if (q == (Quantum *) NULL)
245 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
246 quantum_info,quantum_type,pixels,exception);
247 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
249 if (((y-image->extract_info.y) >= 0) &&
250 ((y-image->extract_info.y) < (ssize_t) image->rows))
252 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
253 canvas_image->columns,1,exception);
254 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
255 image->columns,1,exception);
256 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
258 for (x=0; x < (ssize_t) image->columns; x++)
260 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
261 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
262 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
263 SetPixelAlpha(image,OpaqueAlpha,q);
264 if (image->alpha_trait != UndefinedPixelTrait)
265 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
266 p+=GetPixelChannels(canvas_image);
267 q+=GetPixelChannels(image);
269 if (SyncAuthenticPixels(image,exception) == MagickFalse)
272 if (image->previous == (Image *) NULL)
274 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
276 if (status == MagickFalse)
279 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
296 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
298 if (LocaleCompare(image_info->magick,"RGBO") == 0)
299 quantum_types[3]=OpacityQuantum;
302 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
303 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
306 for (y=0; y < (ssize_t) image->extract_info.height; y++)
308 register const Quantum
317 if (count != (ssize_t) length)
319 ThrowFileException(exception,CorruptImageError,
320 "UnexpectedEndOfFile",image->filename);
323 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
325 quantum_type=quantum_types[i];
326 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
328 if (q == (Quantum *) NULL)
330 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
331 quantum_info,quantum_type,pixels,exception);
332 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
334 if (((y-image->extract_info.y) >= 0) &&
335 ((y-image->extract_info.y) < (ssize_t) image->rows))
337 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
338 0,canvas_image->columns,1,exception);
339 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
340 image->columns,1,exception);
341 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
343 for (x=0; x < (ssize_t) image->columns; x++)
345 switch (quantum_type)
349 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
354 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
359 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
364 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
369 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
375 p+=GetPixelChannels(canvas_image);
376 q+=GetPixelChannels(image);
378 if (SyncAuthenticPixels(image,exception) == MagickFalse)
381 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
384 if (image->previous == (Image *) NULL)
386 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
388 if (status == MagickFalse)
397 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
401 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
402 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
405 for (y=0; y < (ssize_t) image->extract_info.height; y++)
407 register const Quantum
416 if (count != (ssize_t) length)
418 ThrowFileException(exception,CorruptImageError,
419 "UnexpectedEndOfFile",image->filename);
422 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
424 if (q == (Quantum *) NULL)
426 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
427 quantum_info,RedQuantum,pixels,exception);
428 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
430 if (((y-image->extract_info.y) >= 0) &&
431 ((y-image->extract_info.y) < (ssize_t) image->rows))
433 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
434 canvas_image->columns,1,exception);
435 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
436 image->columns,1,exception);
437 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
439 for (x=0; x < (ssize_t) image->columns; x++)
441 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
442 p+=GetPixelChannels(canvas_image);
443 q+=GetPixelChannels(image);
445 if (SyncAuthenticPixels(image,exception) == MagickFalse)
448 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
451 if (image->previous == (Image *) NULL)
453 status=SetImageProgress(image,LoadImageTag,1,6);
454 if (status == MagickFalse)
457 for (y=0; y < (ssize_t) image->extract_info.height; y++)
459 register const Quantum
468 if (count != (ssize_t) length)
470 ThrowFileException(exception,CorruptImageError,
471 "UnexpectedEndOfFile",image->filename);
474 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
476 if (q == (Quantum *) NULL)
478 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
479 quantum_info,GreenQuantum,pixels,exception);
480 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
482 if (((y-image->extract_info.y) >= 0) &&
483 ((y-image->extract_info.y) < (ssize_t) image->rows))
485 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
486 canvas_image->columns,1,exception);
487 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
488 image->columns,1,exception);
489 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
491 for (x=0; x < (ssize_t) image->columns; x++)
493 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
494 p+=GetPixelChannels(canvas_image);
495 q+=GetPixelChannels(image);
497 if (SyncAuthenticPixels(image,exception) == MagickFalse)
500 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
503 if (image->previous == (Image *) NULL)
505 status=SetImageProgress(image,LoadImageTag,2,6);
506 if (status == MagickFalse)
509 for (y=0; y < (ssize_t) image->extract_info.height; y++)
511 register const Quantum
520 if (count != (ssize_t) length)
522 ThrowFileException(exception,CorruptImageError,
523 "UnexpectedEndOfFile",image->filename);
526 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
528 if (q == (Quantum *) NULL)
530 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
531 quantum_info,BlueQuantum,pixels,exception);
532 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
534 if (((y-image->extract_info.y) >= 0) &&
535 ((y-image->extract_info.y) < (ssize_t) image->rows))
537 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
538 canvas_image->columns,1,exception);
539 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
540 image->columns,1,exception);
541 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
543 for (x=0; x < (ssize_t) image->columns; x++)
545 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
546 p+=GetPixelChannels(canvas_image);
547 q+=GetPixelChannels(image);
549 if (SyncAuthenticPixels(image,exception) == MagickFalse)
552 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
555 if (image->previous == (Image *) NULL)
557 status=SetImageProgress(image,LoadImageTag,3,6);
558 if (status == MagickFalse)
561 if (image->previous == (Image *) NULL)
563 status=SetImageProgress(image,LoadImageTag,4,6);
564 if (status == MagickFalse)
567 if (image->alpha_trait != UndefinedPixelTrait)
569 for (y=0; y < (ssize_t) image->extract_info.height; y++)
571 register const Quantum
580 if (count != (ssize_t) length)
582 ThrowFileException(exception,CorruptImageError,
583 "UnexpectedEndOfFile",image->filename);
586 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
588 if (q == (Quantum *) NULL)
590 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
591 quantum_info,AlphaQuantum,pixels,exception);
592 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
594 if (((y-image->extract_info.y) >= 0) &&
595 ((y-image->extract_info.y) < (ssize_t) image->rows))
597 p=GetVirtualPixels(canvas_image,
598 canvas_image->extract_info.x,0,canvas_image->columns,1,
600 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
601 image->columns,1,exception);
602 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
604 for (x=0; x < (ssize_t) image->columns; x++)
606 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
607 p+=GetPixelChannels(canvas_image);
608 q+=GetPixelChannels(image);
610 if (SyncAuthenticPixels(image,exception) == MagickFalse)
613 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
616 if (image->previous == (Image *) NULL)
618 status=SetImageProgress(image,LoadImageTag,5,6);
619 if (status == MagickFalse)
623 if (image->previous == (Image *) NULL)
625 status=SetImageProgress(image,LoadImageTag,6,6);
626 if (status == MagickFalse)
631 case PartitionInterlace:
634 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
636 AppendImageFormat("R",image->filename);
637 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
638 if (status == MagickFalse)
640 canvas_image=DestroyImageList(canvas_image);
641 image=DestroyImageList(image);
642 return((Image *) NULL);
644 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
645 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
647 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
648 for (i=0; i < (ssize_t) scene; i++)
649 for (y=0; y < (ssize_t) image->extract_info.height; y++)
651 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
653 if (count != (ssize_t) length)
655 ThrowFileException(exception,CorruptImageError,
656 "UnexpectedEndOfFile",image->filename);
660 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
662 for (y=0; y < (ssize_t) image->extract_info.height; y++)
664 register const Quantum
673 if (count != (ssize_t) length)
675 ThrowFileException(exception,CorruptImageError,
676 "UnexpectedEndOfFile",image->filename);
679 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
681 if (q == (Quantum *) NULL)
683 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
684 quantum_info,RedQuantum,pixels,exception);
685 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
687 if (((y-image->extract_info.y) >= 0) &&
688 ((y-image->extract_info.y) < (ssize_t) image->rows))
690 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
691 canvas_image->columns,1,exception);
692 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
693 image->columns,1,exception);
694 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
696 for (x=0; x < (ssize_t) image->columns; x++)
698 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
699 p+=GetPixelChannels(canvas_image);
700 q+=GetPixelChannels(image);
702 if (SyncAuthenticPixels(image,exception) == MagickFalse)
705 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
708 if (image->previous == (Image *) NULL)
710 status=SetImageProgress(image,LoadImageTag,1,5);
711 if (status == MagickFalse)
714 (void) CloseBlob(image);
715 AppendImageFormat("G",image->filename);
716 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
717 if (status == MagickFalse)
719 canvas_image=DestroyImageList(canvas_image);
720 image=DestroyImageList(image);
721 return((Image *) NULL);
723 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
724 for (i=0; i < (ssize_t) scene; i++)
725 for (y=0; y < (ssize_t) image->extract_info.height; y++)
727 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
729 if (count != (ssize_t) length)
731 ThrowFileException(exception,CorruptImageError,
732 "UnexpectedEndOfFile",image->filename);
736 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
738 for (y=0; y < (ssize_t) image->extract_info.height; y++)
740 register const Quantum
749 if (count != (ssize_t) length)
751 ThrowFileException(exception,CorruptImageError,
752 "UnexpectedEndOfFile",image->filename);
755 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
757 if (q == (Quantum *) NULL)
759 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
760 quantum_info,GreenQuantum,pixels,exception);
761 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
763 if (((y-image->extract_info.y) >= 0) &&
764 ((y-image->extract_info.y) < (ssize_t) image->rows))
766 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
767 canvas_image->columns,1,exception);
768 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
769 image->columns,1,exception);
770 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
772 for (x=0; x < (ssize_t) image->columns; x++)
774 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
775 p+=GetPixelChannels(canvas_image);
776 q+=GetPixelChannels(image);
778 if (SyncAuthenticPixels(image,exception) == MagickFalse)
781 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
784 if (image->previous == (Image *) NULL)
786 status=SetImageProgress(image,LoadImageTag,2,5);
787 if (status == MagickFalse)
790 (void) CloseBlob(image);
791 AppendImageFormat("B",image->filename);
792 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
793 if (status == MagickFalse)
795 canvas_image=DestroyImageList(canvas_image);
796 image=DestroyImageList(image);
797 return((Image *) NULL);
799 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
800 for (i=0; i < (ssize_t) scene; i++)
801 for (y=0; y < (ssize_t) image->extract_info.height; y++)
803 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
805 if (count != (ssize_t) length)
807 ThrowFileException(exception,CorruptImageError,
808 "UnexpectedEndOfFile",image->filename);
812 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
814 for (y=0; y < (ssize_t) image->extract_info.height; y++)
816 register const Quantum
825 if (count != (ssize_t) length)
827 ThrowFileException(exception,CorruptImageError,
828 "UnexpectedEndOfFile",image->filename);
831 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
833 if (q == (Quantum *) NULL)
835 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
836 quantum_info,BlueQuantum,pixels,exception);
837 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
839 if (((y-image->extract_info.y) >= 0) &&
840 ((y-image->extract_info.y) < (ssize_t) image->rows))
842 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
843 canvas_image->columns,1,exception);
844 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
845 image->columns,1,exception);
846 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
848 for (x=0; x < (ssize_t) image->columns; x++)
850 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
851 p+=GetPixelChannels(canvas_image);
852 q+=GetPixelChannels(image);
854 if (SyncAuthenticPixels(image,exception) == MagickFalse)
857 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
860 if (image->previous == (Image *) NULL)
862 status=SetImageProgress(image,LoadImageTag,3,5);
863 if (status == MagickFalse)
866 if (image->alpha_trait != UndefinedPixelTrait)
868 (void) CloseBlob(image);
869 AppendImageFormat("A",image->filename);
870 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
871 if (status == MagickFalse)
873 canvas_image=DestroyImageList(canvas_image);
874 image=DestroyImageList(image);
875 return((Image *) NULL);
877 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
878 for (i=0; i < (ssize_t) scene; i++)
879 for (y=0; y < (ssize_t) image->extract_info.height; y++)
881 pixels=ReadBlobStream(image,length,
882 GetQuantumPixels(quantum_info),&count);
883 if (count != (ssize_t) length)
885 ThrowFileException(exception,CorruptImageError,
886 "UnexpectedEndOfFile",image->filename);
890 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
892 for (y=0; y < (ssize_t) image->extract_info.height; y++)
894 register const Quantum
903 if (count != (ssize_t) length)
905 ThrowFileException(exception,CorruptImageError,
906 "UnexpectedEndOfFile",image->filename);
909 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
911 if (q == (Quantum *) NULL)
913 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
914 quantum_info,BlueQuantum,pixels,exception);
915 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
917 if (((y-image->extract_info.y) >= 0) &&
918 ((y-image->extract_info.y) < (ssize_t) image->rows))
920 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
921 0,canvas_image->columns,1,exception);
922 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
923 image->columns,1,exception);
924 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
926 for (x=0; x < (ssize_t) image->columns; x++)
928 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
929 p+=GetPixelChannels(canvas_image);
930 q+=GetPixelChannels(image);
932 if (SyncAuthenticPixels(image,exception) == MagickFalse)
935 pixels=ReadBlobStream(image,length,GetQuantumPixels(quantum_info),
938 if (image->previous == (Image *) NULL)
940 status=SetImageProgress(image,LoadImageTag,4,5);
941 if (status == MagickFalse)
945 (void) CloseBlob(image);
946 if (image->previous == (Image *) NULL)
948 status=SetImageProgress(image,LoadImageTag,5,5);
949 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)
970 image=DestroyImageList(image);
971 return((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 return(GetFirstImageInList(image));
988 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 % R e g i s t e r R G B I m a g e %
996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998 % RegisterRGBImage() adds attributes for the RGB image format to
999 % the list of supported formats. The attributes include the image format
1000 % tag, a method to read and/or write the format, whether the format
1001 % supports the saving of more than one frame to the same file or blob,
1002 % whether the format supports native in-memory I/O, and a brief
1003 % description of the format.
1005 % The format of the RegisterRGBImage method is:
1007 % size_t RegisterRGBImage(void)
1010 ModuleExport size_t RegisterRGBImage(void)
1015 entry=SetMagickInfo("RGB");
1016 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1017 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1018 entry->flags|=CoderRawSupportFlag;
1019 entry->flags|=CoderEndianSupportFlag;
1020 entry->description=ConstantString("Raw red, green, and blue samples");
1021 entry->module=ConstantString("RGB");
1022 (void) RegisterMagickInfo(entry);
1023 entry=SetMagickInfo("RGBA");
1024 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1025 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1026 entry->flags|=CoderRawSupportFlag;
1027 entry->flags|=CoderEndianSupportFlag;
1028 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1029 entry->module=ConstantString("RGB");
1030 (void) RegisterMagickInfo(entry);
1031 entry=SetMagickInfo("RGBO");
1032 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1033 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1034 entry->flags|=CoderRawSupportFlag;
1035 entry->flags|=CoderEndianSupportFlag;
1036 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1037 entry->module=ConstantString("RGB");
1038 (void) RegisterMagickInfo(entry);
1039 return(MagickImageCoderSignature);
1043 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1047 % U n r e g i s t e r R G B I m a g e %
1051 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1053 % UnregisterRGBImage() removes format registrations made by the RGB module
1054 % from the list of supported formats.
1056 % The format of the UnregisterRGBImage method is:
1058 % UnregisterRGBImage(void)
1061 ModuleExport void UnregisterRGBImage(void)
1063 (void) UnregisterMagickInfo("RGBO");
1064 (void) UnregisterMagickInfo("RGBA");
1065 (void) UnregisterMagickInfo("RGB");
1069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1073 % W r i t e R G B I m a g e %
1077 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1080 % rasterfile format.
1082 % The format of the WriteRGBImage method is:
1084 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1085 % Image *image,ExceptionInfo *exception)
1087 % A description of each parameter follows.
1089 % o image_info: the image info.
1091 % o image: The image.
1093 % o exception: return any errors or warnings in this structure.
1096 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1097 Image *image,ExceptionInfo *exception)
1122 Allocate memory for pixels.
1124 assert(image_info != (const ImageInfo *) NULL);
1125 assert(image_info->signature == MagickSignature);
1126 assert(image != (Image *) NULL);
1127 assert(image->signature == MagickSignature);
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;
1148 Convert MIFF to RGB raster pixels.
1150 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1151 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1152 (image->alpha_trait == UndefinedPixelTrait))
1153 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1154 quantum_info=AcquireQuantumInfo(image_info,image);
1155 if (quantum_info == (QuantumInfo *) NULL)
1156 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1157 pixels=GetQuantumPixels(quantum_info);
1158 switch (image_info->interlace)
1164 No interlacing: RGBRGBRGBRGBRGBRGB...
1166 for (y=0; y < (ssize_t) image->rows; y++)
1168 register const Quantum
1171 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1172 if (p == (const Quantum *) NULL)
1174 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1175 quantum_type,pixels,exception);
1176 count=WriteBlob(image,length,pixels);
1177 if (count != (ssize_t) length)
1179 if (image->previous == (Image *) NULL)
1181 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1183 if (status == MagickFalse)
1192 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1194 for (y=0; y < (ssize_t) image->rows; y++)
1196 register const Quantum
1199 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1200 if (p == (const Quantum *) NULL)
1202 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1203 RedQuantum,pixels,exception);
1204 count=WriteBlob(image,length,pixels);
1205 if (count != (ssize_t) length)
1207 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1208 GreenQuantum,pixels,exception);
1209 count=WriteBlob(image,length,pixels);
1210 if (count != (ssize_t) length)
1212 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1213 BlueQuantum,pixels,exception);
1214 count=WriteBlob(image,length,pixels);
1215 if (count != (ssize_t) length)
1217 if (quantum_type == RGBAQuantum)
1219 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1220 AlphaQuantum,pixels,exception);
1221 count=WriteBlob(image,length,pixels);
1222 if (count != (ssize_t) length)
1225 if (quantum_type == RGBOQuantum)
1227 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1228 OpacityQuantum,pixels,exception);
1229 count=WriteBlob(image,length,pixels);
1230 if (count != (ssize_t) length)
1233 if (image->previous == (Image *) NULL)
1235 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1237 if (status == MagickFalse)
1243 case PlaneInterlace:
1246 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1248 for (y=0; y < (ssize_t) image->rows; y++)
1250 register const Quantum
1253 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1254 if (p == (const Quantum *) NULL)
1256 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1257 RedQuantum,pixels,exception);
1258 count=WriteBlob(image,length,pixels);
1259 if (count != (ssize_t) length)
1262 if (image->previous == (Image *) NULL)
1264 status=SetImageProgress(image,SaveImageTag,1,6);
1265 if (status == MagickFalse)
1268 for (y=0; y < (ssize_t) image->rows; y++)
1270 register const Quantum
1273 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1274 if (p == (const Quantum *) NULL)
1276 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1277 GreenQuantum,pixels,exception);
1278 count=WriteBlob(image,length,pixels);
1279 if (count != (ssize_t) length)
1282 if (image->previous == (Image *) NULL)
1284 status=SetImageProgress(image,SaveImageTag,2,6);
1285 if (status == MagickFalse)
1288 for (y=0; y < (ssize_t) image->rows; y++)
1290 register const Quantum
1293 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1294 if (p == (const Quantum *) NULL)
1296 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1297 BlueQuantum,pixels,exception);
1298 count=WriteBlob(image,length,pixels);
1299 if (count != (ssize_t) length)
1302 if (image->previous == (Image *) NULL)
1304 status=SetImageProgress(image,SaveImageTag,3,6);
1305 if (status == MagickFalse)
1308 if (quantum_type == RGBAQuantum)
1310 for (y=0; y < (ssize_t) image->rows; y++)
1312 register const Quantum
1315 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1316 if (p == (const Quantum *) NULL)
1318 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1319 AlphaQuantum,pixels,exception);
1320 count=WriteBlob(image,length,pixels);
1321 if (count != (ssize_t) length)
1324 if (image->previous == (Image *) NULL)
1326 status=SetImageProgress(image,SaveImageTag,5,6);
1327 if (status == MagickFalse)
1331 if (image_info->interlace == PartitionInterlace)
1332 (void) CopyMagickString(image->filename,image_info->filename,
1334 if (image->previous == (Image *) NULL)
1336 status=SetImageProgress(image,SaveImageTag,6,6);
1337 if (status == MagickFalse)
1342 case PartitionInterlace:
1345 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1347 AppendImageFormat("R",image->filename);
1348 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1349 AppendBinaryBlobMode,exception);
1350 if (status == MagickFalse)
1352 for (y=0; y < (ssize_t) image->rows; y++)
1354 register const Quantum
1357 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1358 if (p == (const Quantum *) NULL)
1360 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1361 RedQuantum,pixels,exception);
1362 count=WriteBlob(image,length,pixels);
1363 if (count != (ssize_t) length)
1366 if (image->previous == (Image *) NULL)
1368 status=SetImageProgress(image,SaveImageTag,1,6);
1369 if (status == MagickFalse)
1372 (void) CloseBlob(image);
1373 AppendImageFormat("G",image->filename);
1374 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1375 AppendBinaryBlobMode,exception);
1376 if (status == MagickFalse)
1378 for (y=0; y < (ssize_t) image->rows; y++)
1380 register const Quantum
1383 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1384 if (p == (const Quantum *) NULL)
1386 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1387 GreenQuantum,pixels,exception);
1388 count=WriteBlob(image,length,pixels);
1389 if (count != (ssize_t) length)
1392 if (image->previous == (Image *) NULL)
1394 status=SetImageProgress(image,SaveImageTag,2,6);
1395 if (status == MagickFalse)
1398 (void) CloseBlob(image);
1399 AppendImageFormat("B",image->filename);
1400 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1401 AppendBinaryBlobMode,exception);
1402 if (status == MagickFalse)
1404 for (y=0; y < (ssize_t) image->rows; y++)
1406 register const Quantum
1409 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1410 if (p == (const Quantum *) NULL)
1412 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1413 BlueQuantum,pixels,exception);
1414 count=WriteBlob(image,length,pixels);
1415 if (count != (ssize_t) length)
1418 if (image->previous == (Image *) NULL)
1420 status=SetImageProgress(image,SaveImageTag,3,6);
1421 if (status == MagickFalse)
1424 if (quantum_type == RGBAQuantum)
1426 (void) CloseBlob(image);
1427 AppendImageFormat("A",image->filename);
1428 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1429 AppendBinaryBlobMode,exception);
1430 if (status == MagickFalse)
1432 for (y=0; y < (ssize_t) image->rows; y++)
1434 register const Quantum
1437 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1438 if (p == (const Quantum *) NULL)
1440 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1441 AlphaQuantum,pixels,exception);
1442 count=WriteBlob(image,length,pixels);
1443 if (count != (ssize_t) length)
1446 if (image->previous == (Image *) NULL)
1448 status=SetImageProgress(image,SaveImageTag,5,6);
1449 if (status == MagickFalse)
1453 (void) CloseBlob(image);
1454 (void) CopyMagickString(image->filename,image_info->filename,
1456 if (image->previous == (Image *) NULL)
1458 status=SetImageProgress(image,SaveImageTag,6,6);
1459 if (status == MagickFalse)
1465 quantum_info=DestroyQuantumInfo(quantum_info);
1466 if (GetNextImageInList(image) == (Image *) NULL)
1468 image=SyncNextImageInList(image);
1469 status=SetImageProgress(image,SaveImagesTag,scene++,
1470 GetImageListLength(image));
1471 if (status == MagickFalse)
1473 } while (image_info->adjoin != MagickFalse);
1474 (void) CloseBlob(image);