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 *);
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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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 == (const 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,
1066 % A description of each parameter follows.
1068 % o image_info: the image info.
1070 % o image: The image.
1073 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1099 Allocate memory for pixels.
1101 assert(image_info != (const ImageInfo *) NULL);
1102 assert(image_info->signature == MagickSignature);
1103 assert(image != (Image *) NULL);
1104 assert(image->signature == MagickSignature);
1105 if (image->debug != MagickFalse)
1106 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1107 if (image_info->interlace != PartitionInterlace)
1110 Open output image file.
1112 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1113 if (status == MagickFalse)
1116 quantum_type=RGBQuantum;
1117 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1119 quantum_type=RGBAQuantum;
1120 image->matte=MagickTrue;
1122 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1124 quantum_type=RGBOQuantum;
1125 image->matte=MagickTrue;
1131 Convert MIFF to RGB raster pixels.
1133 if (IsRGBColorspace(image->colorspace) == MagickFalse)
1134 (void) TransformImageColorspace(image,RGBColorspace);
1135 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1136 (image->matte == MagickFalse))
1137 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel);
1138 quantum_info=AcquireQuantumInfo(image_info,image);
1139 if (quantum_info == (QuantumInfo *) NULL)
1140 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1141 pixels=GetQuantumPixels(quantum_info);
1142 switch (image_info->interlace)
1148 No interlacing: RGBRGBRGBRGBRGBRGB...
1150 for (y=0; y < (ssize_t) image->rows; y++)
1152 register const Quantum
1155 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1156 if (p == (const Quantum *) NULL)
1158 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1159 quantum_type,pixels,&image->exception);
1160 count=WriteBlob(image,length,pixels);
1161 if (count != (ssize_t) length)
1163 if (image->previous == (Image *) NULL)
1165 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1167 if (status == MagickFalse)
1176 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1178 for (y=0; y < (ssize_t) image->rows; y++)
1180 register const Quantum
1183 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1184 if (p == (const Quantum *) NULL)
1186 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1187 RedQuantum,pixels,&image->exception);
1188 count=WriteBlob(image,length,pixels);
1189 if (count != (ssize_t) length)
1191 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1192 GreenQuantum,pixels,&image->exception);
1193 count=WriteBlob(image,length,pixels);
1194 if (count != (ssize_t) length)
1196 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1197 BlueQuantum,pixels,&image->exception);
1198 count=WriteBlob(image,length,pixels);
1199 if (count != (ssize_t) length)
1201 if (quantum_type == RGBAQuantum)
1203 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1204 AlphaQuantum,pixels,&image->exception);
1205 count=WriteBlob(image,length,pixels);
1206 if (count != (ssize_t) length)
1209 if (quantum_type == RGBOQuantum)
1211 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1212 OpacityQuantum,pixels,&image->exception);
1213 count=WriteBlob(image,length,pixels);
1214 if (count != (ssize_t) length)
1217 if (image->previous == (Image *) NULL)
1219 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1221 if (status == MagickFalse)
1227 case PlaneInterlace:
1230 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1232 for (y=0; y < (ssize_t) image->rows; y++)
1234 register const Quantum
1237 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1238 if (p == (const Quantum *) NULL)
1240 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1241 RedQuantum,pixels,&image->exception);
1242 count=WriteBlob(image,length,pixels);
1243 if (count != (ssize_t) length)
1246 if (image->previous == (Image *) NULL)
1248 status=SetImageProgress(image,SaveImageTag,1,6);
1249 if (status == MagickFalse)
1252 for (y=0; y < (ssize_t) image->rows; y++)
1254 register const Quantum
1257 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1258 if (p == (const Quantum *) NULL)
1260 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1261 GreenQuantum,pixels,&image->exception);
1262 count=WriteBlob(image,length,pixels);
1263 if (count != (ssize_t) length)
1266 if (image->previous == (Image *) NULL)
1268 status=SetImageProgress(image,SaveImageTag,2,6);
1269 if (status == MagickFalse)
1272 for (y=0; y < (ssize_t) image->rows; y++)
1274 register const Quantum
1277 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1278 if (p == (const Quantum *) NULL)
1280 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1281 BlueQuantum,pixels,&image->exception);
1282 count=WriteBlob(image,length,pixels);
1283 if (count != (ssize_t) length)
1286 if (image->previous == (Image *) NULL)
1288 status=SetImageProgress(image,SaveImageTag,3,6);
1289 if (status == MagickFalse)
1292 if (quantum_type == RGBAQuantum)
1294 for (y=0; y < (ssize_t) image->rows; y++)
1296 register const Quantum
1299 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1300 if (p == (const Quantum *) NULL)
1302 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1303 AlphaQuantum,pixels,&image->exception);
1304 count=WriteBlob(image,length,pixels);
1305 if (count != (ssize_t) length)
1308 if (image->previous == (Image *) NULL)
1310 status=SetImageProgress(image,SaveImageTag,5,6);
1311 if (status == MagickFalse)
1315 if (image_info->interlace == PartitionInterlace)
1316 (void) CopyMagickString(image->filename,image_info->filename,
1318 if (image->previous == (Image *) NULL)
1320 status=SetImageProgress(image,SaveImageTag,6,6);
1321 if (status == MagickFalse)
1326 case PartitionInterlace:
1329 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1331 AppendImageFormat("R",image->filename);
1332 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1333 AppendBinaryBlobMode,&image->exception);
1334 if (status == MagickFalse)
1336 for (y=0; y < (ssize_t) image->rows; y++)
1338 register const Quantum
1341 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1342 if (p == (const Quantum *) NULL)
1344 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1345 RedQuantum,pixels,&image->exception);
1346 count=WriteBlob(image,length,pixels);
1347 if (count != (ssize_t) length)
1350 if (image->previous == (Image *) NULL)
1352 status=SetImageProgress(image,SaveImageTag,1,6);
1353 if (status == MagickFalse)
1356 (void) CloseBlob(image);
1357 AppendImageFormat("G",image->filename);
1358 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1359 AppendBinaryBlobMode,&image->exception);
1360 if (status == MagickFalse)
1362 for (y=0; y < (ssize_t) image->rows; y++)
1364 register const Quantum
1367 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1368 if (p == (const Quantum *) NULL)
1370 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1371 GreenQuantum,pixels,&image->exception);
1372 count=WriteBlob(image,length,pixels);
1373 if (count != (ssize_t) length)
1376 if (image->previous == (Image *) NULL)
1378 status=SetImageProgress(image,SaveImageTag,2,6);
1379 if (status == MagickFalse)
1382 (void) CloseBlob(image);
1383 AppendImageFormat("B",image->filename);
1384 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1385 AppendBinaryBlobMode,&image->exception);
1386 if (status == MagickFalse)
1388 for (y=0; y < (ssize_t) image->rows; y++)
1390 register const Quantum
1393 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1394 if (p == (const Quantum *) NULL)
1396 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1397 BlueQuantum,pixels,&image->exception);
1398 count=WriteBlob(image,length,pixels);
1399 if (count != (ssize_t) length)
1402 if (image->previous == (Image *) NULL)
1404 status=SetImageProgress(image,SaveImageTag,3,6);
1405 if (status == MagickFalse)
1408 (void) CloseBlob(image);
1409 if (quantum_type == RGBAQuantum)
1411 (void) CloseBlob(image);
1412 AppendImageFormat("A",image->filename);
1413 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1414 AppendBinaryBlobMode,&image->exception);
1415 if (status == MagickFalse)
1417 for (y=0; y < (ssize_t) image->rows; y++)
1419 register const Quantum
1422 p=GetVirtualPixels(image,0,y,image->columns,1,
1424 if (p == (const Quantum *) NULL)
1426 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1427 AlphaQuantum,pixels,&image->exception);
1428 count=WriteBlob(image,length,pixels);
1429 if (count != (ssize_t) length)
1432 if (image->previous == (Image *) NULL)
1434 status=SetImageProgress(image,SaveImageTag,5,6);
1435 if (status == MagickFalse)
1439 (void) CloseBlob(image);
1440 (void) CopyMagickString(image->filename,image_info->filename,
1442 if (image->previous == (Image *) NULL)
1444 status=SetImageProgress(image,SaveImageTag,6,6);
1445 if (status == MagickFalse)
1451 quantum_info=DestroyQuantumInfo(quantum_info);
1452 if (GetNextImageInList(image) == (Image *) NULL)
1454 image=SyncNextImageInList(image);
1455 status=SetImageProgress(image,SaveImagesTag,scene++,
1456 GetImageListLength(image));
1457 if (status == MagickFalse)
1459 } while (image_info->adjoin != MagickFalse);
1460 (void) CloseBlob(image);