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 SetImageColorspace(image,sRGBColorspace,exception);
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 pixels=GetQuantumPixels(quantum_info);
167 quantum_type=RGBQuantum;
168 if (LocaleCompare(image_info->magick,"RGBA") == 0)
170 quantum_type=RGBAQuantum;
171 image->matte=MagickTrue;
172 canvas_image->matte=MagickTrue;
174 if (LocaleCompare(image_info->magick,"RGBO") == 0)
176 quantum_type=RGBOQuantum;
177 canvas_image->matte=MagickTrue;
179 if (image_info->number_scenes != 0)
180 while (image->scene < image_info->scene)
186 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
187 for (y=0; y < (ssize_t) image->rows; y++)
189 count=ReadBlob(image,length,pixels);
190 if (count != (ssize_t) length)
200 Read pixels to virtual canvas image then push to image.
202 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
203 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
205 SetImageColorspace(image,sRGBColorspace,exception);
206 switch (image_info->interlace)
212 No interlacing: RGBRGBRGBRGBRGBRGB...
216 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
217 count=ReadBlob(image,length,pixels);
219 for (y=0; y < (ssize_t) image->extract_info.height; y++)
221 register const Quantum
230 if (count != (ssize_t) length)
232 ThrowFileException(exception,CorruptImageError,
233 "UnexpectedEndOfFile",image->filename);
236 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
238 if (q == (Quantum *) NULL)
240 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
241 quantum_info,quantum_type,pixels,exception);
242 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
244 if (((y-image->extract_info.y) >= 0) &&
245 ((y-image->extract_info.y) < (ssize_t) image->rows))
247 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
248 canvas_image->columns,1,exception);
249 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
250 image->columns,1,exception);
251 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
253 for (x=0; x < (ssize_t) image->columns; x++)
255 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
256 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
257 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
258 SetPixelAlpha(image,OpaqueAlpha,q);
259 if (image->matte != MagickFalse)
260 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
261 p+=GetPixelChannels(canvas_image);
262 q+=GetPixelChannels(image);
264 if (SyncAuthenticPixels(image,exception) == MagickFalse)
267 if (image->previous == (Image *) NULL)
269 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
271 if (status == MagickFalse)
274 count=ReadBlob(image,length,pixels);
290 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
292 if (LocaleCompare(image_info->magick,"RGBO") == 0)
293 quantum_types[3]=OpacityQuantum;
296 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
297 count=ReadBlob(image,length,pixels);
299 for (y=0; y < (ssize_t) image->extract_info.height; y++)
301 register const Quantum
310 if (count != (ssize_t) length)
312 ThrowFileException(exception,CorruptImageError,
313 "UnexpectedEndOfFile",image->filename);
316 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
318 quantum_type=quantum_types[i];
319 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
321 if (q == (Quantum *) NULL)
323 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
324 quantum_info,quantum_type,pixels,exception);
325 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
327 if (((y-image->extract_info.y) >= 0) &&
328 ((y-image->extract_info.y) < (ssize_t) image->rows))
330 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
331 0,canvas_image->columns,1,exception);
332 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
333 image->columns,1,exception);
334 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
336 for (x=0; x < (ssize_t) image->columns; x++)
338 switch (quantum_type)
342 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
347 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
352 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
357 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
362 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
368 p+=GetPixelChannels(canvas_image);
369 q+=GetPixelChannels(image);
371 if (SyncAuthenticPixels(image,exception) == MagickFalse)
374 count=ReadBlob(image,length,pixels);
376 if (image->previous == (Image *) NULL)
378 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
380 if (status == MagickFalse)
389 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
393 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
394 count=ReadBlob(image,length,pixels);
396 for (y=0; y < (ssize_t) image->extract_info.height; y++)
398 register const Quantum
407 if (count != (ssize_t) length)
409 ThrowFileException(exception,CorruptImageError,
410 "UnexpectedEndOfFile",image->filename);
413 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
415 if (q == (Quantum *) NULL)
417 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
418 quantum_info,RedQuantum,pixels,exception);
419 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
421 if (((y-image->extract_info.y) >= 0) &&
422 ((y-image->extract_info.y) < (ssize_t) image->rows))
424 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
425 canvas_image->columns,1,exception);
426 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
427 image->columns,1,exception);
428 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
430 for (x=0; x < (ssize_t) image->columns; x++)
432 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
433 p+=GetPixelChannels(canvas_image);
434 q+=GetPixelChannels(image);
436 if (SyncAuthenticPixels(image,exception) == MagickFalse)
439 count=ReadBlob(image,length,pixels);
441 if (image->previous == (Image *) NULL)
443 status=SetImageProgress(image,LoadImageTag,1,6);
444 if (status == MagickFalse)
447 for (y=0; y < (ssize_t) image->extract_info.height; y++)
449 register const Quantum
458 if (count != (ssize_t) length)
460 ThrowFileException(exception,CorruptImageError,
461 "UnexpectedEndOfFile",image->filename);
464 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
466 if (q == (Quantum *) NULL)
468 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
469 quantum_info,GreenQuantum,pixels,exception);
470 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
472 if (((y-image->extract_info.y) >= 0) &&
473 ((y-image->extract_info.y) < (ssize_t) image->rows))
475 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
476 canvas_image->columns,1,exception);
477 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
478 image->columns,1,exception);
479 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
481 for (x=0; x < (ssize_t) image->columns; x++)
483 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
484 p+=GetPixelChannels(canvas_image);
485 q+=GetPixelChannels(image);
487 if (SyncAuthenticPixels(image,exception) == MagickFalse)
490 count=ReadBlob(image,length,pixels);
492 if (image->previous == (Image *) NULL)
494 status=SetImageProgress(image,LoadImageTag,2,6);
495 if (status == MagickFalse)
498 for (y=0; y < (ssize_t) image->extract_info.height; y++)
500 register const Quantum
509 if (count != (ssize_t) length)
511 ThrowFileException(exception,CorruptImageError,
512 "UnexpectedEndOfFile",image->filename);
515 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
517 if (q == (Quantum *) NULL)
519 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
520 quantum_info,BlueQuantum,pixels,exception);
521 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
523 if (((y-image->extract_info.y) >= 0) &&
524 ((y-image->extract_info.y) < (ssize_t) image->rows))
526 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
527 canvas_image->columns,1,exception);
528 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
529 image->columns,1,exception);
530 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
532 for (x=0; x < (ssize_t) image->columns; x++)
534 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
535 p+=GetPixelChannels(canvas_image);
536 q+=GetPixelChannels(image);
538 if (SyncAuthenticPixels(image,exception) == MagickFalse)
541 count=ReadBlob(image,length,pixels);
543 if (image->previous == (Image *) NULL)
545 status=SetImageProgress(image,LoadImageTag,3,6);
546 if (status == MagickFalse)
549 if (image->previous == (Image *) NULL)
551 status=SetImageProgress(image,LoadImageTag,4,6);
552 if (status == MagickFalse)
555 if (image->matte != MagickFalse)
557 for (y=0; y < (ssize_t) image->extract_info.height; y++)
559 register const Quantum
568 if (count != (ssize_t) length)
570 ThrowFileException(exception,CorruptImageError,
571 "UnexpectedEndOfFile",image->filename);
574 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
576 if (q == (Quantum *) NULL)
578 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
579 quantum_info,AlphaQuantum,pixels,exception);
580 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
582 if (((y-image->extract_info.y) >= 0) &&
583 ((y-image->extract_info.y) < (ssize_t) image->rows))
585 p=GetVirtualPixels(canvas_image,
586 canvas_image->extract_info.x,0,canvas_image->columns,1,
588 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
589 image->columns,1,exception);
590 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
592 for (x=0; x < (ssize_t) image->columns; x++)
594 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
595 p+=GetPixelChannels(canvas_image);
596 q+=GetPixelChannels(image);
598 if (SyncAuthenticPixels(image,exception) == MagickFalse)
601 count=ReadBlob(image,length,pixels);
603 if (image->previous == (Image *) NULL)
605 status=SetImageProgress(image,LoadImageTag,5,6);
606 if (status == MagickFalse)
610 if (image->previous == (Image *) NULL)
612 status=SetImageProgress(image,LoadImageTag,6,6);
613 if (status == MagickFalse)
618 case PartitionInterlace:
621 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
623 AppendImageFormat("R",image->filename);
624 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
625 if (status == MagickFalse)
627 canvas_image=DestroyImageList(canvas_image);
628 image=DestroyImageList(image);
629 return((Image *) NULL);
631 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
632 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
634 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
635 for (i=0; i < (ssize_t) scene; i++)
636 for (y=0; y < (ssize_t) image->extract_info.height; y++)
637 if (ReadBlob(image,length,pixels) != (ssize_t) length)
639 ThrowFileException(exception,CorruptImageError,
640 "UnexpectedEndOfFile",image->filename);
643 count=ReadBlob(image,length,pixels);
644 for (y=0; y < (ssize_t) image->extract_info.height; y++)
646 register const Quantum
655 if (count != (ssize_t) length)
657 ThrowFileException(exception,CorruptImageError,
658 "UnexpectedEndOfFile",image->filename);
661 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
663 if (q == (Quantum *) NULL)
665 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
666 quantum_info,RedQuantum,pixels,exception);
667 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
669 if (((y-image->extract_info.y) >= 0) &&
670 ((y-image->extract_info.y) < (ssize_t) image->rows))
672 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
673 canvas_image->columns,1,exception);
674 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
675 image->columns,1,exception);
676 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
678 for (x=0; x < (ssize_t) image->columns; x++)
680 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
681 p+=GetPixelChannels(canvas_image);
682 q+=GetPixelChannels(image);
684 if (SyncAuthenticPixels(image,exception) == MagickFalse)
687 count=ReadBlob(image,length,pixels);
689 if (image->previous == (Image *) NULL)
691 status=SetImageProgress(image,LoadImageTag,1,5);
692 if (status == MagickFalse)
695 (void) CloseBlob(image);
696 AppendImageFormat("G",image->filename);
697 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
698 if (status == MagickFalse)
700 canvas_image=DestroyImageList(canvas_image);
701 image=DestroyImageList(image);
702 return((Image *) NULL);
704 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
705 for (i=0; i < (ssize_t) scene; i++)
706 for (y=0; y < (ssize_t) image->extract_info.height; y++)
707 if (ReadBlob(image,length,pixels) != (ssize_t) length)
709 ThrowFileException(exception,CorruptImageError,
710 "UnexpectedEndOfFile",image->filename);
713 count=ReadBlob(image,length,pixels);
714 for (y=0; y < (ssize_t) image->extract_info.height; y++)
716 register const Quantum
725 if (count != (ssize_t) length)
727 ThrowFileException(exception,CorruptImageError,
728 "UnexpectedEndOfFile",image->filename);
731 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
733 if (q == (Quantum *) NULL)
735 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
736 quantum_info,GreenQuantum,pixels,exception);
737 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
739 if (((y-image->extract_info.y) >= 0) &&
740 ((y-image->extract_info.y) < (ssize_t) image->rows))
742 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
743 canvas_image->columns,1,exception);
744 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
745 image->columns,1,exception);
746 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
748 for (x=0; x < (ssize_t) image->columns; x++)
750 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
751 p+=GetPixelChannels(canvas_image);
752 q+=GetPixelChannels(image);
754 if (SyncAuthenticPixels(image,exception) == MagickFalse)
757 count=ReadBlob(image,length,pixels);
759 if (image->previous == (Image *) NULL)
761 status=SetImageProgress(image,LoadImageTag,2,5);
762 if (status == MagickFalse)
765 (void) CloseBlob(image);
766 AppendImageFormat("B",image->filename);
767 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
768 if (status == MagickFalse)
770 canvas_image=DestroyImageList(canvas_image);
771 image=DestroyImageList(image);
772 return((Image *) NULL);
774 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
775 for (i=0; i < (ssize_t) scene; i++)
776 for (y=0; y < (ssize_t) image->extract_info.height; y++)
777 if (ReadBlob(image,length,pixels) != (ssize_t) length)
779 ThrowFileException(exception,CorruptImageError,
780 "UnexpectedEndOfFile",image->filename);
783 count=ReadBlob(image,length,pixels);
784 for (y=0; y < (ssize_t) image->extract_info.height; y++)
786 register const Quantum
795 if (count != (ssize_t) length)
797 ThrowFileException(exception,CorruptImageError,
798 "UnexpectedEndOfFile",image->filename);
801 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
803 if (q == (Quantum *) NULL)
805 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
806 quantum_info,BlueQuantum,pixels,exception);
807 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
809 if (((y-image->extract_info.y) >= 0) &&
810 ((y-image->extract_info.y) < (ssize_t) image->rows))
812 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
813 canvas_image->columns,1,exception);
814 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
815 image->columns,1,exception);
816 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
818 for (x=0; x < (ssize_t) image->columns; x++)
820 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
821 p+=GetPixelChannels(canvas_image);
822 q+=GetPixelChannels(image);
824 if (SyncAuthenticPixels(image,exception) == MagickFalse)
827 count=ReadBlob(image,length,pixels);
829 if (image->previous == (Image *) NULL)
831 status=SetImageProgress(image,LoadImageTag,3,5);
832 if (status == MagickFalse)
835 if (image->matte != MagickFalse)
837 (void) CloseBlob(image);
838 AppendImageFormat("A",image->filename);
839 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
840 if (status == MagickFalse)
842 canvas_image=DestroyImageList(canvas_image);
843 image=DestroyImageList(image);
844 return((Image *) NULL);
846 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
847 for (i=0; i < (ssize_t) scene; i++)
848 for (y=0; y < (ssize_t) image->extract_info.height; y++)
849 if (ReadBlob(image,length,pixels) != (ssize_t) length)
851 ThrowFileException(exception,CorruptImageError,
852 "UnexpectedEndOfFile",image->filename);
855 count=ReadBlob(image,length,pixels);
856 for (y=0; y < (ssize_t) image->extract_info.height; y++)
858 register const Quantum
867 if (count != (ssize_t) length)
869 ThrowFileException(exception,CorruptImageError,
870 "UnexpectedEndOfFile",image->filename);
873 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
875 if (q == (Quantum *) NULL)
877 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
878 quantum_info,BlueQuantum,pixels,exception);
879 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
881 if (((y-image->extract_info.y) >= 0) &&
882 ((y-image->extract_info.y) < (ssize_t) image->rows))
884 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
885 0,canvas_image->columns,1,exception);
886 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
887 image->columns,1,exception);
888 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
890 for (x=0; x < (ssize_t) image->columns; x++)
892 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
893 p+=GetPixelChannels(canvas_image);
894 q+=GetPixelChannels(image);
896 if (SyncAuthenticPixels(image,exception) == MagickFalse)
899 count=ReadBlob(image,length,pixels);
901 if (image->previous == (Image *) NULL)
903 status=SetImageProgress(image,LoadImageTag,4,5);
904 if (status == MagickFalse)
908 (void) CloseBlob(image);
909 if (image->previous == (Image *) NULL)
911 status=SetImageProgress(image,LoadImageTag,5,5);
912 if (status == MagickFalse)
918 SetQuantumImageType(image,quantum_type);
920 Proceed to next image.
922 if (image_info->number_scenes != 0)
923 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
925 if (count == (ssize_t) length)
928 Allocate next image structure.
930 AcquireNextImage(image_info,image,exception);
931 if (GetNextImageInList(image) == (Image *) NULL)
933 image=DestroyImageList(image);
934 return((Image *) NULL);
936 image=SyncNextImageInList(image);
937 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
939 if (status == MagickFalse)
943 } while (count == (ssize_t) length);
944 quantum_info=DestroyQuantumInfo(quantum_info);
945 canvas_image=DestroyImage(canvas_image);
946 (void) CloseBlob(image);
947 return(GetFirstImageInList(image));
951 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955 % R e g i s t e r R G B I m a g e %
959 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
961 % RegisterRGBImage() adds attributes for the RGB image format to
962 % the list of supported formats. The attributes include the image format
963 % tag, a method to read and/or write the format, whether the format
964 % supports the saving of more than one frame to the same file or blob,
965 % whether the format supports native in-memory I/O, and a brief
966 % description of the format.
968 % The format of the RegisterRGBImage method is:
970 % size_t RegisterRGBImage(void)
973 ModuleExport size_t RegisterRGBImage(void)
978 entry=SetMagickInfo("RGB");
979 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
980 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
981 entry->raw=MagickTrue;
982 entry->endian_support=MagickTrue;
983 entry->description=ConstantString("Raw red, green, and blue samples");
984 entry->module=ConstantString("RGB");
985 (void) RegisterMagickInfo(entry);
986 entry=SetMagickInfo("RGBA");
987 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
988 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
989 entry->raw=MagickTrue;
990 entry->endian_support=MagickTrue;
991 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
992 entry->module=ConstantString("RGB");
993 (void) RegisterMagickInfo(entry);
994 entry=SetMagickInfo("RGBO");
995 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
996 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
997 entry->raw=MagickTrue;
998 entry->endian_support=MagickTrue;
999 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1000 entry->module=ConstantString("RGB");
1001 (void) RegisterMagickInfo(entry);
1002 return(MagickImageCoderSignature);
1006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1010 % U n r e g i s t e r R G B I m a g e %
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016 % UnregisterRGBImage() removes format registrations made by the RGB module
1017 % from the list of supported formats.
1019 % The format of the UnregisterRGBImage method is:
1021 % UnregisterRGBImage(void)
1024 ModuleExport void UnregisterRGBImage(void)
1026 (void) UnregisterMagickInfo("RGBO");
1027 (void) UnregisterMagickInfo("RGBA");
1028 (void) UnregisterMagickInfo("RGB");
1032 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1036 % W r i t e R G B I m a g e %
1040 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1043 % rasterfile format.
1045 % The format of the WriteRGBImage method is:
1047 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1048 % Image *image,ExceptionInfo *exception)
1050 % A description of each parameter follows.
1052 % o image_info: the image info.
1054 % o image: The image.
1056 % o exception: return any errors or warnings in this structure.
1059 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1060 Image *image,ExceptionInfo *exception)
1085 Allocate memory for pixels.
1087 assert(image_info != (const ImageInfo *) NULL);
1088 assert(image_info->signature == MagickSignature);
1089 assert(image != (Image *) NULL);
1090 assert(image->signature == MagickSignature);
1091 if (image->debug != MagickFalse)
1092 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1093 if (image_info->interlace != PartitionInterlace)
1096 Open output image file.
1098 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1099 if (status == MagickFalse)
1102 quantum_type=RGBQuantum;
1103 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1104 quantum_type=RGBAQuantum;
1105 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1106 quantum_type=RGBOQuantum;
1111 Convert MIFF to RGB raster pixels.
1113 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1114 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1115 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1116 (image->matte == MagickFalse))
1117 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1118 quantum_info=AcquireQuantumInfo(image_info,image);
1119 if (quantum_info == (QuantumInfo *) NULL)
1120 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1121 pixels=GetQuantumPixels(quantum_info);
1122 switch (image_info->interlace)
1128 No interlacing: RGBRGBRGBRGBRGBRGB...
1130 for (y=0; y < (ssize_t) image->rows; y++)
1132 register const Quantum
1135 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1136 if (p == (const Quantum *) NULL)
1138 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1139 quantum_type,pixels,exception);
1140 count=WriteBlob(image,length,pixels);
1141 if (count != (ssize_t) length)
1143 if (image->previous == (Image *) NULL)
1145 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1147 if (status == MagickFalse)
1156 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1158 for (y=0; y < (ssize_t) image->rows; y++)
1160 register const Quantum
1163 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1164 if (p == (const Quantum *) NULL)
1166 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1167 RedQuantum,pixels,exception);
1168 count=WriteBlob(image,length,pixels);
1169 if (count != (ssize_t) length)
1171 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1172 GreenQuantum,pixels,exception);
1173 count=WriteBlob(image,length,pixels);
1174 if (count != (ssize_t) length)
1176 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1177 BlueQuantum,pixels,exception);
1178 count=WriteBlob(image,length,pixels);
1179 if (count != (ssize_t) length)
1181 if (quantum_type == RGBAQuantum)
1183 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1184 AlphaQuantum,pixels,exception);
1185 count=WriteBlob(image,length,pixels);
1186 if (count != (ssize_t) length)
1189 if (quantum_type == RGBOQuantum)
1191 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1192 OpacityQuantum,pixels,exception);
1193 count=WriteBlob(image,length,pixels);
1194 if (count != (ssize_t) length)
1197 if (image->previous == (Image *) NULL)
1199 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1201 if (status == MagickFalse)
1207 case PlaneInterlace:
1210 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1212 for (y=0; y < (ssize_t) image->rows; y++)
1214 register const Quantum
1217 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1218 if (p == (const Quantum *) NULL)
1220 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1221 RedQuantum,pixels,exception);
1222 count=WriteBlob(image,length,pixels);
1223 if (count != (ssize_t) length)
1226 if (image->previous == (Image *) NULL)
1228 status=SetImageProgress(image,SaveImageTag,1,6);
1229 if (status == MagickFalse)
1232 for (y=0; y < (ssize_t) image->rows; y++)
1234 register const Quantum
1237 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1238 if (p == (const Quantum *) NULL)
1240 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1241 GreenQuantum,pixels,exception);
1242 count=WriteBlob(image,length,pixels);
1243 if (count != (ssize_t) length)
1246 if (image->previous == (Image *) NULL)
1248 status=SetImageProgress(image,SaveImageTag,2,6);
1249 if (status == MagickFalse)
1252 for (y=0; y < (ssize_t) image->rows; y++)
1254 register const Quantum
1257 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1258 if (p == (const Quantum *) NULL)
1260 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1261 BlueQuantum,pixels,exception);
1262 count=WriteBlob(image,length,pixels);
1263 if (count != (ssize_t) length)
1266 if (image->previous == (Image *) NULL)
1268 status=SetImageProgress(image,SaveImageTag,3,6);
1269 if (status == MagickFalse)
1272 if (quantum_type == RGBAQuantum)
1274 for (y=0; y < (ssize_t) image->rows; y++)
1276 register const Quantum
1279 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1280 if (p == (const Quantum *) NULL)
1282 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1283 AlphaQuantum,pixels,exception);
1284 count=WriteBlob(image,length,pixels);
1285 if (count != (ssize_t) length)
1288 if (image->previous == (Image *) NULL)
1290 status=SetImageProgress(image,SaveImageTag,5,6);
1291 if (status == MagickFalse)
1295 if (image_info->interlace == PartitionInterlace)
1296 (void) CopyMagickString(image->filename,image_info->filename,
1298 if (image->previous == (Image *) NULL)
1300 status=SetImageProgress(image,SaveImageTag,6,6);
1301 if (status == MagickFalse)
1306 case PartitionInterlace:
1309 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1311 AppendImageFormat("R",image->filename);
1312 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1313 AppendBinaryBlobMode,exception);
1314 if (status == MagickFalse)
1316 for (y=0; y < (ssize_t) image->rows; y++)
1318 register const Quantum
1321 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1322 if (p == (const Quantum *) NULL)
1324 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1325 RedQuantum,pixels,exception);
1326 count=WriteBlob(image,length,pixels);
1327 if (count != (ssize_t) length)
1330 if (image->previous == (Image *) NULL)
1332 status=SetImageProgress(image,SaveImageTag,1,6);
1333 if (status == MagickFalse)
1336 (void) CloseBlob(image);
1337 AppendImageFormat("G",image->filename);
1338 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1339 AppendBinaryBlobMode,exception);
1340 if (status == MagickFalse)
1342 for (y=0; y < (ssize_t) image->rows; y++)
1344 register const Quantum
1347 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1348 if (p == (const Quantum *) NULL)
1350 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1351 GreenQuantum,pixels,exception);
1352 count=WriteBlob(image,length,pixels);
1353 if (count != (ssize_t) length)
1356 if (image->previous == (Image *) NULL)
1358 status=SetImageProgress(image,SaveImageTag,2,6);
1359 if (status == MagickFalse)
1362 (void) CloseBlob(image);
1363 AppendImageFormat("B",image->filename);
1364 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1365 AppendBinaryBlobMode,exception);
1366 if (status == MagickFalse)
1368 for (y=0; y < (ssize_t) image->rows; y++)
1370 register const Quantum
1373 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1374 if (p == (const Quantum *) NULL)
1376 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1377 BlueQuantum,pixels,exception);
1378 count=WriteBlob(image,length,pixels);
1379 if (count != (ssize_t) length)
1382 if (image->previous == (Image *) NULL)
1384 status=SetImageProgress(image,SaveImageTag,3,6);
1385 if (status == MagickFalse)
1388 (void) CloseBlob(image);
1389 if (quantum_type == RGBAQuantum)
1391 (void) CloseBlob(image);
1392 AppendImageFormat("A",image->filename);
1393 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1394 AppendBinaryBlobMode,exception);
1395 if (status == MagickFalse)
1397 for (y=0; y < (ssize_t) image->rows; y++)
1399 register const Quantum
1402 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1403 if (p == (const Quantum *) NULL)
1405 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1406 AlphaQuantum,pixels,exception);
1407 count=WriteBlob(image,length,pixels);
1408 if (count != (ssize_t) length)
1411 if (image->previous == (Image *) NULL)
1413 status=SetImageProgress(image,SaveImageTag,5,6);
1414 if (status == MagickFalse)
1418 (void) CloseBlob(image);
1419 (void) CopyMagickString(image->filename,image_info->filename,
1421 if (image->previous == (Image *) NULL)
1423 status=SetImageProgress(image,SaveImageTag,6,6);
1424 if (status == MagickFalse)
1430 quantum_info=DestroyQuantumInfo(quantum_info);
1431 if (GetNextImageInList(image) == (Image *) NULL)
1433 image=SyncNextImageInList(image);
1434 status=SetImageProgress(image,SaveImagesTag,scene++,
1435 GetImageListLength(image));
1436 if (status == MagickFalse)
1438 } while (image_info->adjoin != MagickFalse);
1439 (void) CloseBlob(image);