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,
100 ExceptionInfo *exception)
134 assert(image_info != (const ImageInfo *) NULL);
135 assert(image_info->signature == MagickSignature);
136 if (image_info->debug != MagickFalse)
137 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
138 image_info->filename);
139 assert(exception != (ExceptionInfo *) NULL);
140 assert(exception->signature == MagickSignature);
141 image=AcquireImage(image_info,exception);
142 if ((image->columns == 0) || (image->rows == 0))
143 ThrowReaderException(OptionError,"MustSpecifyImageSize");
144 image->colorspace=RGBColorspace;
145 if (image_info->interlace != PartitionInterlace)
147 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
148 if (status == MagickFalse)
150 image=DestroyImageList(image);
151 return((Image *) NULL);
153 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
154 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
158 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
160 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
162 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
164 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
165 if (quantum_info == (QuantumInfo *) NULL)
166 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
167 pixels=GetQuantumPixels(quantum_info);
168 quantum_type=RGBQuantum;
169 if (LocaleCompare(image_info->magick,"RGBA") == 0)
171 quantum_type=RGBAQuantum;
172 image->matte=MagickTrue;
174 if (LocaleCompare(image_info->magick,"RGBO") == 0)
176 quantum_type=RGBOQuantum;
177 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 image->colorspace=RGBColorspace;
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) ||
252 (q == (Quantum *) NULL))
254 for (x=0; x < (ssize_t) image->columns; x++)
256 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
257 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
258 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
259 SetPixelAlpha(image,OpaqueAlpha,q);
260 if (image->matte != MagickFalse)
261 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
262 p+=GetPixelChannels(canvas_image);
263 q+=GetPixelChannels(image);
265 if (SyncAuthenticPixels(image,exception) == MagickFalse)
268 if (image->previous == (Image *) NULL)
270 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
272 if (status == MagickFalse)
275 count=ReadBlob(image,length,pixels);
291 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
293 if (LocaleCompare(image_info->magick,"RGBO") == 0)
294 quantum_types[3]=OpacityQuantum;
297 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
298 count=ReadBlob(image,length,pixels);
300 for (y=0; y < (ssize_t) image->extract_info.height; y++)
302 register const Quantum
311 if (count != (ssize_t) length)
313 ThrowFileException(exception,CorruptImageError,
314 "UnexpectedEndOfFile",image->filename);
317 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
319 quantum_type=quantum_types[i];
320 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
322 if (q == (Quantum *) NULL)
324 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
325 quantum_info,quantum_type,pixels,exception);
326 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
328 if (((y-image->extract_info.y) >= 0) &&
329 ((y-image->extract_info.y) < (ssize_t) image->rows))
331 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
332 0,canvas_image->columns,1,exception);
333 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
334 image->columns,1,exception);
335 if ((p == (const Quantum *) NULL) ||
336 (q == (Quantum *) NULL))
338 for (x=0; x < (ssize_t) image->columns; x++)
340 switch (quantum_type)
344 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
349 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
354 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
359 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
364 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
370 p+=GetPixelChannels(canvas_image);
371 q+=GetPixelChannels(image);
373 if (SyncAuthenticPixels(image,exception) == MagickFalse)
376 count=ReadBlob(image,length,pixels);
378 if (image->previous == (Image *) NULL)
380 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
382 if (status == MagickFalse)
391 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
395 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
396 count=ReadBlob(image,length,pixels);
398 for (y=0; y < (ssize_t) image->extract_info.height; y++)
400 register const Quantum
409 if (count != (ssize_t) length)
411 ThrowFileException(exception,CorruptImageError,
412 "UnexpectedEndOfFile",image->filename);
415 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
417 if (q == (Quantum *) NULL)
419 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
420 quantum_info,RedQuantum,pixels,exception);
421 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
423 if (((y-image->extract_info.y) >= 0) &&
424 ((y-image->extract_info.y) < (ssize_t) image->rows))
426 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
427 canvas_image->columns,1,exception);
428 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
429 image->columns,1,exception);
430 if ((p == (const Quantum *) NULL) ||
431 (q == (Quantum *) NULL))
433 for (x=0; x < (ssize_t) image->columns; x++)
435 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
436 p+=GetPixelChannels(canvas_image);
437 q+=GetPixelChannels(image);
439 if (SyncAuthenticPixels(image,exception) == MagickFalse)
442 count=ReadBlob(image,length,pixels);
444 if (image->previous == (Image *) NULL)
446 status=SetImageProgress(image,LoadImageTag,1,6);
447 if (status == MagickFalse)
450 for (y=0; y < (ssize_t) image->extract_info.height; y++)
452 register const Quantum
461 if (count != (ssize_t) length)
463 ThrowFileException(exception,CorruptImageError,
464 "UnexpectedEndOfFile",image->filename);
467 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
469 if (q == (Quantum *) NULL)
471 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
472 quantum_info,GreenQuantum,pixels,exception);
473 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
475 if (((y-image->extract_info.y) >= 0) &&
476 ((y-image->extract_info.y) < (ssize_t) image->rows))
478 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
479 canvas_image->columns,1,exception);
480 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
481 image->columns,1,exception);
482 if ((p == (const Quantum *) NULL) ||
483 (q == (Quantum *) NULL))
485 for (x=0; x < (ssize_t) image->columns; x++)
487 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
488 p+=GetPixelChannels(canvas_image);
489 q+=GetPixelChannels(image);
491 if (SyncAuthenticPixels(image,exception) == MagickFalse)
494 count=ReadBlob(image,length,pixels);
496 if (image->previous == (Image *) NULL)
498 status=SetImageProgress(image,LoadImageTag,2,6);
499 if (status == MagickFalse)
502 for (y=0; y < (ssize_t) image->extract_info.height; y++)
504 register const Quantum
513 if (count != (ssize_t) length)
515 ThrowFileException(exception,CorruptImageError,
516 "UnexpectedEndOfFile",image->filename);
519 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
521 if (q == (Quantum *) NULL)
523 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
524 quantum_info,BlueQuantum,pixels,exception);
525 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
527 if (((y-image->extract_info.y) >= 0) &&
528 ((y-image->extract_info.y) < (ssize_t) image->rows))
530 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
531 canvas_image->columns,1,exception);
532 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
533 image->columns,1,exception);
534 if ((p == (const Quantum *) NULL) ||
535 (q == (Quantum *) NULL))
537 for (x=0; x < (ssize_t) image->columns; x++)
539 SetPixelBlue(image,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 == (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 == (Quantum *) NULL))
598 for (x=0; x < (ssize_t) image->columns; x++)
600 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
601 p+=GetPixelChannels(canvas_image);
602 q+=GetPixelChannels(image);
604 if (SyncAuthenticPixels(image,exception) == MagickFalse)
607 count=ReadBlob(image,length,pixels);
609 if (image->previous == (Image *) NULL)
611 status=SetImageProgress(image,LoadImageTag,5,6);
612 if (status == MagickFalse)
616 if (image->previous == (Image *) NULL)
618 status=SetImageProgress(image,LoadImageTag,6,6);
619 if (status == MagickFalse)
624 case PartitionInterlace:
627 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
629 AppendImageFormat("R",image->filename);
630 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
631 if (status == MagickFalse)
633 canvas_image=DestroyImageList(canvas_image);
634 image=DestroyImageList(image);
635 return((Image *) NULL);
637 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
638 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
640 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
641 for (i=0; i < (ssize_t) scene; i++)
642 for (y=0; y < (ssize_t) image->extract_info.height; y++)
643 if (ReadBlob(image,length,pixels) != (ssize_t) length)
645 ThrowFileException(exception,CorruptImageError,
646 "UnexpectedEndOfFile",image->filename);
649 count=ReadBlob(image,length,pixels);
650 for (y=0; y < (ssize_t) image->extract_info.height; y++)
652 register const Quantum
661 if (count != (ssize_t) length)
663 ThrowFileException(exception,CorruptImageError,
664 "UnexpectedEndOfFile",image->filename);
667 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
669 if (q == (Quantum *) NULL)
671 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
672 quantum_info,RedQuantum,pixels,exception);
673 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
675 if (((y-image->extract_info.y) >= 0) &&
676 ((y-image->extract_info.y) < (ssize_t) image->rows))
678 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
679 canvas_image->columns,1,exception);
680 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
681 image->columns,1,exception);
682 if ((p == (const Quantum *) NULL) ||
683 (q == (Quantum *) NULL))
685 for (x=0; x < (ssize_t) image->columns; x++)
687 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
688 p+=GetPixelChannels(canvas_image);
689 q+=GetPixelChannels(image);
691 if (SyncAuthenticPixels(image,exception) == MagickFalse)
694 count=ReadBlob(image,length,pixels);
696 if (image->previous == (Image *) NULL)
698 status=SetImageProgress(image,LoadImageTag,1,5);
699 if (status == MagickFalse)
702 (void) CloseBlob(image);
703 AppendImageFormat("G",image->filename);
704 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
705 if (status == MagickFalse)
707 canvas_image=DestroyImageList(canvas_image);
708 image=DestroyImageList(image);
709 return((Image *) NULL);
711 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
712 for (i=0; i < (ssize_t) scene; i++)
713 for (y=0; y < (ssize_t) image->extract_info.height; y++)
714 if (ReadBlob(image,length,pixels) != (ssize_t) length)
716 ThrowFileException(exception,CorruptImageError,
717 "UnexpectedEndOfFile",image->filename);
720 count=ReadBlob(image,length,pixels);
721 for (y=0; y < (ssize_t) image->extract_info.height; y++)
723 register const Quantum
732 if (count != (ssize_t) length)
734 ThrowFileException(exception,CorruptImageError,
735 "UnexpectedEndOfFile",image->filename);
738 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
740 if (q == (Quantum *) NULL)
742 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
743 quantum_info,GreenQuantum,pixels,exception);
744 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
746 if (((y-image->extract_info.y) >= 0) &&
747 ((y-image->extract_info.y) < (ssize_t) image->rows))
749 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
750 canvas_image->columns,1,exception);
751 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
752 image->columns,1,exception);
753 if ((p == (const Quantum *) NULL) ||
754 (q == (Quantum *) NULL))
756 for (x=0; x < (ssize_t) image->columns; x++)
758 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
759 p+=GetPixelChannels(canvas_image);
760 q+=GetPixelChannels(image);
762 if (SyncAuthenticPixels(image,exception) == MagickFalse)
765 count=ReadBlob(image,length,pixels);
767 if (image->previous == (Image *) NULL)
769 status=SetImageProgress(image,LoadImageTag,2,5);
770 if (status == MagickFalse)
773 (void) CloseBlob(image);
774 AppendImageFormat("B",image->filename);
775 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
776 if (status == MagickFalse)
778 canvas_image=DestroyImageList(canvas_image);
779 image=DestroyImageList(image);
780 return((Image *) NULL);
782 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
783 for (i=0; i < (ssize_t) scene; i++)
784 for (y=0; y < (ssize_t) image->extract_info.height; y++)
785 if (ReadBlob(image,length,pixels) != (ssize_t) length)
787 ThrowFileException(exception,CorruptImageError,
788 "UnexpectedEndOfFile",image->filename);
791 count=ReadBlob(image,length,pixels);
792 for (y=0; y < (ssize_t) image->extract_info.height; y++)
794 register const Quantum
803 if (count != (ssize_t) length)
805 ThrowFileException(exception,CorruptImageError,
806 "UnexpectedEndOfFile",image->filename);
809 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
811 if (q == (Quantum *) NULL)
813 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
814 quantum_info,BlueQuantum,pixels,exception);
815 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
817 if (((y-image->extract_info.y) >= 0) &&
818 ((y-image->extract_info.y) < (ssize_t) image->rows))
820 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
821 canvas_image->columns,1,exception);
822 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
823 image->columns,1,exception);
824 if ((p == (const Quantum *) NULL) ||
825 (q == (Quantum *) NULL))
827 for (x=0; x < (ssize_t) image->columns; x++)
829 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
830 p+=GetPixelChannels(canvas_image);
831 q+=GetPixelChannels(image);
833 if (SyncAuthenticPixels(image,exception) == MagickFalse)
836 count=ReadBlob(image,length,pixels);
838 if (image->previous == (Image *) NULL)
840 status=SetImageProgress(image,LoadImageTag,3,5);
841 if (status == MagickFalse)
844 if (image->matte != MagickFalse)
846 (void) CloseBlob(image);
847 AppendImageFormat("A",image->filename);
848 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
849 if (status == MagickFalse)
851 canvas_image=DestroyImageList(canvas_image);
852 image=DestroyImageList(image);
853 return((Image *) NULL);
855 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
856 for (i=0; i < (ssize_t) scene; i++)
857 for (y=0; y < (ssize_t) image->extract_info.height; y++)
858 if (ReadBlob(image,length,pixels) != (ssize_t) length)
860 ThrowFileException(exception,CorruptImageError,
861 "UnexpectedEndOfFile",image->filename);
864 count=ReadBlob(image,length,pixels);
865 for (y=0; y < (ssize_t) image->extract_info.height; y++)
867 register const Quantum
876 if (count != (ssize_t) length)
878 ThrowFileException(exception,CorruptImageError,
879 "UnexpectedEndOfFile",image->filename);
882 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
884 if (q == (Quantum *) NULL)
886 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
887 quantum_info,BlueQuantum,pixels,exception);
888 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
890 if (((y-image->extract_info.y) >= 0) &&
891 ((y-image->extract_info.y) < (ssize_t) image->rows))
893 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
894 0,canvas_image->columns,1,exception);
895 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
896 image->columns,1,exception);
897 if ((p == (const Quantum *) NULL) ||
898 (q == (Quantum *) NULL))
900 for (x=0; x < (ssize_t) image->columns; x++)
902 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
903 p+=GetPixelChannels(canvas_image);
904 q+=GetPixelChannels(image);
906 if (SyncAuthenticPixels(image,exception) == MagickFalse)
909 count=ReadBlob(image,length,pixels);
911 if (image->previous == (Image *) NULL)
913 status=SetImageProgress(image,LoadImageTag,4,5);
914 if (status == MagickFalse)
918 (void) CloseBlob(image);
919 if (image->previous == (Image *) NULL)
921 status=SetImageProgress(image,LoadImageTag,5,5);
922 if (status == MagickFalse)
928 SetQuantumImageType(image,quantum_type);
930 Proceed to next image.
932 if (image_info->number_scenes != 0)
933 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
935 if (count == (ssize_t) length)
938 Allocate next image structure.
940 AcquireNextImage(image_info,image,exception);
941 if (GetNextImageInList(image) == (Image *) NULL)
943 image=DestroyImageList(image);
944 return((Image *) NULL);
946 image=SyncNextImageInList(image);
947 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
949 if (status == MagickFalse)
953 } while (count == (ssize_t) length);
954 quantum_info=DestroyQuantumInfo(quantum_info);
955 canvas_image=DestroyImage(canvas_image);
956 (void) CloseBlob(image);
957 return(GetFirstImageInList(image));
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 % R e g i s t e r R G B I m a g e %
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971 % RegisterRGBImage() adds attributes for the RGB image format to
972 % the list of supported formats. The attributes include the image format
973 % tag, a method to read and/or write the format, whether the format
974 % supports the saving of more than one frame to the same file or blob,
975 % whether the format supports native in-memory I/O, and a brief
976 % description of the format.
978 % The format of the RegisterRGBImage method is:
980 % size_t RegisterRGBImage(void)
983 ModuleExport size_t RegisterRGBImage(void)
988 entry=SetMagickInfo("RGB");
989 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
990 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
991 entry->raw=MagickTrue;
992 entry->endian_support=MagickTrue;
993 entry->description=ConstantString("Raw red, green, and blue samples");
994 entry->module=ConstantString("RGB");
995 (void) RegisterMagickInfo(entry);
996 entry=SetMagickInfo("RGBA");
997 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
998 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
999 entry->raw=MagickTrue;
1000 entry->endian_support=MagickTrue;
1001 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1002 entry->module=ConstantString("RGB");
1003 (void) RegisterMagickInfo(entry);
1004 entry=SetMagickInfo("RGBO");
1005 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1006 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1007 entry->raw=MagickTrue;
1008 entry->endian_support=MagickTrue;
1009 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1010 entry->module=ConstantString("RGB");
1011 (void) RegisterMagickInfo(entry);
1012 return(MagickImageCoderSignature);
1016 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1020 % U n r e g i s t e r R G B I m a g e %
1024 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026 % UnregisterRGBImage() removes format registrations made by the RGB module
1027 % from the list of supported formats.
1029 % The format of the UnregisterRGBImage method is:
1031 % UnregisterRGBImage(void)
1034 ModuleExport void UnregisterRGBImage(void)
1036 (void) UnregisterMagickInfo("RGBO");
1037 (void) UnregisterMagickInfo("RGBA");
1038 (void) UnregisterMagickInfo("RGB");
1042 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 % W r i t e R G B I m a g e %
1050 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1053 % rasterfile format.
1055 % The format of the WriteRGBImage method is:
1057 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1058 % Image *image,ExceptionInfo *exception)
1060 % A description of each parameter follows.
1062 % o image_info: the image info.
1064 % o image: The image.
1066 % o exception: return any errors or warnings in this structure.
1069 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1070 Image *image,ExceptionInfo *exception)
1095 Allocate memory for pixels.
1097 assert(image_info != (const ImageInfo *) NULL);
1098 assert(image_info->signature == MagickSignature);
1099 assert(image != (Image *) NULL);
1100 assert(image->signature == MagickSignature);
1101 if (image->debug != MagickFalse)
1102 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1103 if (image_info->interlace != PartitionInterlace)
1106 Open output image file.
1108 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1109 if (status == MagickFalse)
1112 quantum_type=RGBQuantum;
1113 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1115 quantum_type=RGBAQuantum;
1116 if (image->matte == MagickFalse)
1117 SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1119 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1121 quantum_type=RGBOQuantum;
1122 if (image->matte == MagickFalse)
1123 SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1129 Convert MIFF to RGB raster pixels.
1131 if (IssRGBColorspace(image->colorspace) == MagickFalse)
1132 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1133 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1134 (image->matte == MagickFalse))
1135 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1136 quantum_info=AcquireQuantumInfo(image_info,image);
1137 if (quantum_info == (QuantumInfo *) NULL)
1138 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1139 pixels=GetQuantumPixels(quantum_info);
1140 switch (image_info->interlace)
1146 No interlacing: RGBRGBRGBRGBRGBRGB...
1148 for (y=0; y < (ssize_t) image->rows; y++)
1150 register const Quantum
1153 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1154 if (p == (const Quantum *) NULL)
1156 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1157 quantum_type,pixels,exception);
1158 count=WriteBlob(image,length,pixels);
1159 if (count != (ssize_t) length)
1161 if (image->previous == (Image *) NULL)
1163 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1165 if (status == MagickFalse)
1174 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1176 for (y=0; y < (ssize_t) image->rows; y++)
1178 register const Quantum
1181 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1182 if (p == (const Quantum *) NULL)
1184 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1185 RedQuantum,pixels,exception);
1186 count=WriteBlob(image,length,pixels);
1187 if (count != (ssize_t) length)
1189 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1190 GreenQuantum,pixels,exception);
1191 count=WriteBlob(image,length,pixels);
1192 if (count != (ssize_t) length)
1194 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1195 BlueQuantum,pixels,exception);
1196 count=WriteBlob(image,length,pixels);
1197 if (count != (ssize_t) length)
1199 if (quantum_type == RGBAQuantum)
1201 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1202 AlphaQuantum,pixels,exception);
1203 count=WriteBlob(image,length,pixels);
1204 if (count != (ssize_t) length)
1207 if (quantum_type == RGBOQuantum)
1209 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1210 OpacityQuantum,pixels,exception);
1211 count=WriteBlob(image,length,pixels);
1212 if (count != (ssize_t) length)
1215 if (image->previous == (Image *) NULL)
1217 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1219 if (status == MagickFalse)
1225 case PlaneInterlace:
1228 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
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 RedQuantum,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,1,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 GreenQuantum,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,2,6);
1267 if (status == MagickFalse)
1270 for (y=0; y < (ssize_t) image->rows; y++)
1272 register const Quantum
1275 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1276 if (p == (const Quantum *) NULL)
1278 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1279 BlueQuantum,pixels,exception);
1280 count=WriteBlob(image,length,pixels);
1281 if (count != (ssize_t) length)
1284 if (image->previous == (Image *) NULL)
1286 status=SetImageProgress(image,SaveImageTag,3,6);
1287 if (status == MagickFalse)
1290 if (quantum_type == RGBAQuantum)
1292 for (y=0; y < (ssize_t) image->rows; y++)
1294 register const Quantum
1297 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1298 if (p == (const Quantum *) NULL)
1300 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1301 AlphaQuantum,pixels,exception);
1302 count=WriteBlob(image,length,pixels);
1303 if (count != (ssize_t) length)
1306 if (image->previous == (Image *) NULL)
1308 status=SetImageProgress(image,SaveImageTag,5,6);
1309 if (status == MagickFalse)
1313 if (image_info->interlace == PartitionInterlace)
1314 (void) CopyMagickString(image->filename,image_info->filename,
1316 if (image->previous == (Image *) NULL)
1318 status=SetImageProgress(image,SaveImageTag,6,6);
1319 if (status == MagickFalse)
1324 case PartitionInterlace:
1327 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1329 AppendImageFormat("R",image->filename);
1330 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1331 AppendBinaryBlobMode,exception);
1332 if (status == MagickFalse)
1334 for (y=0; y < (ssize_t) image->rows; y++)
1336 register const Quantum
1339 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1340 if (p == (const Quantum *) NULL)
1342 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1343 RedQuantum,pixels,exception);
1344 count=WriteBlob(image,length,pixels);
1345 if (count != (ssize_t) length)
1348 if (image->previous == (Image *) NULL)
1350 status=SetImageProgress(image,SaveImageTag,1,6);
1351 if (status == MagickFalse)
1354 (void) CloseBlob(image);
1355 AppendImageFormat("G",image->filename);
1356 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1357 AppendBinaryBlobMode,exception);
1358 if (status == MagickFalse)
1360 for (y=0; y < (ssize_t) image->rows; y++)
1362 register const Quantum
1365 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1366 if (p == (const Quantum *) NULL)
1368 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1369 GreenQuantum,pixels,exception);
1370 count=WriteBlob(image,length,pixels);
1371 if (count != (ssize_t) length)
1374 if (image->previous == (Image *) NULL)
1376 status=SetImageProgress(image,SaveImageTag,2,6);
1377 if (status == MagickFalse)
1380 (void) CloseBlob(image);
1381 AppendImageFormat("B",image->filename);
1382 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1383 AppendBinaryBlobMode,exception);
1384 if (status == MagickFalse)
1386 for (y=0; y < (ssize_t) image->rows; y++)
1388 register const Quantum
1391 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1392 if (p == (const Quantum *) NULL)
1394 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1395 BlueQuantum,pixels,exception);
1396 count=WriteBlob(image,length,pixels);
1397 if (count != (ssize_t) length)
1400 if (image->previous == (Image *) NULL)
1402 status=SetImageProgress(image,SaveImageTag,3,6);
1403 if (status == MagickFalse)
1406 (void) CloseBlob(image);
1407 if (quantum_type == RGBAQuantum)
1409 (void) CloseBlob(image);
1410 AppendImageFormat("A",image->filename);
1411 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1412 AppendBinaryBlobMode,exception);
1413 if (status == MagickFalse)
1415 for (y=0; y < (ssize_t) image->rows; y++)
1417 register const Quantum
1420 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1421 if (p == (const Quantum *) NULL)
1423 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1424 AlphaQuantum,pixels,exception);
1425 count=WriteBlob(image,length,pixels);
1426 if (count != (ssize_t) length)
1429 if (image->previous == (Image *) NULL)
1431 status=SetImageProgress(image,SaveImageTag,5,6);
1432 if (status == MagickFalse)
1436 (void) CloseBlob(image);
1437 (void) CopyMagickString(image->filename,image_info->filename,
1439 if (image->previous == (Image *) NULL)
1441 status=SetImageProgress(image,SaveImageTag,6,6);
1442 if (status == MagickFalse)
1448 quantum_info=DestroyQuantumInfo(quantum_info);
1449 if (GetNextImageInList(image) == (Image *) NULL)
1451 image=SyncNextImageInList(image);
1452 status=SetImageProgress(image,SaveImagesTag,scene++,
1453 GetImageListLength(image));
1454 if (status == MagickFalse)
1456 } while (image_info->adjoin != MagickFalse);
1457 (void) CloseBlob(image);