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);
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++)
487 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++)
540 GetPixelBlue(canvas_image,p),q);
541 p+=GetPixelChannels(canvas_image);
542 q+=GetPixelChannels(image);
544 if (SyncAuthenticPixels(image,exception) == MagickFalse)
547 count=ReadBlob(image,length,pixels);
549 if (image->previous == (Image *) NULL)
551 status=SetImageProgress(image,LoadImageTag,3,6);
552 if (status == MagickFalse)
555 if (image->previous == (Image *) NULL)
557 status=SetImageProgress(image,LoadImageTag,4,6);
558 if (status == MagickFalse)
561 if (image->matte != MagickFalse)
563 for (y=0; y < (ssize_t) image->extract_info.height; y++)
565 register const Quantum
574 if (count != (ssize_t) length)
576 ThrowFileException(exception,CorruptImageError,
577 "UnexpectedEndOfFile",image->filename);
580 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
582 if (q == (Quantum *) NULL)
584 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
585 quantum_info,AlphaQuantum,pixels,exception);
586 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
588 if (((y-image->extract_info.y) >= 0) &&
589 ((y-image->extract_info.y) < (ssize_t) image->rows))
591 p=GetVirtualPixels(canvas_image,
592 canvas_image->extract_info.x,0,canvas_image->columns,1,
594 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
595 image->columns,1,exception);
596 if ((p == (const Quantum *) NULL) ||
597 (q == (Quantum *) NULL))
599 for (x=0; x < (ssize_t) image->columns; x++)
602 GetPixelAlpha(canvas_image,p),q);
603 p+=GetPixelChannels(canvas_image);
604 q+=GetPixelChannels(image);
606 if (SyncAuthenticPixels(image,exception) == MagickFalse)
609 count=ReadBlob(image,length,pixels);
611 if (image->previous == (Image *) NULL)
613 status=SetImageProgress(image,LoadImageTag,5,6);
614 if (status == MagickFalse)
618 if (image->previous == (Image *) NULL)
620 status=SetImageProgress(image,LoadImageTag,6,6);
621 if (status == MagickFalse)
626 case PartitionInterlace:
629 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
631 AppendImageFormat("R",image->filename);
632 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
633 if (status == MagickFalse)
635 canvas_image=DestroyImageList(canvas_image);
636 image=DestroyImageList(image);
637 return((Image *) NULL);
639 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
640 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
642 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
643 for (i=0; i < (ssize_t) scene; i++)
644 for (y=0; y < (ssize_t) image->extract_info.height; y++)
645 if (ReadBlob(image,length,pixels) != (ssize_t) length)
647 ThrowFileException(exception,CorruptImageError,
648 "UnexpectedEndOfFile",image->filename);
651 count=ReadBlob(image,length,pixels);
652 for (y=0; y < (ssize_t) image->extract_info.height; y++)
654 register const Quantum
663 if (count != (ssize_t) length)
665 ThrowFileException(exception,CorruptImageError,
666 "UnexpectedEndOfFile",image->filename);
669 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
671 if (q == (Quantum *) NULL)
673 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
674 quantum_info,RedQuantum,pixels,exception);
675 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
677 if (((y-image->extract_info.y) >= 0) &&
678 ((y-image->extract_info.y) < (ssize_t) image->rows))
680 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
681 canvas_image->columns,1,exception);
682 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
683 image->columns,1,exception);
684 if ((p == (const Quantum *) NULL) ||
685 (q == (Quantum *) NULL))
687 for (x=0; x < (ssize_t) image->columns; x++)
689 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
690 p+=GetPixelChannels(canvas_image);
691 q+=GetPixelChannels(image);
693 if (SyncAuthenticPixels(image,exception) == MagickFalse)
696 count=ReadBlob(image,length,pixels);
698 if (image->previous == (Image *) NULL)
700 status=SetImageProgress(image,LoadImageTag,1,5);
701 if (status == MagickFalse)
704 (void) CloseBlob(image);
705 AppendImageFormat("G",image->filename);
706 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
707 if (status == MagickFalse)
709 canvas_image=DestroyImageList(canvas_image);
710 image=DestroyImageList(image);
711 return((Image *) NULL);
713 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
714 for (i=0; i < (ssize_t) scene; i++)
715 for (y=0; y < (ssize_t) image->extract_info.height; y++)
716 if (ReadBlob(image,length,pixels) != (ssize_t) length)
718 ThrowFileException(exception,CorruptImageError,
719 "UnexpectedEndOfFile",image->filename);
722 count=ReadBlob(image,length,pixels);
723 for (y=0; y < (ssize_t) image->extract_info.height; y++)
725 register const Quantum
734 if (count != (ssize_t) length)
736 ThrowFileException(exception,CorruptImageError,
737 "UnexpectedEndOfFile",image->filename);
740 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
742 if (q == (Quantum *) NULL)
744 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
745 quantum_info,GreenQuantum,pixels,exception);
746 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
748 if (((y-image->extract_info.y) >= 0) &&
749 ((y-image->extract_info.y) < (ssize_t) image->rows))
751 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
752 canvas_image->columns,1,exception);
753 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
754 image->columns,1,exception);
755 if ((p == (const Quantum *) NULL) ||
756 (q == (Quantum *) NULL))
758 for (x=0; x < (ssize_t) image->columns; x++)
761 GetPixelGreen(canvas_image,p),q);
762 p+=GetPixelChannels(canvas_image);
763 q+=GetPixelChannels(image);
765 if (SyncAuthenticPixels(image,exception) == MagickFalse)
768 count=ReadBlob(image,length,pixels);
770 if (image->previous == (Image *) NULL)
772 status=SetImageProgress(image,LoadImageTag,2,5);
773 if (status == MagickFalse)
776 (void) CloseBlob(image);
777 AppendImageFormat("B",image->filename);
778 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
779 if (status == MagickFalse)
781 canvas_image=DestroyImageList(canvas_image);
782 image=DestroyImageList(image);
783 return((Image *) NULL);
785 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
786 for (i=0; i < (ssize_t) scene; i++)
787 for (y=0; y < (ssize_t) image->extract_info.height; y++)
788 if (ReadBlob(image,length,pixels) != (ssize_t) length)
790 ThrowFileException(exception,CorruptImageError,
791 "UnexpectedEndOfFile",image->filename);
794 count=ReadBlob(image,length,pixels);
795 for (y=0; y < (ssize_t) image->extract_info.height; y++)
797 register const Quantum
806 if (count != (ssize_t) length)
808 ThrowFileException(exception,CorruptImageError,
809 "UnexpectedEndOfFile",image->filename);
812 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
814 if (q == (Quantum *) NULL)
816 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
817 quantum_info,BlueQuantum,pixels,exception);
818 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
820 if (((y-image->extract_info.y) >= 0) &&
821 ((y-image->extract_info.y) < (ssize_t) image->rows))
823 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
824 canvas_image->columns,1,exception);
825 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
826 image->columns,1,exception);
827 if ((p == (const Quantum *) NULL) ||
828 (q == (Quantum *) NULL))
830 for (x=0; x < (ssize_t) image->columns; x++)
833 GetPixelBlue(canvas_image,p),q);
834 p+=GetPixelChannels(canvas_image);
835 q+=GetPixelChannels(image);
837 if (SyncAuthenticPixels(image,exception) == MagickFalse)
840 count=ReadBlob(image,length,pixels);
842 if (image->previous == (Image *) NULL)
844 status=SetImageProgress(image,LoadImageTag,3,5);
845 if (status == MagickFalse)
848 if (image->matte != MagickFalse)
850 (void) CloseBlob(image);
851 AppendImageFormat("A",image->filename);
852 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
853 if (status == MagickFalse)
855 canvas_image=DestroyImageList(canvas_image);
856 image=DestroyImageList(image);
857 return((Image *) NULL);
859 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
860 for (i=0; i < (ssize_t) scene; i++)
861 for (y=0; y < (ssize_t) image->extract_info.height; y++)
862 if (ReadBlob(image,length,pixels) != (ssize_t) length)
864 ThrowFileException(exception,CorruptImageError,
865 "UnexpectedEndOfFile",image->filename);
868 count=ReadBlob(image,length,pixels);
869 for (y=0; y < (ssize_t) image->extract_info.height; y++)
871 register const Quantum
880 if (count != (ssize_t) length)
882 ThrowFileException(exception,CorruptImageError,
883 "UnexpectedEndOfFile",image->filename);
886 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
888 if (q == (Quantum *) NULL)
890 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
891 quantum_info,BlueQuantum,pixels,exception);
892 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
894 if (((y-image->extract_info.y) >= 0) &&
895 ((y-image->extract_info.y) < (ssize_t) image->rows))
897 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
898 0,canvas_image->columns,1,exception);
899 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
900 image->columns,1,exception);
901 if ((p == (const Quantum *) NULL) ||
902 (q == (Quantum *) NULL))
904 for (x=0; x < (ssize_t) image->columns; x++)
907 GetPixelAlpha(canvas_image,p),q);
908 p+=GetPixelChannels(canvas_image);
909 q+=GetPixelChannels(image);
911 if (SyncAuthenticPixels(image,exception) == MagickFalse)
914 count=ReadBlob(image,length,pixels);
916 if (image->previous == (Image *) NULL)
918 status=SetImageProgress(image,LoadImageTag,4,5);
919 if (status == MagickFalse)
923 (void) CloseBlob(image);
924 if (image->previous == (Image *) NULL)
926 status=SetImageProgress(image,LoadImageTag,5,5);
927 if (status == MagickFalse)
933 SetQuantumImageType(image,quantum_type);
935 Proceed to next image.
937 if (image_info->number_scenes != 0)
938 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
940 if (count == (ssize_t) length)
943 Allocate next image structure.
945 AcquireNextImage(image_info,image);
946 if (GetNextImageInList(image) == (Image *) NULL)
948 image=DestroyImageList(image);
949 return((Image *) NULL);
951 image=SyncNextImageInList(image);
952 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
954 if (status == MagickFalse)
958 } while (count == (ssize_t) length);
959 quantum_info=DestroyQuantumInfo(quantum_info);
960 InheritException(&image->exception,&canvas_image->exception);
961 canvas_image=DestroyImage(canvas_image);
962 (void) CloseBlob(image);
963 return(GetFirstImageInList(image));
967 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971 % R e g i s t e r R G B I m a g e %
975 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 % RegisterRGBImage() adds attributes for the RGB image format to
978 % the list of supported formats. The attributes include the image format
979 % tag, a method to read and/or write the format, whether the format
980 % supports the saving of more than one frame to the same file or blob,
981 % whether the format supports native in-memory I/O, and a brief
982 % description of the format.
984 % The format of the RegisterRGBImage method is:
986 % size_t RegisterRGBImage(void)
989 ModuleExport size_t RegisterRGBImage(void)
994 entry=SetMagickInfo("RGB");
995 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
996 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
997 entry->raw=MagickTrue;
998 entry->endian_support=MagickTrue;
999 entry->description=ConstantString("Raw red, green, and blue samples");
1000 entry->module=ConstantString("RGB");
1001 (void) RegisterMagickInfo(entry);
1002 entry=SetMagickInfo("RGBA");
1003 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1004 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1005 entry->raw=MagickTrue;
1006 entry->endian_support=MagickTrue;
1007 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1008 entry->module=ConstantString("RGB");
1009 (void) RegisterMagickInfo(entry);
1010 entry=SetMagickInfo("RGBO");
1011 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1012 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1013 entry->raw=MagickTrue;
1014 entry->endian_support=MagickTrue;
1015 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1016 entry->module=ConstantString("RGB");
1017 (void) RegisterMagickInfo(entry);
1018 return(MagickImageCoderSignature);
1022 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1026 % U n r e g i s t e r R G B I m a g e %
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1032 % UnregisterRGBImage() removes format registrations made by the RGB module
1033 % from the list of supported formats.
1035 % The format of the UnregisterRGBImage method is:
1037 % UnregisterRGBImage(void)
1040 ModuleExport void UnregisterRGBImage(void)
1042 (void) UnregisterMagickInfo("RGBO");
1043 (void) UnregisterMagickInfo("RGBA");
1044 (void) UnregisterMagickInfo("RGB");
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052 % W r i t e R G B I m a g e %
1056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1058 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1059 % rasterfile format.
1061 % The format of the WriteRGBImage method is:
1063 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1064 % Image *image,ExceptionInfo *exception)
1066 % A description of each parameter follows.
1068 % o image_info: the image info.
1070 % o image: The image.
1072 % o exception: return any errors or warnings in this structure.
1075 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1076 Image *image,ExceptionInfo *exception)
1101 Allocate memory for pixels.
1103 assert(image_info != (const ImageInfo *) NULL);
1104 assert(image_info->signature == MagickSignature);
1105 assert(image != (Image *) NULL);
1106 assert(image->signature == MagickSignature);
1107 if (image->debug != MagickFalse)
1108 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1109 if (image_info->interlace != PartitionInterlace)
1112 Open output image file.
1114 assert(exception != (ExceptionInfo *) NULL);
1115 assert(exception->signature == MagickSignature);
1116 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1117 if (status == MagickFalse)
1120 quantum_type=RGBQuantum;
1121 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1123 quantum_type=RGBAQuantum;
1124 image->matte=MagickTrue;
1126 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1128 quantum_type=RGBOQuantum;
1129 image->matte=MagickTrue;
1135 Convert MIFF to RGB raster pixels.
1137 if (IsRGBColorspace(image->colorspace) == MagickFalse)
1138 (void) TransformImageColorspace(image,RGBColorspace);
1139 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1140 (image->matte == MagickFalse))
1141 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1142 quantum_info=AcquireQuantumInfo(image_info,image);
1143 if (quantum_info == (QuantumInfo *) NULL)
1144 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1145 pixels=GetQuantumPixels(quantum_info);
1146 switch (image_info->interlace)
1152 No interlacing: RGBRGBRGBRGBRGBRGB...
1154 for (y=0; y < (ssize_t) image->rows; y++)
1156 register const Quantum
1159 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1160 if (p == (const Quantum *) NULL)
1162 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1163 quantum_type,pixels,exception);
1164 count=WriteBlob(image,length,pixels);
1165 if (count != (ssize_t) length)
1167 if (image->previous == (Image *) NULL)
1169 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1171 if (status == MagickFalse)
1180 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1182 for (y=0; y < (ssize_t) image->rows; y++)
1184 register const Quantum
1187 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1188 if (p == (const Quantum *) NULL)
1190 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1191 RedQuantum,pixels,exception);
1192 count=WriteBlob(image,length,pixels);
1193 if (count != (ssize_t) length)
1195 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1196 GreenQuantum,pixels,exception);
1197 count=WriteBlob(image,length,pixels);
1198 if (count != (ssize_t) length)
1200 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1201 BlueQuantum,pixels,exception);
1202 count=WriteBlob(image,length,pixels);
1203 if (count != (ssize_t) length)
1205 if (quantum_type == RGBAQuantum)
1207 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1208 AlphaQuantum,pixels,exception);
1209 count=WriteBlob(image,length,pixels);
1210 if (count != (ssize_t) length)
1213 if (quantum_type == RGBOQuantum)
1215 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1216 OpacityQuantum,pixels,exception);
1217 count=WriteBlob(image,length,pixels);
1218 if (count != (ssize_t) length)
1221 if (image->previous == (Image *) NULL)
1223 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1225 if (status == MagickFalse)
1231 case PlaneInterlace:
1234 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1236 for (y=0; y < (ssize_t) image->rows; y++)
1238 register const Quantum
1241 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1242 if (p == (const Quantum *) NULL)
1244 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1245 RedQuantum,pixels,exception);
1246 count=WriteBlob(image,length,pixels);
1247 if (count != (ssize_t) length)
1250 if (image->previous == (Image *) NULL)
1252 status=SetImageProgress(image,SaveImageTag,1,6);
1253 if (status == MagickFalse)
1256 for (y=0; y < (ssize_t) image->rows; y++)
1258 register const Quantum
1261 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1262 if (p == (const Quantum *) NULL)
1264 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1265 GreenQuantum,pixels,exception);
1266 count=WriteBlob(image,length,pixels);
1267 if (count != (ssize_t) length)
1270 if (image->previous == (Image *) NULL)
1272 status=SetImageProgress(image,SaveImageTag,2,6);
1273 if (status == MagickFalse)
1276 for (y=0; y < (ssize_t) image->rows; y++)
1278 register const Quantum
1281 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1282 if (p == (const Quantum *) NULL)
1284 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1285 BlueQuantum,pixels,exception);
1286 count=WriteBlob(image,length,pixels);
1287 if (count != (ssize_t) length)
1290 if (image->previous == (Image *) NULL)
1292 status=SetImageProgress(image,SaveImageTag,3,6);
1293 if (status == MagickFalse)
1296 if (quantum_type == RGBAQuantum)
1298 for (y=0; y < (ssize_t) image->rows; y++)
1300 register const Quantum
1303 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1304 if (p == (const Quantum *) NULL)
1306 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1307 AlphaQuantum,pixels,exception);
1308 count=WriteBlob(image,length,pixels);
1309 if (count != (ssize_t) length)
1312 if (image->previous == (Image *) NULL)
1314 status=SetImageProgress(image,SaveImageTag,5,6);
1315 if (status == MagickFalse)
1319 if (image_info->interlace == PartitionInterlace)
1320 (void) CopyMagickString(image->filename,image_info->filename,
1322 if (image->previous == (Image *) NULL)
1324 status=SetImageProgress(image,SaveImageTag,6,6);
1325 if (status == MagickFalse)
1330 case PartitionInterlace:
1333 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1335 AppendImageFormat("R",image->filename);
1336 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1337 AppendBinaryBlobMode,exception);
1338 if (status == MagickFalse)
1340 for (y=0; y < (ssize_t) image->rows; y++)
1342 register const Quantum
1345 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1346 if (p == (const Quantum *) NULL)
1348 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1349 RedQuantum,pixels,exception);
1350 count=WriteBlob(image,length,pixels);
1351 if (count != (ssize_t) length)
1354 if (image->previous == (Image *) NULL)
1356 status=SetImageProgress(image,SaveImageTag,1,6);
1357 if (status == MagickFalse)
1360 (void) CloseBlob(image);
1361 AppendImageFormat("G",image->filename);
1362 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1363 AppendBinaryBlobMode,exception);
1364 if (status == MagickFalse)
1366 for (y=0; y < (ssize_t) image->rows; y++)
1368 register const Quantum
1371 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1372 if (p == (const Quantum *) NULL)
1374 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1375 GreenQuantum,pixels,exception);
1376 count=WriteBlob(image,length,pixels);
1377 if (count != (ssize_t) length)
1380 if (image->previous == (Image *) NULL)
1382 status=SetImageProgress(image,SaveImageTag,2,6);
1383 if (status == MagickFalse)
1386 (void) CloseBlob(image);
1387 AppendImageFormat("B",image->filename);
1388 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1389 AppendBinaryBlobMode,exception);
1390 if (status == MagickFalse)
1392 for (y=0; y < (ssize_t) image->rows; y++)
1394 register const Quantum
1397 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1398 if (p == (const Quantum *) NULL)
1400 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1401 BlueQuantum,pixels,exception);
1402 count=WriteBlob(image,length,pixels);
1403 if (count != (ssize_t) length)
1406 if (image->previous == (Image *) NULL)
1408 status=SetImageProgress(image,SaveImageTag,3,6);
1409 if (status == MagickFalse)
1412 (void) CloseBlob(image);
1413 if (quantum_type == RGBAQuantum)
1415 (void) CloseBlob(image);
1416 AppendImageFormat("A",image->filename);
1417 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1418 AppendBinaryBlobMode,exception);
1419 if (status == MagickFalse)
1421 for (y=0; y < (ssize_t) image->rows; y++)
1423 register const Quantum
1426 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1427 if (p == (const Quantum *) NULL)
1429 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1430 AlphaQuantum,pixels,exception);
1431 count=WriteBlob(image,length,pixels);
1432 if (count != (ssize_t) length)
1435 if (image->previous == (Image *) NULL)
1437 status=SetImageProgress(image,SaveImageTag,5,6);
1438 if (status == MagickFalse)
1442 (void) CloseBlob(image);
1443 (void) CopyMagickString(image->filename,image_info->filename,
1445 if (image->previous == (Image *) NULL)
1447 status=SetImageProgress(image,SaveImageTag,6,6);
1448 if (status == MagickFalse)
1454 quantum_info=DestroyQuantumInfo(quantum_info);
1455 if (GetNextImageInList(image) == (Image *) NULL)
1457 image=SyncNextImageInList(image);
1458 status=SetImageProgress(image,SaveImagesTag,scene++,
1459 GetImageListLength(image));
1460 if (status == MagickFalse)
1462 } while (image_info->adjoin != MagickFalse);
1463 (void) CloseBlob(image);