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/constitute.h"
48 #include "MagickCore/exception.h"
49 #include "MagickCore/exception-private.h"
50 #include "MagickCore/image.h"
51 #include "MagickCore/image-private.h"
52 #include "MagickCore/list.h"
53 #include "MagickCore/magick.h"
54 #include "MagickCore/memory_.h"
55 #include "MagickCore/monitor.h"
56 #include "MagickCore/monitor-private.h"
57 #include "MagickCore/pixel-accessor.h"
58 #include "MagickCore/quantum-private.h"
59 #include "MagickCore/static.h"
60 #include "MagickCore/statistic.h"
61 #include "MagickCore/string_.h"
62 #include "MagickCore/module.h"
63 #include "MagickCore/utility.h"
68 static MagickBooleanType
69 WriteRGBImage(const ImageInfo *,Image *);
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 % R e a d R G B I m a g e %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
83 % it. It allocates the memory necessary for the new Image structure and
84 % returns a pointer to the new image.
86 % The format of the ReadRGBImage method is:
88 % Image *ReadRGBImage(const ImageInfo *image_info,
89 % ExceptionInfo *exception)
91 % A description of each parameter follows:
93 % o image_info: the image info.
95 % o exception: return any errors or warnings in this structure.
98 static Image *ReadRGBImage(const ImageInfo *image_info,
99 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);
141 if ((image->columns == 0) || (image->rows == 0))
142 ThrowReaderException(OptionError,"MustSpecifyImageSize");
143 image->colorspace=RGBColorspace;
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);
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;
172 if (LocaleCompare(image_info->magick,"RGBO") == 0)
174 quantum_type=RGBOQuantum;
175 image->matte=MagickTrue;
177 if (image_info->number_scenes != 0)
178 while (image->scene < image_info->scene)
184 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
185 for (y=0; y < (ssize_t) image->rows; y++)
187 count=ReadBlob(image,length,pixels);
188 if (count != (ssize_t) length)
198 Read pixels to virtual canvas image then push to image.
200 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
201 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
203 image->colorspace=RGBColorspace;
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 == (const 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) ||
250 (q == (const Quantum *) NULL))
252 for (x=0; x < (ssize_t) image->columns; x++)
254 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
255 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
256 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
257 SetPixelAlpha(image,OpaqueAlpha,q);
258 if (image->matte != MagickFalse)
259 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
260 p+=GetPixelChannels(canvas_image);
261 q+=GetPixelChannels(image);
263 if (SyncAuthenticPixels(image,exception) == MagickFalse)
266 if (image->previous == (Image *) NULL)
268 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
270 if (status == MagickFalse)
273 count=ReadBlob(image,length,pixels);
289 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
291 if (LocaleCompare(image_info->magick,"RGBO") == 0)
292 quantum_types[3]=OpacityQuantum;
295 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
296 count=ReadBlob(image,length,pixels);
298 for (y=0; y < (ssize_t) image->extract_info.height; y++)
300 register const Quantum
309 if (count != (ssize_t) length)
311 ThrowFileException(exception,CorruptImageError,
312 "UnexpectedEndOfFile",image->filename);
315 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
317 quantum_type=quantum_types[i];
318 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
320 if (q == (const Quantum *) NULL)
322 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
323 quantum_info,quantum_type,pixels,exception);
324 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
326 if (((y-image->extract_info.y) >= 0) &&
327 ((y-image->extract_info.y) < (ssize_t) image->rows))
329 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
330 0,canvas_image->columns,1,exception);
331 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
332 image->columns,1,exception);
333 if ((p == (const Quantum *) NULL) ||
334 (q == (const 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 == (const 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) ||
429 (q == (const Quantum *) NULL))
431 for (x=0; x < (ssize_t) image->columns; x++)
433 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
434 p+=GetPixelChannels(canvas_image);
435 q+=GetPixelChannels(image);
437 if (SyncAuthenticPixels(image,exception) == MagickFalse)
440 count=ReadBlob(image,length,pixels);
442 if (image->previous == (Image *) NULL)
444 status=SetImageProgress(image,LoadImageTag,1,6);
445 if (status == MagickFalse)
448 for (y=0; y < (ssize_t) image->extract_info.height; y++)
450 register const Quantum
459 if (count != (ssize_t) length)
461 ThrowFileException(exception,CorruptImageError,
462 "UnexpectedEndOfFile",image->filename);
465 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
467 if (q == (const Quantum *) NULL)
469 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
470 quantum_info,GreenQuantum,pixels,exception);
471 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
473 if (((y-image->extract_info.y) >= 0) &&
474 ((y-image->extract_info.y) < (ssize_t) image->rows))
476 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
477 canvas_image->columns,1,exception);
478 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
479 image->columns,1,exception);
480 if ((p == (const Quantum *) NULL) ||
481 (q == (const Quantum *) NULL))
483 for (x=0; x < (ssize_t) image->columns; x++)
486 GetPixelGreen(canvas_image,p),q);
487 p+=GetPixelChannels(canvas_image);
488 q+=GetPixelChannels(image);
490 if (SyncAuthenticPixels(image,exception) == MagickFalse)
493 count=ReadBlob(image,length,pixels);
495 if (image->previous == (Image *) NULL)
497 status=SetImageProgress(image,LoadImageTag,2,6);
498 if (status == MagickFalse)
501 for (y=0; y < (ssize_t) image->extract_info.height; y++)
503 register const Quantum
512 if (count != (ssize_t) length)
514 ThrowFileException(exception,CorruptImageError,
515 "UnexpectedEndOfFile",image->filename);
518 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
520 if (q == (const Quantum *) NULL)
522 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
523 quantum_info,BlueQuantum,pixels,exception);
524 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
526 if (((y-image->extract_info.y) >= 0) &&
527 ((y-image->extract_info.y) < (ssize_t) image->rows))
529 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
530 canvas_image->columns,1,exception);
531 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
532 image->columns,1,exception);
533 if ((p == (const Quantum *) NULL) ||
534 (q == (const Quantum *) NULL))
536 for (x=0; x < (ssize_t) image->columns; x++)
539 GetPixelBlue(canvas_image,p),q);
540 p+=GetPixelChannels(canvas_image);
541 q+=GetPixelChannels(image);
543 if (SyncAuthenticPixels(image,exception) == MagickFalse)
546 count=ReadBlob(image,length,pixels);
548 if (image->previous == (Image *) NULL)
550 status=SetImageProgress(image,LoadImageTag,3,6);
551 if (status == MagickFalse)
554 if (image->previous == (Image *) NULL)
556 status=SetImageProgress(image,LoadImageTag,4,6);
557 if (status == MagickFalse)
560 if (image->matte != MagickFalse)
562 for (y=0; y < (ssize_t) image->extract_info.height; y++)
564 register const Quantum
573 if (count != (ssize_t) length)
575 ThrowFileException(exception,CorruptImageError,
576 "UnexpectedEndOfFile",image->filename);
579 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
581 if (q == (const Quantum *) NULL)
583 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
584 quantum_info,AlphaQuantum,pixels,exception);
585 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
587 if (((y-image->extract_info.y) >= 0) &&
588 ((y-image->extract_info.y) < (ssize_t) image->rows))
590 p=GetVirtualPixels(canvas_image,
591 canvas_image->extract_info.x,0,canvas_image->columns,1,
593 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
594 image->columns,1,exception);
595 if ((p == (const Quantum *) NULL) ||
596 (q == (const Quantum *) NULL))
598 for (x=0; x < (ssize_t) image->columns; x++)
601 GetPixelAlpha(canvas_image,p),q);
602 p+=GetPixelChannels(canvas_image);
603 q+=GetPixelChannels(image);
605 if (SyncAuthenticPixels(image,exception) == MagickFalse)
608 count=ReadBlob(image,length,pixels);
610 if (image->previous == (Image *) NULL)
612 status=SetImageProgress(image,LoadImageTag,5,6);
613 if (status == MagickFalse)
617 if (image->previous == (Image *) NULL)
619 status=SetImageProgress(image,LoadImageTag,6,6);
620 if (status == MagickFalse)
625 case PartitionInterlace:
628 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
630 AppendImageFormat("R",image->filename);
631 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
632 if (status == MagickFalse)
634 canvas_image=DestroyImageList(canvas_image);
635 image=DestroyImageList(image);
636 return((Image *) NULL);
638 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
639 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
641 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
642 for (i=0; i < (ssize_t) scene; i++)
643 for (y=0; y < (ssize_t) image->extract_info.height; y++)
644 if (ReadBlob(image,length,pixels) != (ssize_t) length)
646 ThrowFileException(exception,CorruptImageError,
647 "UnexpectedEndOfFile",image->filename);
650 count=ReadBlob(image,length,pixels);
651 for (y=0; y < (ssize_t) image->extract_info.height; y++)
653 register const Quantum
662 if (count != (ssize_t) length)
664 ThrowFileException(exception,CorruptImageError,
665 "UnexpectedEndOfFile",image->filename);
668 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
670 if (q == (const Quantum *) NULL)
672 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
673 quantum_info,RedQuantum,pixels,exception);
674 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
676 if (((y-image->extract_info.y) >= 0) &&
677 ((y-image->extract_info.y) < (ssize_t) image->rows))
679 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
680 canvas_image->columns,1,exception);
681 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
682 image->columns,1,exception);
683 if ((p == (const Quantum *) NULL) ||
684 (q == (const Quantum *) NULL))
686 for (x=0; x < (ssize_t) image->columns; x++)
688 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
689 p+=GetPixelChannels(canvas_image);
690 q+=GetPixelChannels(image);
692 if (SyncAuthenticPixels(image,exception) == MagickFalse)
695 count=ReadBlob(image,length,pixels);
697 if (image->previous == (Image *) NULL)
699 status=SetImageProgress(image,LoadImageTag,1,5);
700 if (status == MagickFalse)
703 (void) CloseBlob(image);
704 AppendImageFormat("G",image->filename);
705 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
706 if (status == MagickFalse)
708 canvas_image=DestroyImageList(canvas_image);
709 image=DestroyImageList(image);
710 return((Image *) NULL);
712 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
713 for (i=0; i < (ssize_t) scene; i++)
714 for (y=0; y < (ssize_t) image->extract_info.height; y++)
715 if (ReadBlob(image,length,pixels) != (ssize_t) length)
717 ThrowFileException(exception,CorruptImageError,
718 "UnexpectedEndOfFile",image->filename);
721 count=ReadBlob(image,length,pixels);
722 for (y=0; y < (ssize_t) image->extract_info.height; y++)
724 register const Quantum
733 if (count != (ssize_t) length)
735 ThrowFileException(exception,CorruptImageError,
736 "UnexpectedEndOfFile",image->filename);
739 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
741 if (q == (const Quantum *) NULL)
743 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
744 quantum_info,GreenQuantum,pixels,exception);
745 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
747 if (((y-image->extract_info.y) >= 0) &&
748 ((y-image->extract_info.y) < (ssize_t) image->rows))
750 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
751 canvas_image->columns,1,exception);
752 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
753 image->columns,1,exception);
754 if ((p == (const Quantum *) NULL) ||
755 (q == (const Quantum *) NULL))
757 for (x=0; x < (ssize_t) image->columns; x++)
760 GetPixelGreen(canvas_image,p),q);
761 p+=GetPixelChannels(canvas_image);
762 q+=GetPixelChannels(image);
764 if (SyncAuthenticPixels(image,exception) == MagickFalse)
767 count=ReadBlob(image,length,pixels);
769 if (image->previous == (Image *) NULL)
771 status=SetImageProgress(image,LoadImageTag,2,5);
772 if (status == MagickFalse)
775 (void) CloseBlob(image);
776 AppendImageFormat("B",image->filename);
777 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
778 if (status == MagickFalse)
780 canvas_image=DestroyImageList(canvas_image);
781 image=DestroyImageList(image);
782 return((Image *) NULL);
784 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
785 for (i=0; i < (ssize_t) scene; i++)
786 for (y=0; y < (ssize_t) image->extract_info.height; y++)
787 if (ReadBlob(image,length,pixels) != (ssize_t) length)
789 ThrowFileException(exception,CorruptImageError,
790 "UnexpectedEndOfFile",image->filename);
793 count=ReadBlob(image,length,pixels);
794 for (y=0; y < (ssize_t) image->extract_info.height; y++)
796 register const Quantum
805 if (count != (ssize_t) length)
807 ThrowFileException(exception,CorruptImageError,
808 "UnexpectedEndOfFile",image->filename);
811 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
813 if (q == (const Quantum *) NULL)
815 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
816 quantum_info,BlueQuantum,pixels,exception);
817 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
819 if (((y-image->extract_info.y) >= 0) &&
820 ((y-image->extract_info.y) < (ssize_t) image->rows))
822 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
823 canvas_image->columns,1,exception);
824 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
825 image->columns,1,exception);
826 if ((p == (const Quantum *) NULL) ||
827 (q == (const Quantum *) NULL))
829 for (x=0; x < (ssize_t) image->columns; x++)
832 GetPixelBlue(canvas_image,p),q);
833 p+=GetPixelChannels(canvas_image);
834 q+=GetPixelChannels(image);
836 if (SyncAuthenticPixels(image,exception) == MagickFalse)
839 count=ReadBlob(image,length,pixels);
841 if (image->previous == (Image *) NULL)
843 status=SetImageProgress(image,LoadImageTag,3,5);
844 if (status == MagickFalse)
847 if (image->matte != MagickFalse)
849 (void) CloseBlob(image);
850 AppendImageFormat("A",image->filename);
851 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
852 if (status == MagickFalse)
854 canvas_image=DestroyImageList(canvas_image);
855 image=DestroyImageList(image);
856 return((Image *) NULL);
858 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
859 for (i=0; i < (ssize_t) scene; i++)
860 for (y=0; y < (ssize_t) image->extract_info.height; y++)
861 if (ReadBlob(image,length,pixels) != (ssize_t) length)
863 ThrowFileException(exception,CorruptImageError,
864 "UnexpectedEndOfFile",image->filename);
867 count=ReadBlob(image,length,pixels);
868 for (y=0; y < (ssize_t) image->extract_info.height; y++)
870 register const Quantum
879 if (count != (ssize_t) length)
881 ThrowFileException(exception,CorruptImageError,
882 "UnexpectedEndOfFile",image->filename);
885 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
887 if (q == (const Quantum *) NULL)
889 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
890 quantum_info,BlueQuantum,pixels,exception);
891 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
893 if (((y-image->extract_info.y) >= 0) &&
894 ((y-image->extract_info.y) < (ssize_t) image->rows))
896 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
897 0,canvas_image->columns,1,exception);
898 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
899 image->columns,1,exception);
900 if ((p == (const Quantum *) NULL) ||
901 (q == (const Quantum *) NULL))
903 for (x=0; x < (ssize_t) image->columns; x++)
906 GetPixelAlpha(canvas_image,p),q);
907 p+=GetPixelChannels(canvas_image);
908 q+=GetPixelChannels(image);
910 if (SyncAuthenticPixels(image,exception) == MagickFalse)
913 count=ReadBlob(image,length,pixels);
915 if (image->previous == (Image *) NULL)
917 status=SetImageProgress(image,LoadImageTag,4,5);
918 if (status == MagickFalse)
922 (void) CloseBlob(image);
923 if (image->previous == (Image *) NULL)
925 status=SetImageProgress(image,LoadImageTag,5,5);
926 if (status == MagickFalse)
932 SetQuantumImageType(image,quantum_type);
934 Proceed to next image.
936 if (image_info->number_scenes != 0)
937 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
939 if (count == (ssize_t) length)
942 Allocate next image structure.
944 AcquireNextImage(image_info,image);
945 if (GetNextImageInList(image) == (Image *) NULL)
947 image=DestroyImageList(image);
948 return((Image *) NULL);
950 image=SyncNextImageInList(image);
951 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
953 if (status == MagickFalse)
957 } while (count == (ssize_t) length);
958 quantum_info=DestroyQuantumInfo(quantum_info);
959 InheritException(&image->exception,&canvas_image->exception);
960 canvas_image=DestroyImage(canvas_image);
961 (void) CloseBlob(image);
962 return(GetFirstImageInList(image));
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970 % R e g i s t e r R G B I m a g e %
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976 % RegisterRGBImage() adds attributes for the RGB image format to
977 % the list of supported formats. The attributes include the image format
978 % tag, a method to read and/or write the format, whether the format
979 % supports the saving of more than one frame to the same file or blob,
980 % whether the format supports native in-memory I/O, and a brief
981 % description of the format.
983 % The format of the RegisterRGBImage method is:
985 % size_t RegisterRGBImage(void)
988 ModuleExport size_t RegisterRGBImage(void)
993 entry=SetMagickInfo("RGB");
994 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
995 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
996 entry->raw=MagickTrue;
997 entry->endian_support=MagickTrue;
998 entry->description=ConstantString("Raw red, green, and blue samples");
999 entry->module=ConstantString("RGB");
1000 (void) RegisterMagickInfo(entry);
1001 entry=SetMagickInfo("RGBA");
1002 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1003 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1004 entry->raw=MagickTrue;
1005 entry->endian_support=MagickTrue;
1006 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1007 entry->module=ConstantString("RGB");
1008 (void) RegisterMagickInfo(entry);
1009 entry=SetMagickInfo("RGBO");
1010 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1011 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1012 entry->raw=MagickTrue;
1013 entry->endian_support=MagickTrue;
1014 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1015 entry->module=ConstantString("RGB");
1016 (void) RegisterMagickInfo(entry);
1017 return(MagickImageCoderSignature);
1021 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 % U n r e g i s t e r R G B I m a g e %
1029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 % UnregisterRGBImage() removes format registrations made by the RGB module
1032 % from the list of supported formats.
1034 % The format of the UnregisterRGBImage method is:
1036 % UnregisterRGBImage(void)
1039 ModuleExport void UnregisterRGBImage(void)
1041 (void) UnregisterMagickInfo("RGBO");
1042 (void) UnregisterMagickInfo("RGBA");
1043 (void) UnregisterMagickInfo("RGB");
1047 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 % W r i t e R G B I m a g e %
1055 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1058 % rasterfile format.
1060 % The format of the WriteRGBImage method is:
1062 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1065 % A description of each parameter follows.
1067 % o image_info: the image info.
1069 % o image: The image.
1072 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1098 Allocate memory for pixels.
1100 assert(image_info != (const ImageInfo *) NULL);
1101 assert(image_info->signature == MagickSignature);
1102 assert(image != (Image *) NULL);
1103 assert(image->signature == MagickSignature);
1104 if (image->debug != MagickFalse)
1105 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1106 if (image_info->interlace != PartitionInterlace)
1109 Open output image file.
1111 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1112 if (status == MagickFalse)
1115 quantum_type=RGBQuantum;
1116 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1118 quantum_type=RGBAQuantum;
1119 image->matte=MagickTrue;
1121 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1123 quantum_type=RGBOQuantum;
1124 image->matte=MagickTrue;
1130 Convert MIFF to RGB raster pixels.
1132 if (image->colorspace != RGBColorspace)
1133 (void) TransformImageColorspace(image,RGBColorspace);
1134 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1135 (image->matte == MagickFalse))
1136 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
1137 quantum_info=AcquireQuantumInfo(image_info,image);
1138 if (quantum_info == (QuantumInfo *) NULL)
1139 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1140 pixels=GetQuantumPixels(quantum_info);
1141 switch (image_info->interlace)
1147 No interlacing: RGBRGBRGBRGBRGBRGB...
1149 for (y=0; y < (ssize_t) image->rows; y++)
1151 register const Quantum
1154 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1155 if (p == (const Quantum *) NULL)
1157 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1158 quantum_type,pixels,&image->exception);
1159 count=WriteBlob(image,length,pixels);
1160 if (count != (ssize_t) length)
1162 if (image->previous == (Image *) NULL)
1164 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1166 if (status == MagickFalse)
1175 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1177 for (y=0; y < (ssize_t) image->rows; y++)
1179 register const Quantum
1182 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1183 if (p == (const Quantum *) NULL)
1185 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1186 RedQuantum,pixels,&image->exception);
1187 count=WriteBlob(image,length,pixels);
1188 if (count != (ssize_t) length)
1190 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1191 GreenQuantum,pixels,&image->exception);
1192 count=WriteBlob(image,length,pixels);
1193 if (count != (ssize_t) length)
1195 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1196 BlueQuantum,pixels,&image->exception);
1197 count=WriteBlob(image,length,pixels);
1198 if (count != (ssize_t) length)
1200 if (quantum_type == RGBAQuantum)
1202 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1203 AlphaQuantum,pixels,&image->exception);
1204 count=WriteBlob(image,length,pixels);
1205 if (count != (ssize_t) length)
1208 if (quantum_type == RGBOQuantum)
1210 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1211 OpacityQuantum,pixels,&image->exception);
1212 count=WriteBlob(image,length,pixels);
1213 if (count != (ssize_t) length)
1216 if (image->previous == (Image *) NULL)
1218 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1220 if (status == MagickFalse)
1226 case PlaneInterlace:
1229 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1231 for (y=0; y < (ssize_t) image->rows; y++)
1233 register const Quantum
1236 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1237 if (p == (const Quantum *) NULL)
1239 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1240 RedQuantum,pixels,&image->exception);
1241 count=WriteBlob(image,length,pixels);
1242 if (count != (ssize_t) length)
1245 if (image->previous == (Image *) NULL)
1247 status=SetImageProgress(image,SaveImageTag,1,6);
1248 if (status == MagickFalse)
1251 for (y=0; y < (ssize_t) image->rows; y++)
1253 register const Quantum
1256 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1257 if (p == (const Quantum *) NULL)
1259 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1260 GreenQuantum,pixels,&image->exception);
1261 count=WriteBlob(image,length,pixels);
1262 if (count != (ssize_t) length)
1265 if (image->previous == (Image *) NULL)
1267 status=SetImageProgress(image,SaveImageTag,2,6);
1268 if (status == MagickFalse)
1271 for (y=0; y < (ssize_t) image->rows; y++)
1273 register const Quantum
1276 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1277 if (p == (const Quantum *) NULL)
1279 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1280 BlueQuantum,pixels,&image->exception);
1281 count=WriteBlob(image,length,pixels);
1282 if (count != (ssize_t) length)
1285 if (image->previous == (Image *) NULL)
1287 status=SetImageProgress(image,SaveImageTag,3,6);
1288 if (status == MagickFalse)
1291 if (quantum_type == RGBAQuantum)
1293 for (y=0; y < (ssize_t) image->rows; y++)
1295 register const Quantum
1298 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1299 if (p == (const Quantum *) NULL)
1301 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1302 AlphaQuantum,pixels,&image->exception);
1303 count=WriteBlob(image,length,pixels);
1304 if (count != (ssize_t) length)
1307 if (image->previous == (Image *) NULL)
1309 status=SetImageProgress(image,SaveImageTag,5,6);
1310 if (status == MagickFalse)
1314 if (image_info->interlace == PartitionInterlace)
1315 (void) CopyMagickString(image->filename,image_info->filename,
1317 if (image->previous == (Image *) NULL)
1319 status=SetImageProgress(image,SaveImageTag,6,6);
1320 if (status == MagickFalse)
1325 case PartitionInterlace:
1328 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1330 AppendImageFormat("R",image->filename);
1331 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1332 AppendBinaryBlobMode,&image->exception);
1333 if (status == MagickFalse)
1335 for (y=0; y < (ssize_t) image->rows; y++)
1337 register const Quantum
1340 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1341 if (p == (const Quantum *) NULL)
1343 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1344 RedQuantum,pixels,&image->exception);
1345 count=WriteBlob(image,length,pixels);
1346 if (count != (ssize_t) length)
1349 if (image->previous == (Image *) NULL)
1351 status=SetImageProgress(image,SaveImageTag,1,6);
1352 if (status == MagickFalse)
1355 (void) CloseBlob(image);
1356 AppendImageFormat("G",image->filename);
1357 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1358 AppendBinaryBlobMode,&image->exception);
1359 if (status == MagickFalse)
1361 for (y=0; y < (ssize_t) image->rows; y++)
1363 register const Quantum
1366 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1367 if (p == (const Quantum *) NULL)
1369 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1370 GreenQuantum,pixels,&image->exception);
1371 count=WriteBlob(image,length,pixels);
1372 if (count != (ssize_t) length)
1375 if (image->previous == (Image *) NULL)
1377 status=SetImageProgress(image,SaveImageTag,2,6);
1378 if (status == MagickFalse)
1381 (void) CloseBlob(image);
1382 AppendImageFormat("B",image->filename);
1383 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1384 AppendBinaryBlobMode,&image->exception);
1385 if (status == MagickFalse)
1387 for (y=0; y < (ssize_t) image->rows; y++)
1389 register const Quantum
1392 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1393 if (p == (const Quantum *) NULL)
1395 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1396 BlueQuantum,pixels,&image->exception);
1397 count=WriteBlob(image,length,pixels);
1398 if (count != (ssize_t) length)
1401 if (image->previous == (Image *) NULL)
1403 status=SetImageProgress(image,SaveImageTag,3,6);
1404 if (status == MagickFalse)
1407 (void) CloseBlob(image);
1408 if (quantum_type == RGBAQuantum)
1410 (void) CloseBlob(image);
1411 AppendImageFormat("A",image->filename);
1412 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1413 AppendBinaryBlobMode,&image->exception);
1414 if (status == MagickFalse)
1416 for (y=0; y < (ssize_t) image->rows; y++)
1418 register const Quantum
1421 p=GetVirtualPixels(image,0,y,image->columns,1,
1423 if (p == (const Quantum *) NULL)
1425 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1426 AlphaQuantum,pixels,&image->exception);
1427 count=WriteBlob(image,length,pixels);
1428 if (count != (ssize_t) length)
1431 if (image->previous == (Image *) NULL)
1433 status=SetImageProgress(image,SaveImageTag,5,6);
1434 if (status == MagickFalse)
1438 (void) CloseBlob(image);
1439 (void) CopyMagickString(image->filename,image_info->filename,
1441 if (image->previous == (Image *) NULL)
1443 status=SetImageProgress(image,SaveImageTag,6,6);
1444 if (status == MagickFalse)
1450 quantum_info=DestroyQuantumInfo(quantum_info);
1451 if (GetNextImageInList(image) == (Image *) NULL)
1453 image=SyncNextImageInList(image);
1454 status=SetImageProgress(image,SaveImagesTag,scene++,
1455 GetImageListLength(image));
1456 if (status == MagickFalse)
1458 } while (image_info->adjoin != MagickFalse);
1459 (void) CloseBlob(image);