2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw RGB Image Format %
20 % Copyright 1999-2014 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/channel.h"
47 #include "MagickCore/colorspace.h"
48 #include "MagickCore/colorspace-private.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/magick.h"
56 #include "MagickCore/memory_.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/statistic.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/utility.h"
70 static MagickBooleanType
71 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % R e a d R G B I m a g e %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
85 % it. It allocates the memory necessary for the new Image structure and
86 % returns a pointer to the new image.
88 % The format of the ReadRGBImage method is:
90 % Image *ReadRGBImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
93 % A description of each parameter follows:
95 % o image_info: the image info.
97 % o exception: return any errors or warnings in this structure.
100 static Image *ReadRGBImage(const ImageInfo *image_info,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 if (image_info->interlace != PartitionInterlace)
146 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
147 if (status == MagickFalse)
149 image=DestroyImageList(image);
150 return((Image *) NULL);
152 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
153 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
157 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
159 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
161 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
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->alpha_trait=BlendPixelTrait;
172 canvas_image->alpha_trait=BlendPixelTrait;
174 if (LocaleCompare(image_info->magick,"RGBO") == 0)
176 quantum_type=RGBOQuantum;
177 canvas_image->alpha_trait=BlendPixelTrait;
179 if (image_info->number_scenes != 0)
180 while (image->scene < image_info->scene)
186 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
187 for (y=0; y < (ssize_t) image->rows; y++)
189 count=ReadBlob(image,length,pixels);
190 if (count != (ssize_t) length)
200 Read pixels to virtual canvas image then push to image.
202 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
203 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
205 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) || (q == (Quantum *) NULL))
252 for (x=0; x < (ssize_t) image->columns; x++)
254 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
255 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
256 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
257 SetPixelAlpha(image,OpaqueAlpha,q);
258 if (image->alpha_trait == BlendPixelTrait)
259 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
260 p+=GetPixelChannels(canvas_image);
261 q+=GetPixelChannels(image);
263 if (SyncAuthenticPixels(image,exception) == MagickFalse)
266 if (image->previous == (Image *) NULL)
268 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
270 if (status == MagickFalse)
273 count=ReadBlob(image,length,pixels);
289 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
291 if (LocaleCompare(image_info->magick,"RGBO") == 0)
292 quantum_types[3]=OpacityQuantum;
295 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
296 count=ReadBlob(image,length,pixels);
298 for (y=0; y < (ssize_t) image->extract_info.height; y++)
300 register const Quantum
309 if (count != (ssize_t) length)
311 ThrowFileException(exception,CorruptImageError,
312 "UnexpectedEndOfFile",image->filename);
315 for (i=0; i < (ssize_t) (image->alpha_trait == BlendPixelTrait ? 4 : 3); i++)
317 quantum_type=quantum_types[i];
318 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
320 if (q == (Quantum *) NULL)
322 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
323 quantum_info,quantum_type,pixels,exception);
324 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
326 if (((y-image->extract_info.y) >= 0) &&
327 ((y-image->extract_info.y) < (ssize_t) image->rows))
329 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
330 0,canvas_image->columns,1,exception);
331 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
332 image->columns,1,exception);
333 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
335 for (x=0; x < (ssize_t) image->columns; x++)
337 switch (quantum_type)
341 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
346 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
351 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
356 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
361 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
367 p+=GetPixelChannels(canvas_image);
368 q+=GetPixelChannels(image);
370 if (SyncAuthenticPixels(image,exception) == MagickFalse)
373 count=ReadBlob(image,length,pixels);
375 if (image->previous == (Image *) NULL)
377 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
379 if (status == MagickFalse)
388 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
392 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
393 count=ReadBlob(image,length,pixels);
395 for (y=0; y < (ssize_t) image->extract_info.height; y++)
397 register const Quantum
406 if (count != (ssize_t) length)
408 ThrowFileException(exception,CorruptImageError,
409 "UnexpectedEndOfFile",image->filename);
412 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
414 if (q == (Quantum *) NULL)
416 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
417 quantum_info,RedQuantum,pixels,exception);
418 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
420 if (((y-image->extract_info.y) >= 0) &&
421 ((y-image->extract_info.y) < (ssize_t) image->rows))
423 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
424 canvas_image->columns,1,exception);
425 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
426 image->columns,1,exception);
427 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
429 for (x=0; x < (ssize_t) image->columns; x++)
431 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
432 p+=GetPixelChannels(canvas_image);
433 q+=GetPixelChannels(image);
435 if (SyncAuthenticPixels(image,exception) == MagickFalse)
438 count=ReadBlob(image,length,pixels);
440 if (image->previous == (Image *) NULL)
442 status=SetImageProgress(image,LoadImageTag,1,6);
443 if (status == MagickFalse)
446 for (y=0; y < (ssize_t) image->extract_info.height; y++)
448 register const Quantum
457 if (count != (ssize_t) length)
459 ThrowFileException(exception,CorruptImageError,
460 "UnexpectedEndOfFile",image->filename);
463 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
465 if (q == (Quantum *) NULL)
467 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
468 quantum_info,GreenQuantum,pixels,exception);
469 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
471 if (((y-image->extract_info.y) >= 0) &&
472 ((y-image->extract_info.y) < (ssize_t) image->rows))
474 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
475 canvas_image->columns,1,exception);
476 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
477 image->columns,1,exception);
478 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
480 for (x=0; x < (ssize_t) image->columns; x++)
482 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
483 p+=GetPixelChannels(canvas_image);
484 q+=GetPixelChannels(image);
486 if (SyncAuthenticPixels(image,exception) == MagickFalse)
489 count=ReadBlob(image,length,pixels);
491 if (image->previous == (Image *) NULL)
493 status=SetImageProgress(image,LoadImageTag,2,6);
494 if (status == MagickFalse)
497 for (y=0; y < (ssize_t) image->extract_info.height; y++)
499 register const Quantum
508 if (count != (ssize_t) length)
510 ThrowFileException(exception,CorruptImageError,
511 "UnexpectedEndOfFile",image->filename);
514 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
516 if (q == (Quantum *) NULL)
518 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
519 quantum_info,BlueQuantum,pixels,exception);
520 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
522 if (((y-image->extract_info.y) >= 0) &&
523 ((y-image->extract_info.y) < (ssize_t) image->rows))
525 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
526 canvas_image->columns,1,exception);
527 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
528 image->columns,1,exception);
529 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
531 for (x=0; x < (ssize_t) image->columns; x++)
533 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
534 p+=GetPixelChannels(canvas_image);
535 q+=GetPixelChannels(image);
537 if (SyncAuthenticPixels(image,exception) == MagickFalse)
540 count=ReadBlob(image,length,pixels);
542 if (image->previous == (Image *) NULL)
544 status=SetImageProgress(image,LoadImageTag,3,6);
545 if (status == MagickFalse)
548 if (image->previous == (Image *) NULL)
550 status=SetImageProgress(image,LoadImageTag,4,6);
551 if (status == MagickFalse)
554 if (image->alpha_trait == BlendPixelTrait)
556 for (y=0; y < (ssize_t) image->extract_info.height; y++)
558 register const Quantum
567 if (count != (ssize_t) length)
569 ThrowFileException(exception,CorruptImageError,
570 "UnexpectedEndOfFile",image->filename);
573 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
575 if (q == (Quantum *) NULL)
577 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
578 quantum_info,AlphaQuantum,pixels,exception);
579 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
581 if (((y-image->extract_info.y) >= 0) &&
582 ((y-image->extract_info.y) < (ssize_t) image->rows))
584 p=GetVirtualPixels(canvas_image,
585 canvas_image->extract_info.x,0,canvas_image->columns,1,
587 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
588 image->columns,1,exception);
589 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
591 for (x=0; x < (ssize_t) image->columns; x++)
593 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
594 p+=GetPixelChannels(canvas_image);
595 q+=GetPixelChannels(image);
597 if (SyncAuthenticPixels(image,exception) == MagickFalse)
600 count=ReadBlob(image,length,pixels);
602 if (image->previous == (Image *) NULL)
604 status=SetImageProgress(image,LoadImageTag,5,6);
605 if (status == MagickFalse)
609 if (image->previous == (Image *) NULL)
611 status=SetImageProgress(image,LoadImageTag,6,6);
612 if (status == MagickFalse)
617 case PartitionInterlace:
620 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
622 AppendImageFormat("R",image->filename);
623 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
624 if (status == MagickFalse)
626 canvas_image=DestroyImageList(canvas_image);
627 image=DestroyImageList(image);
628 return((Image *) NULL);
630 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
631 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
633 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
634 for (i=0; i < (ssize_t) scene; i++)
635 for (y=0; y < (ssize_t) image->extract_info.height; y++)
636 if (ReadBlob(image,length,pixels) != (ssize_t) length)
638 ThrowFileException(exception,CorruptImageError,
639 "UnexpectedEndOfFile",image->filename);
642 count=ReadBlob(image,length,pixels);
643 for (y=0; y < (ssize_t) image->extract_info.height; y++)
645 register const Quantum
654 if (count != (ssize_t) length)
656 ThrowFileException(exception,CorruptImageError,
657 "UnexpectedEndOfFile",image->filename);
660 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
662 if (q == (Quantum *) NULL)
664 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
665 quantum_info,RedQuantum,pixels,exception);
666 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
668 if (((y-image->extract_info.y) >= 0) &&
669 ((y-image->extract_info.y) < (ssize_t) image->rows))
671 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
672 canvas_image->columns,1,exception);
673 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
674 image->columns,1,exception);
675 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
677 for (x=0; x < (ssize_t) image->columns; x++)
679 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
680 p+=GetPixelChannels(canvas_image);
681 q+=GetPixelChannels(image);
683 if (SyncAuthenticPixels(image,exception) == MagickFalse)
686 count=ReadBlob(image,length,pixels);
688 if (image->previous == (Image *) NULL)
690 status=SetImageProgress(image,LoadImageTag,1,5);
691 if (status == MagickFalse)
694 (void) CloseBlob(image);
695 AppendImageFormat("G",image->filename);
696 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
697 if (status == MagickFalse)
699 canvas_image=DestroyImageList(canvas_image);
700 image=DestroyImageList(image);
701 return((Image *) NULL);
703 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
704 for (i=0; i < (ssize_t) scene; i++)
705 for (y=0; y < (ssize_t) image->extract_info.height; y++)
706 if (ReadBlob(image,length,pixels) != (ssize_t) length)
708 ThrowFileException(exception,CorruptImageError,
709 "UnexpectedEndOfFile",image->filename);
712 count=ReadBlob(image,length,pixels);
713 for (y=0; y < (ssize_t) image->extract_info.height; y++)
715 register const Quantum
724 if (count != (ssize_t) length)
726 ThrowFileException(exception,CorruptImageError,
727 "UnexpectedEndOfFile",image->filename);
730 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
732 if (q == (Quantum *) NULL)
734 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
735 quantum_info,GreenQuantum,pixels,exception);
736 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
738 if (((y-image->extract_info.y) >= 0) &&
739 ((y-image->extract_info.y) < (ssize_t) image->rows))
741 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
742 canvas_image->columns,1,exception);
743 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
744 image->columns,1,exception);
745 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
747 for (x=0; x < (ssize_t) image->columns; x++)
749 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
750 p+=GetPixelChannels(canvas_image);
751 q+=GetPixelChannels(image);
753 if (SyncAuthenticPixels(image,exception) == MagickFalse)
756 count=ReadBlob(image,length,pixels);
758 if (image->previous == (Image *) NULL)
760 status=SetImageProgress(image,LoadImageTag,2,5);
761 if (status == MagickFalse)
764 (void) CloseBlob(image);
765 AppendImageFormat("B",image->filename);
766 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
767 if (status == MagickFalse)
769 canvas_image=DestroyImageList(canvas_image);
770 image=DestroyImageList(image);
771 return((Image *) NULL);
773 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
774 for (i=0; i < (ssize_t) scene; i++)
775 for (y=0; y < (ssize_t) image->extract_info.height; y++)
776 if (ReadBlob(image,length,pixels) != (ssize_t) length)
778 ThrowFileException(exception,CorruptImageError,
779 "UnexpectedEndOfFile",image->filename);
782 count=ReadBlob(image,length,pixels);
783 for (y=0; y < (ssize_t) image->extract_info.height; y++)
785 register const Quantum
794 if (count != (ssize_t) length)
796 ThrowFileException(exception,CorruptImageError,
797 "UnexpectedEndOfFile",image->filename);
800 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
802 if (q == (Quantum *) NULL)
804 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
805 quantum_info,BlueQuantum,pixels,exception);
806 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
808 if (((y-image->extract_info.y) >= 0) &&
809 ((y-image->extract_info.y) < (ssize_t) image->rows))
811 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
812 canvas_image->columns,1,exception);
813 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
814 image->columns,1,exception);
815 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
817 for (x=0; x < (ssize_t) image->columns; x++)
819 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
820 p+=GetPixelChannels(canvas_image);
821 q+=GetPixelChannels(image);
823 if (SyncAuthenticPixels(image,exception) == MagickFalse)
826 count=ReadBlob(image,length,pixels);
828 if (image->previous == (Image *) NULL)
830 status=SetImageProgress(image,LoadImageTag,3,5);
831 if (status == MagickFalse)
834 if (image->alpha_trait == BlendPixelTrait)
836 (void) CloseBlob(image);
837 AppendImageFormat("A",image->filename);
838 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
839 if (status == MagickFalse)
841 canvas_image=DestroyImageList(canvas_image);
842 image=DestroyImageList(image);
843 return((Image *) NULL);
845 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
846 for (i=0; i < (ssize_t) scene; i++)
847 for (y=0; y < (ssize_t) image->extract_info.height; y++)
848 if (ReadBlob(image,length,pixels) != (ssize_t) length)
850 ThrowFileException(exception,CorruptImageError,
851 "UnexpectedEndOfFile",image->filename);
854 count=ReadBlob(image,length,pixels);
855 for (y=0; y < (ssize_t) image->extract_info.height; y++)
857 register const Quantum
866 if (count != (ssize_t) length)
868 ThrowFileException(exception,CorruptImageError,
869 "UnexpectedEndOfFile",image->filename);
872 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
874 if (q == (Quantum *) NULL)
876 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
877 quantum_info,BlueQuantum,pixels,exception);
878 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
880 if (((y-image->extract_info.y) >= 0) &&
881 ((y-image->extract_info.y) < (ssize_t) image->rows))
883 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
884 0,canvas_image->columns,1,exception);
885 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
886 image->columns,1,exception);
887 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
889 for (x=0; x < (ssize_t) image->columns; x++)
891 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
892 p+=GetPixelChannels(canvas_image);
893 q+=GetPixelChannels(image);
895 if (SyncAuthenticPixels(image,exception) == MagickFalse)
898 count=ReadBlob(image,length,pixels);
900 if (image->previous == (Image *) NULL)
902 status=SetImageProgress(image,LoadImageTag,4,5);
903 if (status == MagickFalse)
907 (void) CloseBlob(image);
908 if (image->previous == (Image *) NULL)
910 status=SetImageProgress(image,LoadImageTag,5,5);
911 if (status == MagickFalse)
917 SetQuantumImageType(image,quantum_type);
919 Proceed to next image.
921 if (image_info->number_scenes != 0)
922 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
924 if (count == (ssize_t) length)
927 Allocate next image structure.
929 AcquireNextImage(image_info,image,exception);
930 if (GetNextImageInList(image) == (Image *) NULL)
932 image=DestroyImageList(image);
933 return((Image *) NULL);
935 image=SyncNextImageInList(image);
936 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
938 if (status == MagickFalse)
942 } while (count == (ssize_t) length);
943 quantum_info=DestroyQuantumInfo(quantum_info);
944 canvas_image=DestroyImage(canvas_image);
945 (void) CloseBlob(image);
946 return(GetFirstImageInList(image));
950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 % R e g i s t e r R G B I m a g e %
958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960 % RegisterRGBImage() adds attributes for the RGB image format to
961 % the list of supported formats. The attributes include the image format
962 % tag, a method to read and/or write the format, whether the format
963 % supports the saving of more than one frame to the same file or blob,
964 % whether the format supports native in-memory I/O, and a brief
965 % description of the format.
967 % The format of the RegisterRGBImage method is:
969 % size_t RegisterRGBImage(void)
972 ModuleExport size_t RegisterRGBImage(void)
977 entry=SetMagickInfo("RGB");
978 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
979 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
980 entry->raw=MagickTrue;
981 entry->endian_support=MagickTrue;
982 entry->description=ConstantString("Raw red, green, and blue samples");
983 entry->module=ConstantString("RGB");
984 (void) RegisterMagickInfo(entry);
985 entry=SetMagickInfo("RGBA");
986 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
987 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
988 entry->raw=MagickTrue;
989 entry->endian_support=MagickTrue;
990 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
991 entry->module=ConstantString("RGB");
992 (void) RegisterMagickInfo(entry);
993 entry=SetMagickInfo("RGBO");
994 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
995 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
996 entry->raw=MagickTrue;
997 entry->endian_support=MagickTrue;
998 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
999 entry->module=ConstantString("RGB");
1000 (void) RegisterMagickInfo(entry);
1001 return(MagickImageCoderSignature);
1005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009 % U n r e g i s t e r R G B I m a g e %
1013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015 % UnregisterRGBImage() removes format registrations made by the RGB module
1016 % from the list of supported formats.
1018 % The format of the UnregisterRGBImage method is:
1020 % UnregisterRGBImage(void)
1023 ModuleExport void UnregisterRGBImage(void)
1025 (void) UnregisterMagickInfo("RGBO");
1026 (void) UnregisterMagickInfo("RGBA");
1027 (void) UnregisterMagickInfo("RGB");
1031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035 % W r i t e R G B I m a g e %
1039 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1041 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1042 % rasterfile format.
1044 % The format of the WriteRGBImage method is:
1046 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1047 % Image *image,ExceptionInfo *exception)
1049 % A description of each parameter follows.
1051 % o image_info: the image info.
1053 % o image: The image.
1055 % o exception: return any errors or warnings in this structure.
1058 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1059 Image *image,ExceptionInfo *exception)
1084 Allocate memory for pixels.
1086 assert(image_info != (const ImageInfo *) NULL);
1087 assert(image_info->signature == MagickSignature);
1088 assert(image != (Image *) NULL);
1089 assert(image->signature == MagickSignature);
1090 if (image->debug != MagickFalse)
1091 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1092 if (image_info->interlace != PartitionInterlace)
1095 Open output image file.
1097 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1098 if (status == MagickFalse)
1101 quantum_type=RGBQuantum;
1102 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1103 quantum_type=RGBAQuantum;
1104 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1105 quantum_type=RGBOQuantum;
1110 Convert MIFF to RGB raster pixels.
1112 (void) TransformImageColorspace(image,sRGBColorspace,exception);
1113 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1114 (image->alpha_trait != BlendPixelTrait))
1115 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1116 quantum_info=AcquireQuantumInfo(image_info,image);
1117 if (quantum_info == (QuantumInfo *) NULL)
1118 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1119 pixels=GetQuantumPixels(quantum_info);
1120 switch (image_info->interlace)
1126 No interlacing: RGBRGBRGBRGBRGBRGB...
1128 for (y=0; y < (ssize_t) image->rows; y++)
1130 register const Quantum
1133 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1134 if (p == (const Quantum *) NULL)
1136 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1137 quantum_type,pixels,exception);
1138 count=WriteBlob(image,length,pixels);
1139 if (count != (ssize_t) length)
1141 if (image->previous == (Image *) NULL)
1143 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1145 if (status == MagickFalse)
1154 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1156 for (y=0; y < (ssize_t) image->rows; y++)
1158 register const Quantum
1161 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1162 if (p == (const Quantum *) NULL)
1164 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1165 RedQuantum,pixels,exception);
1166 count=WriteBlob(image,length,pixels);
1167 if (count != (ssize_t) length)
1169 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1170 GreenQuantum,pixels,exception);
1171 count=WriteBlob(image,length,pixels);
1172 if (count != (ssize_t) length)
1174 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1175 BlueQuantum,pixels,exception);
1176 count=WriteBlob(image,length,pixels);
1177 if (count != (ssize_t) length)
1179 if (quantum_type == RGBAQuantum)
1181 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1182 AlphaQuantum,pixels,exception);
1183 count=WriteBlob(image,length,pixels);
1184 if (count != (ssize_t) length)
1187 if (quantum_type == RGBOQuantum)
1189 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1190 OpacityQuantum,pixels,exception);
1191 count=WriteBlob(image,length,pixels);
1192 if (count != (ssize_t) length)
1195 if (image->previous == (Image *) NULL)
1197 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1199 if (status == MagickFalse)
1205 case PlaneInterlace:
1208 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1210 for (y=0; y < (ssize_t) image->rows; y++)
1212 register const Quantum
1215 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1216 if (p == (const Quantum *) NULL)
1218 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1219 RedQuantum,pixels,exception);
1220 count=WriteBlob(image,length,pixels);
1221 if (count != (ssize_t) length)
1224 if (image->previous == (Image *) NULL)
1226 status=SetImageProgress(image,SaveImageTag,1,6);
1227 if (status == MagickFalse)
1230 for (y=0; y < (ssize_t) image->rows; y++)
1232 register const Quantum
1235 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1236 if (p == (const Quantum *) NULL)
1238 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1239 GreenQuantum,pixels,exception);
1240 count=WriteBlob(image,length,pixels);
1241 if (count != (ssize_t) length)
1244 if (image->previous == (Image *) NULL)
1246 status=SetImageProgress(image,SaveImageTag,2,6);
1247 if (status == MagickFalse)
1250 for (y=0; y < (ssize_t) image->rows; y++)
1252 register const Quantum
1255 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1256 if (p == (const Quantum *) NULL)
1258 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1259 BlueQuantum,pixels,exception);
1260 count=WriteBlob(image,length,pixels);
1261 if (count != (ssize_t) length)
1264 if (image->previous == (Image *) NULL)
1266 status=SetImageProgress(image,SaveImageTag,3,6);
1267 if (status == MagickFalse)
1270 if (quantum_type == RGBAQuantum)
1272 for (y=0; y < (ssize_t) image->rows; y++)
1274 register const Quantum
1277 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1278 if (p == (const Quantum *) NULL)
1280 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1281 AlphaQuantum,pixels,exception);
1282 count=WriteBlob(image,length,pixels);
1283 if (count != (ssize_t) length)
1286 if (image->previous == (Image *) NULL)
1288 status=SetImageProgress(image,SaveImageTag,5,6);
1289 if (status == MagickFalse)
1293 if (image_info->interlace == PartitionInterlace)
1294 (void) CopyMagickString(image->filename,image_info->filename,
1296 if (image->previous == (Image *) NULL)
1298 status=SetImageProgress(image,SaveImageTag,6,6);
1299 if (status == MagickFalse)
1304 case PartitionInterlace:
1307 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1309 AppendImageFormat("R",image->filename);
1310 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1311 AppendBinaryBlobMode,exception);
1312 if (status == MagickFalse)
1314 for (y=0; y < (ssize_t) image->rows; y++)
1316 register const Quantum
1319 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1320 if (p == (const Quantum *) NULL)
1322 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1323 RedQuantum,pixels,exception);
1324 count=WriteBlob(image,length,pixels);
1325 if (count != (ssize_t) length)
1328 if (image->previous == (Image *) NULL)
1330 status=SetImageProgress(image,SaveImageTag,1,6);
1331 if (status == MagickFalse)
1334 (void) CloseBlob(image);
1335 AppendImageFormat("G",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 GreenQuantum,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,2,6);
1357 if (status == MagickFalse)
1360 (void) CloseBlob(image);
1361 AppendImageFormat("B",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 BlueQuantum,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,3,6);
1383 if (status == MagickFalse)
1386 if (quantum_type == RGBAQuantum)
1388 (void) CloseBlob(image);
1389 AppendImageFormat("A",image->filename);
1390 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1391 AppendBinaryBlobMode,exception);
1392 if (status == MagickFalse)
1394 for (y=0; y < (ssize_t) image->rows; y++)
1396 register const Quantum
1399 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1400 if (p == (const Quantum *) NULL)
1402 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1403 AlphaQuantum,pixels,exception);
1404 count=WriteBlob(image,length,pixels);
1405 if (count != (ssize_t) length)
1408 if (image->previous == (Image *) NULL)
1410 status=SetImageProgress(image,SaveImageTag,5,6);
1411 if (status == MagickFalse)
1415 (void) CloseBlob(image);
1416 (void) CopyMagickString(image->filename,image_info->filename,
1418 if (image->previous == (Image *) NULL)
1420 status=SetImageProgress(image,SaveImageTag,6,6);
1421 if (status == MagickFalse)
1427 quantum_info=DestroyQuantumInfo(quantum_info);
1428 if (GetNextImageInList(image) == (Image *) NULL)
1430 image=SyncNextImageInList(image);
1431 status=SetImageProgress(image,SaveImagesTag,scene++,
1432 GetImageListLength(image));
1433 if (status == MagickFalse)
1435 } while (image_info->adjoin != MagickFalse);
1436 (void) CloseBlob(image);