2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw RGB Image Format %
20 % Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/colorspace.h"
47 #include "MagickCore/colorspace-private.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/exception.h"
50 #include "MagickCore/exception-private.h"
51 #include "MagickCore/image.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/magick.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/monitor.h"
57 #include "MagickCore/monitor-private.h"
58 #include "MagickCore/pixel-accessor.h"
59 #include "MagickCore/quantum-private.h"
60 #include "MagickCore/static.h"
61 #include "MagickCore/statistic.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/module.h"
64 #include "MagickCore/utility.h"
69 static MagickBooleanType
70 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 % R e a d R G B I m a g e %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
84 % it. It allocates the memory necessary for the new Image structure and
85 % returns a pointer to the new image.
87 % The format of the ReadRGBImage method is:
89 % Image *ReadRGBImage(const ImageInfo *image_info,
90 % ExceptionInfo *exception)
92 % A description of each parameter follows:
94 % o image_info: the image info.
96 % o exception: return any errors or warnings in this structure.
99 static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
133 assert(image_info != (const ImageInfo *) NULL);
134 assert(image_info->signature == MagickSignature);
135 if (image_info->debug != MagickFalse)
136 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
137 image_info->filename);
138 assert(exception != (ExceptionInfo *) NULL);
139 assert(exception->signature == MagickSignature);
140 image=AcquireImage(image_info,exception);
141 if ((image->columns == 0) || (image->rows == 0))
142 ThrowReaderException(OptionError,"MustSpecifyImageSize");
143 if (image_info->interlace != PartitionInterlace)
145 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
146 if (status == MagickFalse)
148 image=DestroyImageList(image);
149 return((Image *) NULL);
151 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
152 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
156 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
158 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
160 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
162 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
163 if (quantum_info == (QuantumInfo *) NULL)
164 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
165 pixels=GetQuantumPixels(quantum_info);
166 quantum_type=RGBQuantum;
167 if (LocaleCompare(image_info->magick,"RGBA") == 0)
169 quantum_type=RGBAQuantum;
170 image->matte=MagickTrue;
171 canvas_image->matte=MagickTrue;
173 if (LocaleCompare(image_info->magick,"RGBO") == 0)
175 quantum_type=RGBOQuantum;
176 canvas_image->matte=MagickTrue;
178 if (image_info->number_scenes != 0)
179 while (image->scene < image_info->scene)
185 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
186 for (y=0; y < (ssize_t) image->rows; y++)
188 count=ReadBlob(image,length,pixels);
189 if (count != (ssize_t) length)
199 Read pixels to virtual canvas image then push to image.
201 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
202 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
204 switch (image_info->interlace)
210 No interlacing: RGBRGBRGBRGBRGBRGB...
214 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
215 count=ReadBlob(image,length,pixels);
217 for (y=0; y < (ssize_t) image->extract_info.height; y++)
219 register const Quantum
228 if (count != (ssize_t) length)
230 ThrowFileException(exception,CorruptImageError,
231 "UnexpectedEndOfFile",image->filename);
234 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
236 if (q == (Quantum *) NULL)
238 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
239 quantum_info,quantum_type,pixels,exception);
240 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
242 if (((y-image->extract_info.y) >= 0) &&
243 ((y-image->extract_info.y) < (ssize_t) image->rows))
245 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
246 canvas_image->columns,1,exception);
247 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
248 image->columns,1,exception);
249 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
251 for (x=0; x < (ssize_t) image->columns; x++)
253 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
254 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
255 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
256 SetPixelAlpha(image,OpaqueAlpha,q);
257 if (image->matte != MagickFalse)
258 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
259 p+=GetPixelChannels(canvas_image);
260 q+=GetPixelChannels(image);
262 if (SyncAuthenticPixels(image,exception) == MagickFalse)
265 if (image->previous == (Image *) NULL)
267 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
269 if (status == MagickFalse)
272 count=ReadBlob(image,length,pixels);
288 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
290 if (LocaleCompare(image_info->magick,"RGBO") == 0)
291 quantum_types[3]=OpacityQuantum;
294 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
295 count=ReadBlob(image,length,pixels);
297 for (y=0; y < (ssize_t) image->extract_info.height; y++)
299 register const Quantum
308 if (count != (ssize_t) length)
310 ThrowFileException(exception,CorruptImageError,
311 "UnexpectedEndOfFile",image->filename);
314 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
316 quantum_type=quantum_types[i];
317 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
319 if (q == (Quantum *) NULL)
321 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
322 quantum_info,quantum_type,pixels,exception);
323 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
325 if (((y-image->extract_info.y) >= 0) &&
326 ((y-image->extract_info.y) < (ssize_t) image->rows))
328 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
329 0,canvas_image->columns,1,exception);
330 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
331 image->columns,1,exception);
332 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
334 for (x=0; x < (ssize_t) image->columns; x++)
336 switch (quantum_type)
340 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
345 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
350 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
355 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
360 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
366 p+=GetPixelChannels(canvas_image);
367 q+=GetPixelChannels(image);
369 if (SyncAuthenticPixels(image,exception) == MagickFalse)
372 count=ReadBlob(image,length,pixels);
374 if (image->previous == (Image *) NULL)
376 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
378 if (status == MagickFalse)
387 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
391 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
392 count=ReadBlob(image,length,pixels);
394 for (y=0; y < (ssize_t) image->extract_info.height; y++)
396 register const Quantum
405 if (count != (ssize_t) length)
407 ThrowFileException(exception,CorruptImageError,
408 "UnexpectedEndOfFile",image->filename);
411 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
413 if (q == (Quantum *) NULL)
415 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
416 quantum_info,RedQuantum,pixels,exception);
417 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
419 if (((y-image->extract_info.y) >= 0) &&
420 ((y-image->extract_info.y) < (ssize_t) image->rows))
422 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
423 canvas_image->columns,1,exception);
424 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
425 image->columns,1,exception);
426 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
428 for (x=0; x < (ssize_t) image->columns; x++)
430 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
431 p+=GetPixelChannels(canvas_image);
432 q+=GetPixelChannels(image);
434 if (SyncAuthenticPixels(image,exception) == MagickFalse)
437 count=ReadBlob(image,length,pixels);
439 if (image->previous == (Image *) NULL)
441 status=SetImageProgress(image,LoadImageTag,1,6);
442 if (status == MagickFalse)
445 for (y=0; y < (ssize_t) image->extract_info.height; y++)
447 register const Quantum
456 if (count != (ssize_t) length)
458 ThrowFileException(exception,CorruptImageError,
459 "UnexpectedEndOfFile",image->filename);
462 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
464 if (q == (Quantum *) NULL)
466 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
467 quantum_info,GreenQuantum,pixels,exception);
468 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
470 if (((y-image->extract_info.y) >= 0) &&
471 ((y-image->extract_info.y) < (ssize_t) image->rows))
473 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
474 canvas_image->columns,1,exception);
475 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
476 image->columns,1,exception);
477 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
479 for (x=0; x < (ssize_t) image->columns; x++)
481 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
482 p+=GetPixelChannels(canvas_image);
483 q+=GetPixelChannels(image);
485 if (SyncAuthenticPixels(image,exception) == MagickFalse)
488 count=ReadBlob(image,length,pixels);
490 if (image->previous == (Image *) NULL)
492 status=SetImageProgress(image,LoadImageTag,2,6);
493 if (status == MagickFalse)
496 for (y=0; y < (ssize_t) image->extract_info.height; y++)
498 register const Quantum
507 if (count != (ssize_t) length)
509 ThrowFileException(exception,CorruptImageError,
510 "UnexpectedEndOfFile",image->filename);
513 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
515 if (q == (Quantum *) NULL)
517 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
518 quantum_info,BlueQuantum,pixels,exception);
519 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
521 if (((y-image->extract_info.y) >= 0) &&
522 ((y-image->extract_info.y) < (ssize_t) image->rows))
524 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
525 canvas_image->columns,1,exception);
526 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
527 image->columns,1,exception);
528 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
530 for (x=0; x < (ssize_t) image->columns; x++)
532 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
533 p+=GetPixelChannels(canvas_image);
534 q+=GetPixelChannels(image);
536 if (SyncAuthenticPixels(image,exception) == MagickFalse)
539 count=ReadBlob(image,length,pixels);
541 if (image->previous == (Image *) NULL)
543 status=SetImageProgress(image,LoadImageTag,3,6);
544 if (status == MagickFalse)
547 if (image->previous == (Image *) NULL)
549 status=SetImageProgress(image,LoadImageTag,4,6);
550 if (status == MagickFalse)
553 if (image->matte != MagickFalse)
555 for (y=0; y < (ssize_t) image->extract_info.height; y++)
557 register const Quantum
566 if (count != (ssize_t) length)
568 ThrowFileException(exception,CorruptImageError,
569 "UnexpectedEndOfFile",image->filename);
572 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
574 if (q == (Quantum *) NULL)
576 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
577 quantum_info,AlphaQuantum,pixels,exception);
578 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
580 if (((y-image->extract_info.y) >= 0) &&
581 ((y-image->extract_info.y) < (ssize_t) image->rows))
583 p=GetVirtualPixels(canvas_image,
584 canvas_image->extract_info.x,0,canvas_image->columns,1,
586 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
587 image->columns,1,exception);
588 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
590 for (x=0; x < (ssize_t) image->columns; x++)
592 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
593 p+=GetPixelChannels(canvas_image);
594 q+=GetPixelChannels(image);
596 if (SyncAuthenticPixels(image,exception) == MagickFalse)
599 count=ReadBlob(image,length,pixels);
601 if (image->previous == (Image *) NULL)
603 status=SetImageProgress(image,LoadImageTag,5,6);
604 if (status == MagickFalse)
608 if (image->previous == (Image *) NULL)
610 status=SetImageProgress(image,LoadImageTag,6,6);
611 if (status == MagickFalse)
616 case PartitionInterlace:
619 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
621 AppendImageFormat("R",image->filename);
622 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
623 if (status == MagickFalse)
625 canvas_image=DestroyImageList(canvas_image);
626 image=DestroyImageList(image);
627 return((Image *) NULL);
629 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
630 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
632 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
633 for (i=0; i < (ssize_t) scene; i++)
634 for (y=0; y < (ssize_t) image->extract_info.height; y++)
635 if (ReadBlob(image,length,pixels) != (ssize_t) length)
637 ThrowFileException(exception,CorruptImageError,
638 "UnexpectedEndOfFile",image->filename);
641 count=ReadBlob(image,length,pixels);
642 for (y=0; y < (ssize_t) image->extract_info.height; y++)
644 register const Quantum
653 if (count != (ssize_t) length)
655 ThrowFileException(exception,CorruptImageError,
656 "UnexpectedEndOfFile",image->filename);
659 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
661 if (q == (Quantum *) NULL)
663 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
664 quantum_info,RedQuantum,pixels,exception);
665 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
667 if (((y-image->extract_info.y) >= 0) &&
668 ((y-image->extract_info.y) < (ssize_t) image->rows))
670 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
671 canvas_image->columns,1,exception);
672 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
673 image->columns,1,exception);
674 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
676 for (x=0; x < (ssize_t) image->columns; x++)
678 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
679 p+=GetPixelChannels(canvas_image);
680 q+=GetPixelChannels(image);
682 if (SyncAuthenticPixels(image,exception) == MagickFalse)
685 count=ReadBlob(image,length,pixels);
687 if (image->previous == (Image *) NULL)
689 status=SetImageProgress(image,LoadImageTag,1,5);
690 if (status == MagickFalse)
693 (void) CloseBlob(image);
694 AppendImageFormat("G",image->filename);
695 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
696 if (status == MagickFalse)
698 canvas_image=DestroyImageList(canvas_image);
699 image=DestroyImageList(image);
700 return((Image *) NULL);
702 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
703 for (i=0; i < (ssize_t) scene; i++)
704 for (y=0; y < (ssize_t) image->extract_info.height; y++)
705 if (ReadBlob(image,length,pixels) != (ssize_t) length)
707 ThrowFileException(exception,CorruptImageError,
708 "UnexpectedEndOfFile",image->filename);
711 count=ReadBlob(image,length,pixels);
712 for (y=0; y < (ssize_t) image->extract_info.height; y++)
714 register const Quantum
723 if (count != (ssize_t) length)
725 ThrowFileException(exception,CorruptImageError,
726 "UnexpectedEndOfFile",image->filename);
729 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
731 if (q == (Quantum *) NULL)
733 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
734 quantum_info,GreenQuantum,pixels,exception);
735 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
737 if (((y-image->extract_info.y) >= 0) &&
738 ((y-image->extract_info.y) < (ssize_t) image->rows))
740 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
741 canvas_image->columns,1,exception);
742 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
743 image->columns,1,exception);
744 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
746 for (x=0; x < (ssize_t) image->columns; x++)
748 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
749 p+=GetPixelChannels(canvas_image);
750 q+=GetPixelChannels(image);
752 if (SyncAuthenticPixels(image,exception) == MagickFalse)
755 count=ReadBlob(image,length,pixels);
757 if (image->previous == (Image *) NULL)
759 status=SetImageProgress(image,LoadImageTag,2,5);
760 if (status == MagickFalse)
763 (void) CloseBlob(image);
764 AppendImageFormat("B",image->filename);
765 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
766 if (status == MagickFalse)
768 canvas_image=DestroyImageList(canvas_image);
769 image=DestroyImageList(image);
770 return((Image *) NULL);
772 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
773 for (i=0; i < (ssize_t) scene; i++)
774 for (y=0; y < (ssize_t) image->extract_info.height; y++)
775 if (ReadBlob(image,length,pixels) != (ssize_t) length)
777 ThrowFileException(exception,CorruptImageError,
778 "UnexpectedEndOfFile",image->filename);
781 count=ReadBlob(image,length,pixels);
782 for (y=0; y < (ssize_t) image->extract_info.height; y++)
784 register const Quantum
793 if (count != (ssize_t) length)
795 ThrowFileException(exception,CorruptImageError,
796 "UnexpectedEndOfFile",image->filename);
799 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
801 if (q == (Quantum *) NULL)
803 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
804 quantum_info,BlueQuantum,pixels,exception);
805 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
807 if (((y-image->extract_info.y) >= 0) &&
808 ((y-image->extract_info.y) < (ssize_t) image->rows))
810 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
811 canvas_image->columns,1,exception);
812 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
813 image->columns,1,exception);
814 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
816 for (x=0; x < (ssize_t) image->columns; x++)
818 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
819 p+=GetPixelChannels(canvas_image);
820 q+=GetPixelChannels(image);
822 if (SyncAuthenticPixels(image,exception) == MagickFalse)
825 count=ReadBlob(image,length,pixels);
827 if (image->previous == (Image *) NULL)
829 status=SetImageProgress(image,LoadImageTag,3,5);
830 if (status == MagickFalse)
833 if (image->matte != MagickFalse)
835 (void) CloseBlob(image);
836 AppendImageFormat("A",image->filename);
837 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
838 if (status == MagickFalse)
840 canvas_image=DestroyImageList(canvas_image);
841 image=DestroyImageList(image);
842 return((Image *) NULL);
844 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
845 for (i=0; i < (ssize_t) scene; i++)
846 for (y=0; y < (ssize_t) image->extract_info.height; y++)
847 if (ReadBlob(image,length,pixels) != (ssize_t) length)
849 ThrowFileException(exception,CorruptImageError,
850 "UnexpectedEndOfFile",image->filename);
853 count=ReadBlob(image,length,pixels);
854 for (y=0; y < (ssize_t) image->extract_info.height; y++)
856 register const Quantum
865 if (count != (ssize_t) length)
867 ThrowFileException(exception,CorruptImageError,
868 "UnexpectedEndOfFile",image->filename);
871 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
873 if (q == (Quantum *) NULL)
875 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
876 quantum_info,BlueQuantum,pixels,exception);
877 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
879 if (((y-image->extract_info.y) >= 0) &&
880 ((y-image->extract_info.y) < (ssize_t) image->rows))
882 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
883 0,canvas_image->columns,1,exception);
884 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
885 image->columns,1,exception);
886 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
888 for (x=0; x < (ssize_t) image->columns; x++)
890 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
891 p+=GetPixelChannels(canvas_image);
892 q+=GetPixelChannels(image);
894 if (SyncAuthenticPixels(image,exception) == MagickFalse)
897 count=ReadBlob(image,length,pixels);
899 if (image->previous == (Image *) NULL)
901 status=SetImageProgress(image,LoadImageTag,4,5);
902 if (status == MagickFalse)
906 (void) CloseBlob(image);
907 if (image->previous == (Image *) NULL)
909 status=SetImageProgress(image,LoadImageTag,5,5);
910 if (status == MagickFalse)
916 SetQuantumImageType(image,quantum_type);
918 Proceed to next image.
920 if (image_info->number_scenes != 0)
921 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
923 if (count == (ssize_t) length)
926 Allocate next image structure.
928 AcquireNextImage(image_info,image,exception);
929 if (GetNextImageInList(image) == (Image *) NULL)
931 image=DestroyImageList(image);
932 return((Image *) NULL);
934 image=SyncNextImageInList(image);
935 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
937 if (status == MagickFalse)
941 } while (count == (ssize_t) length);
942 quantum_info=DestroyQuantumInfo(quantum_info);
943 canvas_image=DestroyImage(canvas_image);
944 (void) CloseBlob(image);
945 return(GetFirstImageInList(image));
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953 % R e g i s t e r R G B I m a g e %
957 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 % RegisterRGBImage() adds attributes for the RGB image format to
960 % the list of supported formats. The attributes include the image format
961 % tag, a method to read and/or write the format, whether the format
962 % supports the saving of more than one frame to the same file or blob,
963 % whether the format supports native in-memory I/O, and a brief
964 % description of the format.
966 % The format of the RegisterRGBImage method is:
968 % size_t RegisterRGBImage(void)
971 ModuleExport size_t RegisterRGBImage(void)
976 entry=SetMagickInfo("RGB");
977 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
978 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
979 entry->raw=MagickTrue;
980 entry->endian_support=MagickTrue;
981 entry->description=ConstantString("Raw red, green, and blue samples");
982 entry->module=ConstantString("RGB");
983 (void) RegisterMagickInfo(entry);
984 entry=SetMagickInfo("RGBA");
985 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
986 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
987 entry->raw=MagickTrue;
988 entry->endian_support=MagickTrue;
989 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
990 entry->module=ConstantString("RGB");
991 (void) RegisterMagickInfo(entry);
992 entry=SetMagickInfo("RGBO");
993 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
994 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
995 entry->raw=MagickTrue;
996 entry->endian_support=MagickTrue;
997 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
998 entry->module=ConstantString("RGB");
999 (void) RegisterMagickInfo(entry);
1000 return(MagickImageCoderSignature);
1004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008 % U n r e g i s t e r R G B I m a g e %
1012 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1014 % UnregisterRGBImage() removes format registrations made by the RGB module
1015 % from the list of supported formats.
1017 % The format of the UnregisterRGBImage method is:
1019 % UnregisterRGBImage(void)
1022 ModuleExport void UnregisterRGBImage(void)
1024 (void) UnregisterMagickInfo("RGBO");
1025 (void) UnregisterMagickInfo("RGBA");
1026 (void) UnregisterMagickInfo("RGB");
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1034 % W r i t e R G B I m a g e %
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1040 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1041 % rasterfile format.
1043 % The format of the WriteRGBImage method is:
1045 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1046 % Image *image,ExceptionInfo *exception)
1048 % A description of each parameter follows.
1050 % o image_info: the image info.
1052 % o image: The image.
1054 % o exception: return any errors or warnings in this structure.
1057 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1058 Image *image,ExceptionInfo *exception)
1083 Allocate memory for pixels.
1085 assert(image_info != (const ImageInfo *) NULL);
1086 assert(image_info->signature == MagickSignature);
1087 assert(image != (Image *) NULL);
1088 assert(image->signature == MagickSignature);
1089 if (image->debug != MagickFalse)
1090 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1091 if (image_info->interlace != PartitionInterlace)
1094 Open output image file.
1096 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1097 if (status == MagickFalse)
1100 quantum_type=RGBQuantum;
1101 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1102 quantum_type=RGBAQuantum;
1103 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1104 quantum_type=RGBOQuantum;
1109 Convert MIFF to RGB raster pixels.
1111 if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
1112 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1113 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1114 (image->matte == MagickFalse))
1115 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1116 quantum_info=AcquireQuantumInfo(image_info,image);
1117 if (quantum_info == (QuantumInfo *) NULL)
1118 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1119 pixels=GetQuantumPixels(quantum_info);
1120 switch (image_info->interlace)
1126 No interlacing: RGBRGBRGBRGBRGBRGB...
1128 for (y=0; y < (ssize_t) image->rows; y++)
1130 register const Quantum
1133 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1134 if (p == (const Quantum *) NULL)
1136 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1137 quantum_type,pixels,exception);
1138 count=WriteBlob(image,length,pixels);
1139 if (count != (ssize_t) length)
1141 if (image->previous == (Image *) NULL)
1143 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1145 if (status == MagickFalse)
1154 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1156 for (y=0; y < (ssize_t) image->rows; y++)
1158 register const Quantum
1161 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1162 if (p == (const Quantum *) NULL)
1164 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1165 RedQuantum,pixels,exception);
1166 count=WriteBlob(image,length,pixels);
1167 if (count != (ssize_t) length)
1169 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1170 GreenQuantum,pixels,exception);
1171 count=WriteBlob(image,length,pixels);
1172 if (count != (ssize_t) length)
1174 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1175 BlueQuantum,pixels,exception);
1176 count=WriteBlob(image,length,pixels);
1177 if (count != (ssize_t) length)
1179 if (quantum_type == RGBAQuantum)
1181 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1182 AlphaQuantum,pixels,exception);
1183 count=WriteBlob(image,length,pixels);
1184 if (count != (ssize_t) length)
1187 if (quantum_type == RGBOQuantum)
1189 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1190 OpacityQuantum,pixels,exception);
1191 count=WriteBlob(image,length,pixels);
1192 if (count != (ssize_t) length)
1195 if (image->previous == (Image *) NULL)
1197 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1199 if (status == MagickFalse)
1205 case PlaneInterlace:
1208 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1210 for (y=0; y < (ssize_t) image->rows; y++)
1212 register const Quantum
1215 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1216 if (p == (const Quantum *) NULL)
1218 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1219 RedQuantum,pixels,exception);
1220 count=WriteBlob(image,length,pixels);
1221 if (count != (ssize_t) length)
1224 if (image->previous == (Image *) NULL)
1226 status=SetImageProgress(image,SaveImageTag,1,6);
1227 if (status == MagickFalse)
1230 for (y=0; y < (ssize_t) image->rows; y++)
1232 register const Quantum
1235 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1236 if (p == (const Quantum *) NULL)
1238 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1239 GreenQuantum,pixels,exception);
1240 count=WriteBlob(image,length,pixels);
1241 if (count != (ssize_t) length)
1244 if (image->previous == (Image *) NULL)
1246 status=SetImageProgress(image,SaveImageTag,2,6);
1247 if (status == MagickFalse)
1250 for (y=0; y < (ssize_t) image->rows; y++)
1252 register const Quantum
1255 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1256 if (p == (const Quantum *) NULL)
1258 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1259 BlueQuantum,pixels,exception);
1260 count=WriteBlob(image,length,pixels);
1261 if (count != (ssize_t) length)
1264 if (image->previous == (Image *) NULL)
1266 status=SetImageProgress(image,SaveImageTag,3,6);
1267 if (status == MagickFalse)
1270 if (quantum_type == RGBAQuantum)
1272 for (y=0; y < (ssize_t) image->rows; y++)
1274 register const Quantum
1277 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1278 if (p == (const Quantum *) NULL)
1280 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1281 AlphaQuantum,pixels,exception);
1282 count=WriteBlob(image,length,pixels);
1283 if (count != (ssize_t) length)
1286 if (image->previous == (Image *) NULL)
1288 status=SetImageProgress(image,SaveImageTag,5,6);
1289 if (status == MagickFalse)
1293 if (image_info->interlace == PartitionInterlace)
1294 (void) CopyMagickString(image->filename,image_info->filename,
1296 if (image->previous == (Image *) NULL)
1298 status=SetImageProgress(image,SaveImageTag,6,6);
1299 if (status == MagickFalse)
1304 case PartitionInterlace:
1307 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1309 AppendImageFormat("R",image->filename);
1310 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1311 AppendBinaryBlobMode,exception);
1312 if (status == MagickFalse)
1314 for (y=0; y < (ssize_t) image->rows; y++)
1316 register const Quantum
1319 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1320 if (p == (const Quantum *) NULL)
1322 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1323 RedQuantum,pixels,exception);
1324 count=WriteBlob(image,length,pixels);
1325 if (count != (ssize_t) length)
1328 if (image->previous == (Image *) NULL)
1330 status=SetImageProgress(image,SaveImageTag,1,6);
1331 if (status == MagickFalse)
1334 (void) CloseBlob(image);
1335 AppendImageFormat("G",image->filename);
1336 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1337 AppendBinaryBlobMode,exception);
1338 if (status == MagickFalse)
1340 for (y=0; y < (ssize_t) image->rows; y++)
1342 register const Quantum
1345 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1346 if (p == (const Quantum *) NULL)
1348 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1349 GreenQuantum,pixels,exception);
1350 count=WriteBlob(image,length,pixels);
1351 if (count != (ssize_t) length)
1354 if (image->previous == (Image *) NULL)
1356 status=SetImageProgress(image,SaveImageTag,2,6);
1357 if (status == MagickFalse)
1360 (void) CloseBlob(image);
1361 AppendImageFormat("B",image->filename);
1362 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1363 AppendBinaryBlobMode,exception);
1364 if (status == MagickFalse)
1366 for (y=0; y < (ssize_t) image->rows; y++)
1368 register const Quantum
1371 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1372 if (p == (const Quantum *) NULL)
1374 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1375 BlueQuantum,pixels,exception);
1376 count=WriteBlob(image,length,pixels);
1377 if (count != (ssize_t) length)
1380 if (image->previous == (Image *) NULL)
1382 status=SetImageProgress(image,SaveImageTag,3,6);
1383 if (status == MagickFalse)
1386 (void) CloseBlob(image);
1387 if (quantum_type == RGBAQuantum)
1389 (void) CloseBlob(image);
1390 AppendImageFormat("A",image->filename);
1391 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1392 AppendBinaryBlobMode,exception);
1393 if (status == MagickFalse)
1395 for (y=0; y < (ssize_t) image->rows; y++)
1397 register const Quantum
1400 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1401 if (p == (const Quantum *) NULL)
1403 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1404 AlphaQuantum,pixels,exception);
1405 count=WriteBlob(image,length,pixels);
1406 if (count != (ssize_t) length)
1409 if (image->previous == (Image *) NULL)
1411 status=SetImageProgress(image,SaveImageTag,5,6);
1412 if (status == MagickFalse)
1416 (void) CloseBlob(image);
1417 (void) CopyMagickString(image->filename,image_info->filename,
1419 if (image->previous == (Image *) NULL)
1421 status=SetImageProgress(image,SaveImageTag,6,6);
1422 if (status == MagickFalse)
1428 quantum_info=DestroyQuantumInfo(quantum_info);
1429 if (GetNextImageInList(image) == (Image *) NULL)
1431 image=SyncNextImageInList(image);
1432 status=SetImageProgress(image,SaveImagesTag,scene++,
1433 GetImageListLength(image));
1434 if (status == MagickFalse)
1436 } while (image_info->adjoin != MagickFalse);
1437 (void) CloseBlob(image);