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);
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;
173 if (LocaleCompare(image_info->magick,"RGBO") == 0)
175 quantum_type=RGBOQuantum;
176 image->matte=MagickTrue;
178 if (image_info->number_scenes != 0)
179 while (image->scene < image_info->scene)
185 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
186 for (y=0; y < (ssize_t) image->rows; y++)
188 count=ReadBlob(image,length,pixels);
189 if (count != (ssize_t) length)
199 Read pixels to virtual canvas image then push to image.
201 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
202 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
204 image->colorspace=RGBColorspace;
205 switch (image_info->interlace)
211 No interlacing: RGBRGBRGBRGBRGBRGB...
215 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
216 count=ReadBlob(image,length,pixels);
218 for (y=0; y < (ssize_t) image->extract_info.height; y++)
220 register const Quantum
229 if (count != (ssize_t) length)
231 ThrowFileException(exception,CorruptImageError,
232 "UnexpectedEndOfFile",image->filename);
235 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
237 if (q == (Quantum *) NULL)
239 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
240 quantum_info,quantum_type,pixels,exception);
241 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
243 if (((y-image->extract_info.y) >= 0) &&
244 ((y-image->extract_info.y) < (ssize_t) image->rows))
246 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
247 canvas_image->columns,1,exception);
248 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
249 image->columns,1,exception);
250 if ((p == (const Quantum *) NULL) ||
251 (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) ||
335 (q == (Quantum *) NULL))
337 for (x=0; x < (ssize_t) image->columns; x++)
339 switch (quantum_type)
343 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
348 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
353 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
358 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
363 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
369 p+=GetPixelChannels(canvas_image);
370 q+=GetPixelChannels(image);
372 if (SyncAuthenticPixels(image,exception) == MagickFalse)
375 count=ReadBlob(image,length,pixels);
377 if (image->previous == (Image *) NULL)
379 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
381 if (status == MagickFalse)
390 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
394 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
395 count=ReadBlob(image,length,pixels);
397 for (y=0; y < (ssize_t) image->extract_info.height; y++)
399 register const Quantum
408 if (count != (ssize_t) length)
410 ThrowFileException(exception,CorruptImageError,
411 "UnexpectedEndOfFile",image->filename);
414 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
416 if (q == (Quantum *) NULL)
418 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
419 quantum_info,RedQuantum,pixels,exception);
420 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
422 if (((y-image->extract_info.y) >= 0) &&
423 ((y-image->extract_info.y) < (ssize_t) image->rows))
425 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
426 canvas_image->columns,1,exception);
427 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
428 image->columns,1,exception);
429 if ((p == (const Quantum *) NULL) ||
430 (q == (Quantum *) NULL))
432 for (x=0; x < (ssize_t) image->columns; x++)
434 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
435 p+=GetPixelChannels(canvas_image);
436 q+=GetPixelChannels(image);
438 if (SyncAuthenticPixels(image,exception) == MagickFalse)
441 count=ReadBlob(image,length,pixels);
443 if (image->previous == (Image *) NULL)
445 status=SetImageProgress(image,LoadImageTag,1,6);
446 if (status == MagickFalse)
449 for (y=0; y < (ssize_t) image->extract_info.height; y++)
451 register const Quantum
460 if (count != (ssize_t) length)
462 ThrowFileException(exception,CorruptImageError,
463 "UnexpectedEndOfFile",image->filename);
466 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
468 if (q == (Quantum *) NULL)
470 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
471 quantum_info,GreenQuantum,pixels,exception);
472 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
474 if (((y-image->extract_info.y) >= 0) &&
475 ((y-image->extract_info.y) < (ssize_t) image->rows))
477 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
478 canvas_image->columns,1,exception);
479 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
480 image->columns,1,exception);
481 if ((p == (const Quantum *) NULL) ||
482 (q == (Quantum *) NULL))
484 for (x=0; x < (ssize_t) image->columns; x++)
486 SetPixelGreen(image,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 == (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 == (Quantum *) NULL))
536 for (x=0; x < (ssize_t) image->columns; x++)
538 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
539 p+=GetPixelChannels(canvas_image);
540 q+=GetPixelChannels(image);
542 if (SyncAuthenticPixels(image,exception) == MagickFalse)
545 count=ReadBlob(image,length,pixels);
547 if (image->previous == (Image *) NULL)
549 status=SetImageProgress(image,LoadImageTag,3,6);
550 if (status == MagickFalse)
553 if (image->previous == (Image *) NULL)
555 status=SetImageProgress(image,LoadImageTag,4,6);
556 if (status == MagickFalse)
559 if (image->matte != MagickFalse)
561 for (y=0; y < (ssize_t) image->extract_info.height; y++)
563 register const Quantum
572 if (count != (ssize_t) length)
574 ThrowFileException(exception,CorruptImageError,
575 "UnexpectedEndOfFile",image->filename);
578 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
580 if (q == (Quantum *) NULL)
582 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
583 quantum_info,AlphaQuantum,pixels,exception);
584 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
586 if (((y-image->extract_info.y) >= 0) &&
587 ((y-image->extract_info.y) < (ssize_t) image->rows))
589 p=GetVirtualPixels(canvas_image,
590 canvas_image->extract_info.x,0,canvas_image->columns,1,
592 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
593 image->columns,1,exception);
594 if ((p == (const Quantum *) NULL) ||
595 (q == (Quantum *) NULL))
597 for (x=0; x < (ssize_t) image->columns; x++)
599 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
600 p+=GetPixelChannels(canvas_image);
601 q+=GetPixelChannels(image);
603 if (SyncAuthenticPixels(image,exception) == MagickFalse)
606 count=ReadBlob(image,length,pixels);
608 if (image->previous == (Image *) NULL)
610 status=SetImageProgress(image,LoadImageTag,5,6);
611 if (status == MagickFalse)
615 if (image->previous == (Image *) NULL)
617 status=SetImageProgress(image,LoadImageTag,6,6);
618 if (status == MagickFalse)
623 case PartitionInterlace:
626 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
628 AppendImageFormat("R",image->filename);
629 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
630 if (status == MagickFalse)
632 canvas_image=DestroyImageList(canvas_image);
633 image=DestroyImageList(image);
634 return((Image *) NULL);
636 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
637 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
639 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
640 for (i=0; i < (ssize_t) scene; i++)
641 for (y=0; y < (ssize_t) image->extract_info.height; y++)
642 if (ReadBlob(image,length,pixels) != (ssize_t) length)
644 ThrowFileException(exception,CorruptImageError,
645 "UnexpectedEndOfFile",image->filename);
648 count=ReadBlob(image,length,pixels);
649 for (y=0; y < (ssize_t) image->extract_info.height; y++)
651 register const Quantum
660 if (count != (ssize_t) length)
662 ThrowFileException(exception,CorruptImageError,
663 "UnexpectedEndOfFile",image->filename);
666 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
668 if (q == (Quantum *) NULL)
670 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
671 quantum_info,RedQuantum,pixels,exception);
672 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
674 if (((y-image->extract_info.y) >= 0) &&
675 ((y-image->extract_info.y) < (ssize_t) image->rows))
677 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
678 canvas_image->columns,1,exception);
679 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
680 image->columns,1,exception);
681 if ((p == (const Quantum *) NULL) ||
682 (q == (Quantum *) NULL))
684 for (x=0; x < (ssize_t) image->columns; x++)
686 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
687 p+=GetPixelChannels(canvas_image);
688 q+=GetPixelChannels(image);
690 if (SyncAuthenticPixels(image,exception) == MagickFalse)
693 count=ReadBlob(image,length,pixels);
695 if (image->previous == (Image *) NULL)
697 status=SetImageProgress(image,LoadImageTag,1,5);
698 if (status == MagickFalse)
701 (void) CloseBlob(image);
702 AppendImageFormat("G",image->filename);
703 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
704 if (status == MagickFalse)
706 canvas_image=DestroyImageList(canvas_image);
707 image=DestroyImageList(image);
708 return((Image *) NULL);
710 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
711 for (i=0; i < (ssize_t) scene; i++)
712 for (y=0; y < (ssize_t) image->extract_info.height; y++)
713 if (ReadBlob(image,length,pixels) != (ssize_t) length)
715 ThrowFileException(exception,CorruptImageError,
716 "UnexpectedEndOfFile",image->filename);
719 count=ReadBlob(image,length,pixels);
720 for (y=0; y < (ssize_t) image->extract_info.height; y++)
722 register const Quantum
731 if (count != (ssize_t) length)
733 ThrowFileException(exception,CorruptImageError,
734 "UnexpectedEndOfFile",image->filename);
737 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
739 if (q == (Quantum *) NULL)
741 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
742 quantum_info,GreenQuantum,pixels,exception);
743 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
745 if (((y-image->extract_info.y) >= 0) &&
746 ((y-image->extract_info.y) < (ssize_t) image->rows))
748 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
749 canvas_image->columns,1,exception);
750 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
751 image->columns,1,exception);
752 if ((p == (const Quantum *) NULL) ||
753 (q == (Quantum *) NULL))
755 for (x=0; x < (ssize_t) image->columns; x++)
757 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
758 p+=GetPixelChannels(canvas_image);
759 q+=GetPixelChannels(image);
761 if (SyncAuthenticPixels(image,exception) == MagickFalse)
764 count=ReadBlob(image,length,pixels);
766 if (image->previous == (Image *) NULL)
768 status=SetImageProgress(image,LoadImageTag,2,5);
769 if (status == MagickFalse)
772 (void) CloseBlob(image);
773 AppendImageFormat("B",image->filename);
774 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
775 if (status == MagickFalse)
777 canvas_image=DestroyImageList(canvas_image);
778 image=DestroyImageList(image);
779 return((Image *) NULL);
781 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
782 for (i=0; i < (ssize_t) scene; i++)
783 for (y=0; y < (ssize_t) image->extract_info.height; y++)
784 if (ReadBlob(image,length,pixels) != (ssize_t) length)
786 ThrowFileException(exception,CorruptImageError,
787 "UnexpectedEndOfFile",image->filename);
790 count=ReadBlob(image,length,pixels);
791 for (y=0; y < (ssize_t) image->extract_info.height; y++)
793 register const Quantum
802 if (count != (ssize_t) length)
804 ThrowFileException(exception,CorruptImageError,
805 "UnexpectedEndOfFile",image->filename);
808 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
810 if (q == (Quantum *) NULL)
812 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
813 quantum_info,BlueQuantum,pixels,exception);
814 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
816 if (((y-image->extract_info.y) >= 0) &&
817 ((y-image->extract_info.y) < (ssize_t) image->rows))
819 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
820 canvas_image->columns,1,exception);
821 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
822 image->columns,1,exception);
823 if ((p == (const Quantum *) NULL) ||
824 (q == (Quantum *) NULL))
826 for (x=0; x < (ssize_t) image->columns; x++)
828 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
829 p+=GetPixelChannels(canvas_image);
830 q+=GetPixelChannels(image);
832 if (SyncAuthenticPixels(image,exception) == MagickFalse)
835 count=ReadBlob(image,length,pixels);
837 if (image->previous == (Image *) NULL)
839 status=SetImageProgress(image,LoadImageTag,3,5);
840 if (status == MagickFalse)
843 if (image->matte != MagickFalse)
845 (void) CloseBlob(image);
846 AppendImageFormat("A",image->filename);
847 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
848 if (status == MagickFalse)
850 canvas_image=DestroyImageList(canvas_image);
851 image=DestroyImageList(image);
852 return((Image *) NULL);
854 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
855 for (i=0; i < (ssize_t) scene; i++)
856 for (y=0; y < (ssize_t) image->extract_info.height; y++)
857 if (ReadBlob(image,length,pixels) != (ssize_t) length)
859 ThrowFileException(exception,CorruptImageError,
860 "UnexpectedEndOfFile",image->filename);
863 count=ReadBlob(image,length,pixels);
864 for (y=0; y < (ssize_t) image->extract_info.height; y++)
866 register const Quantum
875 if (count != (ssize_t) length)
877 ThrowFileException(exception,CorruptImageError,
878 "UnexpectedEndOfFile",image->filename);
881 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
883 if (q == (Quantum *) NULL)
885 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
886 quantum_info,BlueQuantum,pixels,exception);
887 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
889 if (((y-image->extract_info.y) >= 0) &&
890 ((y-image->extract_info.y) < (ssize_t) image->rows))
892 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
893 0,canvas_image->columns,1,exception);
894 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
895 image->columns,1,exception);
896 if ((p == (const Quantum *) NULL) ||
897 (q == (Quantum *) NULL))
899 for (x=0; x < (ssize_t) image->columns; x++)
901 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
902 p+=GetPixelChannels(canvas_image);
903 q+=GetPixelChannels(image);
905 if (SyncAuthenticPixels(image,exception) == MagickFalse)
908 count=ReadBlob(image,length,pixels);
910 if (image->previous == (Image *) NULL)
912 status=SetImageProgress(image,LoadImageTag,4,5);
913 if (status == MagickFalse)
917 (void) CloseBlob(image);
918 if (image->previous == (Image *) NULL)
920 status=SetImageProgress(image,LoadImageTag,5,5);
921 if (status == MagickFalse)
927 SetQuantumImageType(image,quantum_type);
929 Proceed to next image.
931 if (image_info->number_scenes != 0)
932 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
934 if (count == (ssize_t) length)
937 Allocate next image structure.
939 AcquireNextImage(image_info,image,exception);
940 if (GetNextImageInList(image) == (Image *) NULL)
942 image=DestroyImageList(image);
943 return((Image *) NULL);
945 image=SyncNextImageInList(image);
946 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
948 if (status == MagickFalse)
952 } while (count == (ssize_t) length);
953 quantum_info=DestroyQuantumInfo(quantum_info);
954 InheritException(&image->exception,&canvas_image->exception);
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 image->matte=MagickTrue;
1118 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1120 quantum_type=RGBOQuantum;
1121 image->matte=MagickTrue;
1127 Convert MIFF to RGB raster pixels.
1129 if (IsRGBColorspace(image->colorspace) == MagickFalse)
1130 (void) TransformImageColorspace(image,RGBColorspace);
1131 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1132 (image->matte == MagickFalse))
1133 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1134 quantum_info=AcquireQuantumInfo(image_info,image);
1135 if (quantum_info == (QuantumInfo *) NULL)
1136 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1137 pixels=GetQuantumPixels(quantum_info);
1138 switch (image_info->interlace)
1144 No interlacing: RGBRGBRGBRGBRGBRGB...
1146 for (y=0; y < (ssize_t) image->rows; y++)
1148 register const Quantum
1151 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1152 if (p == (const Quantum *) NULL)
1154 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1155 quantum_type,pixels,exception);
1156 count=WriteBlob(image,length,pixels);
1157 if (count != (ssize_t) length)
1159 if (image->previous == (Image *) NULL)
1161 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1163 if (status == MagickFalse)
1172 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1174 for (y=0; y < (ssize_t) image->rows; y++)
1176 register const Quantum
1179 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1180 if (p == (const Quantum *) NULL)
1182 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1183 RedQuantum,pixels,exception);
1184 count=WriteBlob(image,length,pixels);
1185 if (count != (ssize_t) length)
1187 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1188 GreenQuantum,pixels,exception);
1189 count=WriteBlob(image,length,pixels);
1190 if (count != (ssize_t) length)
1192 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1193 BlueQuantum,pixels,exception);
1194 count=WriteBlob(image,length,pixels);
1195 if (count != (ssize_t) length)
1197 if (quantum_type == RGBAQuantum)
1199 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1200 AlphaQuantum,pixels,exception);
1201 count=WriteBlob(image,length,pixels);
1202 if (count != (ssize_t) length)
1205 if (quantum_type == RGBOQuantum)
1207 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1208 OpacityQuantum,pixels,exception);
1209 count=WriteBlob(image,length,pixels);
1210 if (count != (ssize_t) length)
1213 if (image->previous == (Image *) NULL)
1215 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1217 if (status == MagickFalse)
1223 case PlaneInterlace:
1226 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1228 for (y=0; y < (ssize_t) image->rows; y++)
1230 register const Quantum
1233 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1234 if (p == (const Quantum *) NULL)
1236 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1237 RedQuantum,pixels,exception);
1238 count=WriteBlob(image,length,pixels);
1239 if (count != (ssize_t) length)
1242 if (image->previous == (Image *) NULL)
1244 status=SetImageProgress(image,SaveImageTag,1,6);
1245 if (status == MagickFalse)
1248 for (y=0; y < (ssize_t) image->rows; y++)
1250 register const Quantum
1253 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1254 if (p == (const Quantum *) NULL)
1256 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1257 GreenQuantum,pixels,exception);
1258 count=WriteBlob(image,length,pixels);
1259 if (count != (ssize_t) length)
1262 if (image->previous == (Image *) NULL)
1264 status=SetImageProgress(image,SaveImageTag,2,6);
1265 if (status == MagickFalse)
1268 for (y=0; y < (ssize_t) image->rows; y++)
1270 register const Quantum
1273 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1274 if (p == (const Quantum *) NULL)
1276 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1277 BlueQuantum,pixels,exception);
1278 count=WriteBlob(image,length,pixels);
1279 if (count != (ssize_t) length)
1282 if (image->previous == (Image *) NULL)
1284 status=SetImageProgress(image,SaveImageTag,3,6);
1285 if (status == MagickFalse)
1288 if (quantum_type == RGBAQuantum)
1290 for (y=0; y < (ssize_t) image->rows; y++)
1292 register const Quantum
1295 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1296 if (p == (const Quantum *) NULL)
1298 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1299 AlphaQuantum,pixels,exception);
1300 count=WriteBlob(image,length,pixels);
1301 if (count != (ssize_t) length)
1304 if (image->previous == (Image *) NULL)
1306 status=SetImageProgress(image,SaveImageTag,5,6);
1307 if (status == MagickFalse)
1311 if (image_info->interlace == PartitionInterlace)
1312 (void) CopyMagickString(image->filename,image_info->filename,
1314 if (image->previous == (Image *) NULL)
1316 status=SetImageProgress(image,SaveImageTag,6,6);
1317 if (status == MagickFalse)
1322 case PartitionInterlace:
1325 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1327 AppendImageFormat("R",image->filename);
1328 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1329 AppendBinaryBlobMode,exception);
1330 if (status == MagickFalse)
1332 for (y=0; y < (ssize_t) image->rows; y++)
1334 register const Quantum
1337 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1338 if (p == (const Quantum *) NULL)
1340 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1341 RedQuantum,pixels,exception);
1342 count=WriteBlob(image,length,pixels);
1343 if (count != (ssize_t) length)
1346 if (image->previous == (Image *) NULL)
1348 status=SetImageProgress(image,SaveImageTag,1,6);
1349 if (status == MagickFalse)
1352 (void) CloseBlob(image);
1353 AppendImageFormat("G",image->filename);
1354 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1355 AppendBinaryBlobMode,exception);
1356 if (status == MagickFalse)
1358 for (y=0; y < (ssize_t) image->rows; y++)
1360 register const Quantum
1363 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1364 if (p == (const Quantum *) NULL)
1366 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1367 GreenQuantum,pixels,exception);
1368 count=WriteBlob(image,length,pixels);
1369 if (count != (ssize_t) length)
1372 if (image->previous == (Image *) NULL)
1374 status=SetImageProgress(image,SaveImageTag,2,6);
1375 if (status == MagickFalse)
1378 (void) CloseBlob(image);
1379 AppendImageFormat("B",image->filename);
1380 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1381 AppendBinaryBlobMode,exception);
1382 if (status == MagickFalse)
1384 for (y=0; y < (ssize_t) image->rows; y++)
1386 register const Quantum
1389 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1390 if (p == (const Quantum *) NULL)
1392 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1393 BlueQuantum,pixels,exception);
1394 count=WriteBlob(image,length,pixels);
1395 if (count != (ssize_t) length)
1398 if (image->previous == (Image *) NULL)
1400 status=SetImageProgress(image,SaveImageTag,3,6);
1401 if (status == MagickFalse)
1404 (void) CloseBlob(image);
1405 if (quantum_type == RGBAQuantum)
1407 (void) CloseBlob(image);
1408 AppendImageFormat("A",image->filename);
1409 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1410 AppendBinaryBlobMode,exception);
1411 if (status == MagickFalse)
1413 for (y=0; y < (ssize_t) image->rows; y++)
1415 register const Quantum
1418 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1419 if (p == (const Quantum *) NULL)
1421 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1422 AlphaQuantum,pixels,exception);
1423 count=WriteBlob(image,length,pixels);
1424 if (count != (ssize_t) length)
1427 if (image->previous == (Image *) NULL)
1429 status=SetImageProgress(image,SaveImageTag,5,6);
1430 if (status == MagickFalse)
1434 (void) CloseBlob(image);
1435 (void) CopyMagickString(image->filename,image_info->filename,
1437 if (image->previous == (Image *) NULL)
1439 status=SetImageProgress(image,SaveImageTag,6,6);
1440 if (status == MagickFalse)
1446 quantum_info=DestroyQuantumInfo(quantum_info);
1447 if (GetNextImageInList(image) == (Image *) NULL)
1449 image=SyncNextImageInList(image);
1450 status=SetImageProgress(image,SaveImagesTag,scene++,
1451 GetImageListLength(image));
1452 if (status == MagickFalse)
1454 } while (image_info->adjoin != MagickFalse);
1455 (void) CloseBlob(image);