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 unsigned char *) 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=(const unsigned char *) ReadBlobStream(image,length,
191 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
222 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
280 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
304 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
382 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
403 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
449 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
501 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
553 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
614 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
652 GetQuantumPixels(quantum_info),&count);
653 if (count != (ssize_t) length)
655 ThrowFileException(exception,CorruptImageError,
656 "UnexpectedEndOfFile",image->filename);
660 pixels=(const unsigned char *) ReadBlobStream(image,length,
661 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
706 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
728 GetQuantumPixels(quantum_info),&count);
729 if (count != (ssize_t) length)
731 ThrowFileException(exception,CorruptImageError,
732 "UnexpectedEndOfFile",image->filename);
736 pixels=(const unsigned char *) ReadBlobStream(image,length,
737 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
782 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
804 GetQuantumPixels(quantum_info),&count);
805 if (count != (ssize_t) length)
807 ThrowFileException(exception,CorruptImageError,
808 "UnexpectedEndOfFile",image->filename);
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)
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=(const unsigned char *) ReadBlobStream(image,length,
858 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
882 GetQuantumPixels(quantum_info),&count);
883 if (count != (ssize_t) length)
885 ThrowFileException(exception,CorruptImageError,
886 "UnexpectedEndOfFile",image->filename);
890 pixels=(const unsigned char *) ReadBlobStream(image,length,
891 GetQuantumPixels(quantum_info),&count);
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=(const unsigned char *) ReadBlobStream(image,length,
936 GetQuantumPixels(quantum_info),&count);
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=AcquireMagickInfo("RGB","RGB",
1016 "Raw red, green, and blue samples");
1017 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1018 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1019 entry->flags|=CoderRawSupportFlag;
1020 entry->flags|=CoderEndianSupportFlag;
1021 (void) RegisterMagickInfo(entry);
1022 entry=AcquireMagickInfo("RGB","RGBA",
1023 "Raw red, green, blue, and alpha samples");
1024 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1025 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1026 entry->flags|=CoderRawSupportFlag;
1027 entry->flags|=CoderEndianSupportFlag;
1028 (void) RegisterMagickInfo(entry);
1029 entry=AcquireMagickInfo("RGB","RGBO",
1030 "Raw red, green, blue, and opacity samples");
1031 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1032 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1033 entry->flags|=CoderRawSupportFlag;
1034 entry->flags|=CoderEndianSupportFlag;
1035 (void) RegisterMagickInfo(entry);
1036 return(MagickImageCoderSignature);
1040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044 % U n r e g i s t e r R G B I m a g e %
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050 % UnregisterRGBImage() removes format registrations made by the RGB module
1051 % from the list of supported formats.
1053 % The format of the UnregisterRGBImage method is:
1055 % UnregisterRGBImage(void)
1058 ModuleExport void UnregisterRGBImage(void)
1060 (void) UnregisterMagickInfo("RGBO");
1061 (void) UnregisterMagickInfo("RGBA");
1062 (void) UnregisterMagickInfo("RGB");
1066 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1070 % W r i t e R G B I m a g e %
1074 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1076 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1077 % rasterfile format.
1079 % The format of the WriteRGBImage method is:
1081 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1082 % Image *image,ExceptionInfo *exception)
1084 % A description of each parameter follows.
1086 % o image_info: the image info.
1088 % o image: The image.
1090 % o exception: return any errors or warnings in this structure.
1093 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1094 Image *image,ExceptionInfo *exception)
1119 Allocate memory for pixels.
1121 assert(image_info != (const ImageInfo *) NULL);
1122 assert(image_info->signature == MagickSignature);
1123 assert(image != (Image *) NULL);
1124 assert(image->signature == MagickSignature);
1125 if (image->debug != MagickFalse)
1126 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1127 if (image_info->interlace != PartitionInterlace)
1130 Open output image file.
1132 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1133 if (status == MagickFalse)
1136 quantum_type=RGBQuantum;
1137 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1138 quantum_type=RGBAQuantum;
1139 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1140 quantum_type=RGBOQuantum;
1145 Convert MIFF to RGB raster pixels.
1147 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1148 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1149 (image->alpha_trait == UndefinedPixelTrait))
1150 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1151 quantum_info=AcquireQuantumInfo(image_info,image);
1152 if (quantum_info == (QuantumInfo *) NULL)
1153 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1154 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1155 switch (image_info->interlace)
1161 No interlacing: RGBRGBRGBRGBRGBRGB...
1163 for (y=0; y < (ssize_t) image->rows; y++)
1165 register const Quantum
1168 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1169 if (p == (const Quantum *) NULL)
1171 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1172 quantum_type,pixels,exception);
1173 count=WriteBlob(image,length,pixels);
1174 if (count != (ssize_t) length)
1176 if (image->previous == (Image *) NULL)
1178 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1180 if (status == MagickFalse)
1189 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1191 for (y=0; y < (ssize_t) image->rows; y++)
1193 register const Quantum
1196 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1197 if (p == (const Quantum *) NULL)
1199 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1200 RedQuantum,pixels,exception);
1201 count=WriteBlob(image,length,pixels);
1202 if (count != (ssize_t) length)
1204 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1205 GreenQuantum,pixels,exception);
1206 count=WriteBlob(image,length,pixels);
1207 if (count != (ssize_t) length)
1209 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1210 BlueQuantum,pixels,exception);
1211 count=WriteBlob(image,length,pixels);
1212 if (count != (ssize_t) length)
1214 if (quantum_type == RGBAQuantum)
1216 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1217 AlphaQuantum,pixels,exception);
1218 count=WriteBlob(image,length,pixels);
1219 if (count != (ssize_t) length)
1222 if (quantum_type == RGBOQuantum)
1224 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1225 OpacityQuantum,pixels,exception);
1226 count=WriteBlob(image,length,pixels);
1227 if (count != (ssize_t) length)
1230 if (image->previous == (Image *) NULL)
1232 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1234 if (status == MagickFalse)
1240 case PlaneInterlace:
1243 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1245 for (y=0; y < (ssize_t) image->rows; y++)
1247 register const Quantum
1250 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1251 if (p == (const Quantum *) NULL)
1253 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1254 RedQuantum,pixels,exception);
1255 count=WriteBlob(image,length,pixels);
1256 if (count != (ssize_t) length)
1259 if (image->previous == (Image *) NULL)
1261 status=SetImageProgress(image,SaveImageTag,1,6);
1262 if (status == MagickFalse)
1265 for (y=0; y < (ssize_t) image->rows; y++)
1267 register const Quantum
1270 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1271 if (p == (const Quantum *) NULL)
1273 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1274 GreenQuantum,pixels,exception);
1275 count=WriteBlob(image,length,pixels);
1276 if (count != (ssize_t) length)
1279 if (image->previous == (Image *) NULL)
1281 status=SetImageProgress(image,SaveImageTag,2,6);
1282 if (status == MagickFalse)
1285 for (y=0; y < (ssize_t) image->rows; y++)
1287 register const Quantum
1290 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1291 if (p == (const Quantum *) NULL)
1293 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1294 BlueQuantum,pixels,exception);
1295 count=WriteBlob(image,length,pixels);
1296 if (count != (ssize_t) length)
1299 if (image->previous == (Image *) NULL)
1301 status=SetImageProgress(image,SaveImageTag,3,6);
1302 if (status == MagickFalse)
1305 if (quantum_type == RGBAQuantum)
1307 for (y=0; y < (ssize_t) image->rows; y++)
1309 register const Quantum
1312 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1313 if (p == (const Quantum *) NULL)
1315 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1316 AlphaQuantum,pixels,exception);
1317 count=WriteBlob(image,length,pixels);
1318 if (count != (ssize_t) length)
1321 if (image->previous == (Image *) NULL)
1323 status=SetImageProgress(image,SaveImageTag,5,6);
1324 if (status == MagickFalse)
1328 if (image_info->interlace == PartitionInterlace)
1329 (void) CopyMagickString(image->filename,image_info->filename,
1331 if (image->previous == (Image *) NULL)
1333 status=SetImageProgress(image,SaveImageTag,6,6);
1334 if (status == MagickFalse)
1339 case PartitionInterlace:
1342 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1344 AppendImageFormat("R",image->filename);
1345 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1346 AppendBinaryBlobMode,exception);
1347 if (status == MagickFalse)
1349 for (y=0; y < (ssize_t) image->rows; y++)
1351 register const Quantum
1354 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1355 if (p == (const Quantum *) NULL)
1357 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1358 RedQuantum,pixels,exception);
1359 count=WriteBlob(image,length,pixels);
1360 if (count != (ssize_t) length)
1363 if (image->previous == (Image *) NULL)
1365 status=SetImageProgress(image,SaveImageTag,1,6);
1366 if (status == MagickFalse)
1369 (void) CloseBlob(image);
1370 AppendImageFormat("G",image->filename);
1371 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1372 AppendBinaryBlobMode,exception);
1373 if (status == MagickFalse)
1375 for (y=0; y < (ssize_t) image->rows; y++)
1377 register const Quantum
1380 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1381 if (p == (const Quantum *) NULL)
1383 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1384 GreenQuantum,pixels,exception);
1385 count=WriteBlob(image,length,pixels);
1386 if (count != (ssize_t) length)
1389 if (image->previous == (Image *) NULL)
1391 status=SetImageProgress(image,SaveImageTag,2,6);
1392 if (status == MagickFalse)
1395 (void) CloseBlob(image);
1396 AppendImageFormat("B",image->filename);
1397 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1398 AppendBinaryBlobMode,exception);
1399 if (status == MagickFalse)
1401 for (y=0; y < (ssize_t) image->rows; y++)
1403 register const Quantum
1406 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1407 if (p == (const Quantum *) NULL)
1409 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1410 BlueQuantum,pixels,exception);
1411 count=WriteBlob(image,length,pixels);
1412 if (count != (ssize_t) length)
1415 if (image->previous == (Image *) NULL)
1417 status=SetImageProgress(image,SaveImageTag,3,6);
1418 if (status == MagickFalse)
1421 if (quantum_type == RGBAQuantum)
1423 (void) CloseBlob(image);
1424 AppendImageFormat("A",image->filename);
1425 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1426 AppendBinaryBlobMode,exception);
1427 if (status == MagickFalse)
1429 for (y=0; y < (ssize_t) image->rows; y++)
1431 register const Quantum
1434 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1435 if (p == (const Quantum *) NULL)
1437 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1438 AlphaQuantum,pixels,exception);
1439 count=WriteBlob(image,length,pixels);
1440 if (count != (ssize_t) length)
1443 if (image->previous == (Image *) NULL)
1445 status=SetImageProgress(image,SaveImageTag,5,6);
1446 if (status == MagickFalse)
1450 (void) CloseBlob(image);
1451 (void) CopyMagickString(image->filename,image_info->filename,
1453 if (image->previous == (Image *) NULL)
1455 status=SetImageProgress(image,SaveImageTag,6,6);
1456 if (status == MagickFalse)
1462 quantum_info=DestroyQuantumInfo(quantum_info);
1463 if (GetNextImageInList(image) == (Image *) NULL)
1465 image=SyncNextImageInList(image);
1466 status=SetImageProgress(image,SaveImagesTag,scene++,
1467 GetImageListLength(image));
1468 if (status == MagickFalse)
1470 } while (image_info->adjoin != MagickFalse);
1471 (void) CloseBlob(image);