2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw RGB Image Format %
20 % Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/colorspace.h"
47 #include "MagickCore/colorspace-private.h"
48 #include "MagickCore/constitute.h"
49 #include "MagickCore/exception.h"
50 #include "MagickCore/exception-private.h"
51 #include "MagickCore/image.h"
52 #include "MagickCore/image-private.h"
53 #include "MagickCore/list.h"
54 #include "MagickCore/magick.h"
55 #include "MagickCore/memory_.h"
56 #include "MagickCore/monitor.h"
57 #include "MagickCore/monitor-private.h"
58 #include "MagickCore/pixel-accessor.h"
59 #include "MagickCore/quantum-private.h"
60 #include "MagickCore/static.h"
61 #include "MagickCore/statistic.h"
62 #include "MagickCore/string_.h"
63 #include "MagickCore/module.h"
64 #include "MagickCore/utility.h"
69 static MagickBooleanType
70 WriteRGBImage(const ImageInfo *,Image *,ExceptionInfo *);
73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 % R e a d R G B I m a g e %
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 % ReadRGBImage() reads an image of raw RGB, RGBA, or RGBO samples and returns
84 % it. It allocates the memory necessary for the new Image structure and
85 % returns a pointer to the new image.
87 % The format of the ReadRGBImage method is:
89 % Image *ReadRGBImage(const ImageInfo *image_info,
90 % ExceptionInfo *exception)
92 % A description of each parameter follows:
94 % o image_info: the image info.
96 % o exception: return any errors or warnings in this structure.
99 static Image *ReadRGBImage(const ImageInfo *image_info,
100 ExceptionInfo *exception)
134 assert(image_info != (const ImageInfo *) NULL);
135 assert(image_info->signature == MagickSignature);
136 if (image_info->debug != MagickFalse)
137 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
138 image_info->filename);
139 assert(exception != (ExceptionInfo *) NULL);
140 assert(exception->signature == MagickSignature);
141 image=AcquireImage(image_info,exception);
142 if ((image->columns == 0) || (image->rows == 0))
143 ThrowReaderException(OptionError,"MustSpecifyImageSize");
144 image->colorspace=RGBColorspace;
145 if (image_info->interlace != PartitionInterlace)
147 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
148 if (status == MagickFalse)
150 image=DestroyImageList(image);
151 return((Image *) NULL);
153 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
154 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
158 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
160 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
162 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod);
163 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
164 if (quantum_info == (QuantumInfo *) NULL)
165 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
166 pixels=GetQuantumPixels(quantum_info);
167 quantum_type=RGBQuantum;
168 if (LocaleCompare(image_info->magick,"RGBA") == 0)
170 quantum_type=RGBAQuantum;
171 image->matte=MagickTrue;
173 if (LocaleCompare(image_info->magick,"RGBO") == 0)
175 quantum_type=RGBOQuantum;
176 image->matte=MagickTrue;
178 if (image_info->number_scenes != 0)
179 while (image->scene < image_info->scene)
185 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
186 for (y=0; y < (ssize_t) image->rows; y++)
188 count=ReadBlob(image,length,pixels);
189 if (count != (ssize_t) length)
199 Read pixels to virtual canvas image then push to image.
201 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
202 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
204 image->colorspace=RGBColorspace;
205 switch (image_info->interlace)
211 No interlacing: RGBRGBRGBRGBRGBRGB...
215 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
216 count=ReadBlob(image,length,pixels);
218 for (y=0; y < (ssize_t) image->extract_info.height; y++)
220 register const Quantum
229 if (count != (ssize_t) length)
231 ThrowFileException(exception,CorruptImageError,
232 "UnexpectedEndOfFile",image->filename);
235 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
237 if (q == (Quantum *) NULL)
239 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
240 quantum_info,quantum_type,pixels,exception);
241 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
243 if (((y-image->extract_info.y) >= 0) &&
244 ((y-image->extract_info.y) < (ssize_t) image->rows))
246 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
247 canvas_image->columns,1,exception);
248 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
249 image->columns,1,exception);
250 if ((p == (const Quantum *) NULL) ||
251 (q == (Quantum *) NULL))
253 for (x=0; x < (ssize_t) image->columns; x++)
255 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
256 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
257 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
258 SetPixelAlpha(image,OpaqueAlpha,q);
259 if (image->matte != MagickFalse)
260 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
261 p+=GetPixelChannels(canvas_image);
262 q+=GetPixelChannels(image);
264 if (SyncAuthenticPixels(image,exception) == MagickFalse)
267 if (image->previous == (Image *) NULL)
269 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
271 if (status == MagickFalse)
274 count=ReadBlob(image,length,pixels);
290 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
292 if (LocaleCompare(image_info->magick,"RGBO") == 0)
293 quantum_types[3]=OpacityQuantum;
296 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
297 count=ReadBlob(image,length,pixels);
299 for (y=0; y < (ssize_t) image->extract_info.height; y++)
301 register const Quantum
310 if (count != (ssize_t) length)
312 ThrowFileException(exception,CorruptImageError,
313 "UnexpectedEndOfFile",image->filename);
316 for (i=0; i < (ssize_t) (image->matte != MagickFalse ? 4 : 3); i++)
318 quantum_type=quantum_types[i];
319 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
321 if (q == (Quantum *) NULL)
323 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
324 quantum_info,quantum_type,pixels,exception);
325 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
327 if (((y-image->extract_info.y) >= 0) &&
328 ((y-image->extract_info.y) < (ssize_t) image->rows))
330 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
331 0,canvas_image->columns,1,exception);
332 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
333 image->columns,1,exception);
334 if ((p == (const Quantum *) NULL) ||
335 (q == (Quantum *) NULL))
337 for (x=0; x < (ssize_t) image->columns; x++)
339 switch (quantum_type)
343 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
348 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
353 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
358 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
363 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
369 p+=GetPixelChannels(canvas_image);
370 q+=GetPixelChannels(image);
372 if (SyncAuthenticPixels(image,exception) == MagickFalse)
375 count=ReadBlob(image,length,pixels);
377 if (image->previous == (Image *) NULL)
379 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
381 if (status == MagickFalse)
390 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
394 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
395 count=ReadBlob(image,length,pixels);
397 for (y=0; y < (ssize_t) image->extract_info.height; y++)
399 register const Quantum
408 if (count != (ssize_t) length)
410 ThrowFileException(exception,CorruptImageError,
411 "UnexpectedEndOfFile",image->filename);
414 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
416 if (q == (Quantum *) NULL)
418 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
419 quantum_info,RedQuantum,pixels,exception);
420 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
422 if (((y-image->extract_info.y) >= 0) &&
423 ((y-image->extract_info.y) < (ssize_t) image->rows))
425 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
426 canvas_image->columns,1,exception);
427 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
428 image->columns,1,exception);
429 if ((p == (const Quantum *) NULL) ||
430 (q == (Quantum *) NULL))
432 for (x=0; x < (ssize_t) image->columns; x++)
434 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
435 p+=GetPixelChannels(canvas_image);
436 q+=GetPixelChannels(image);
438 if (SyncAuthenticPixels(image,exception) == MagickFalse)
441 count=ReadBlob(image,length,pixels);
443 if (image->previous == (Image *) NULL)
445 status=SetImageProgress(image,LoadImageTag,1,6);
446 if (status == MagickFalse)
449 for (y=0; y < (ssize_t) image->extract_info.height; y++)
451 register const Quantum
460 if (count != (ssize_t) length)
462 ThrowFileException(exception,CorruptImageError,
463 "UnexpectedEndOfFile",image->filename);
466 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
468 if (q == (Quantum *) NULL)
470 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
471 quantum_info,GreenQuantum,pixels,exception);
472 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
474 if (((y-image->extract_info.y) >= 0) &&
475 ((y-image->extract_info.y) < (ssize_t) image->rows))
477 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
478 canvas_image->columns,1,exception);
479 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
480 image->columns,1,exception);
481 if ((p == (const Quantum *) NULL) ||
482 (q == (Quantum *) NULL))
484 for (x=0; x < (ssize_t) image->columns; x++)
486 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
487 p+=GetPixelChannels(canvas_image);
488 q+=GetPixelChannels(image);
490 if (SyncAuthenticPixels(image,exception) == MagickFalse)
493 count=ReadBlob(image,length,pixels);
495 if (image->previous == (Image *) NULL)
497 status=SetImageProgress(image,LoadImageTag,2,6);
498 if (status == MagickFalse)
501 for (y=0; y < (ssize_t) image->extract_info.height; y++)
503 register const Quantum
512 if (count != (ssize_t) length)
514 ThrowFileException(exception,CorruptImageError,
515 "UnexpectedEndOfFile",image->filename);
518 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
520 if (q == (Quantum *) NULL)
522 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
523 quantum_info,BlueQuantum,pixels,exception);
524 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
526 if (((y-image->extract_info.y) >= 0) &&
527 ((y-image->extract_info.y) < (ssize_t) image->rows))
529 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
530 canvas_image->columns,1,exception);
531 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
532 image->columns,1,exception);
533 if ((p == (const Quantum *) NULL) ||
534 (q == (Quantum *) NULL))
536 for (x=0; x < (ssize_t) image->columns; x++)
538 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
539 p+=GetPixelChannels(canvas_image);
540 q+=GetPixelChannels(image);
542 if (SyncAuthenticPixels(image,exception) == MagickFalse)
545 count=ReadBlob(image,length,pixels);
547 if (image->previous == (Image *) NULL)
549 status=SetImageProgress(image,LoadImageTag,3,6);
550 if (status == MagickFalse)
553 if (image->previous == (Image *) NULL)
555 status=SetImageProgress(image,LoadImageTag,4,6);
556 if (status == MagickFalse)
559 if (image->matte != MagickFalse)
561 for (y=0; y < (ssize_t) image->extract_info.height; y++)
563 register const Quantum
572 if (count != (ssize_t) length)
574 ThrowFileException(exception,CorruptImageError,
575 "UnexpectedEndOfFile",image->filename);
578 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
580 if (q == (Quantum *) NULL)
582 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
583 quantum_info,AlphaQuantum,pixels,exception);
584 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
586 if (((y-image->extract_info.y) >= 0) &&
587 ((y-image->extract_info.y) < (ssize_t) image->rows))
589 p=GetVirtualPixels(canvas_image,
590 canvas_image->extract_info.x,0,canvas_image->columns,1,
592 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
593 image->columns,1,exception);
594 if ((p == (const Quantum *) NULL) ||
595 (q == (Quantum *) NULL))
597 for (x=0; x < (ssize_t) image->columns; x++)
599 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
600 p+=GetPixelChannels(canvas_image);
601 q+=GetPixelChannels(image);
603 if (SyncAuthenticPixels(image,exception) == MagickFalse)
606 count=ReadBlob(image,length,pixels);
608 if (image->previous == (Image *) NULL)
610 status=SetImageProgress(image,LoadImageTag,5,6);
611 if (status == MagickFalse)
615 if (image->previous == (Image *) NULL)
617 status=SetImageProgress(image,LoadImageTag,6,6);
618 if (status == MagickFalse)
623 case PartitionInterlace:
626 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
628 AppendImageFormat("R",image->filename);
629 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
630 if (status == MagickFalse)
632 canvas_image=DestroyImageList(canvas_image);
633 image=DestroyImageList(image);
634 return((Image *) NULL);
636 if (DiscardBlobBytes(image,image->offset) == MagickFalse)
637 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
639 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
640 for (i=0; i < (ssize_t) scene; i++)
641 for (y=0; y < (ssize_t) image->extract_info.height; y++)
642 if (ReadBlob(image,length,pixels) != (ssize_t) length)
644 ThrowFileException(exception,CorruptImageError,
645 "UnexpectedEndOfFile",image->filename);
648 count=ReadBlob(image,length,pixels);
649 for (y=0; y < (ssize_t) image->extract_info.height; y++)
651 register const Quantum
660 if (count != (ssize_t) length)
662 ThrowFileException(exception,CorruptImageError,
663 "UnexpectedEndOfFile",image->filename);
666 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
668 if (q == (Quantum *) NULL)
670 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
671 quantum_info,RedQuantum,pixels,exception);
672 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
674 if (((y-image->extract_info.y) >= 0) &&
675 ((y-image->extract_info.y) < (ssize_t) image->rows))
677 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
678 canvas_image->columns,1,exception);
679 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
680 image->columns,1,exception);
681 if ((p == (const Quantum *) NULL) ||
682 (q == (Quantum *) NULL))
684 for (x=0; x < (ssize_t) image->columns; x++)
686 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
687 p+=GetPixelChannels(canvas_image);
688 q+=GetPixelChannels(image);
690 if (SyncAuthenticPixels(image,exception) == MagickFalse)
693 count=ReadBlob(image,length,pixels);
695 if (image->previous == (Image *) NULL)
697 status=SetImageProgress(image,LoadImageTag,1,5);
698 if (status == MagickFalse)
701 (void) CloseBlob(image);
702 AppendImageFormat("G",image->filename);
703 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
704 if (status == MagickFalse)
706 canvas_image=DestroyImageList(canvas_image);
707 image=DestroyImageList(image);
708 return((Image *) NULL);
710 length=GetQuantumExtent(canvas_image,quantum_info,GreenQuantum);
711 for (i=0; i < (ssize_t) scene; i++)
712 for (y=0; y < (ssize_t) image->extract_info.height; y++)
713 if (ReadBlob(image,length,pixels) != (ssize_t) length)
715 ThrowFileException(exception,CorruptImageError,
716 "UnexpectedEndOfFile",image->filename);
719 count=ReadBlob(image,length,pixels);
720 for (y=0; y < (ssize_t) image->extract_info.height; y++)
722 register const Quantum
731 if (count != (ssize_t) length)
733 ThrowFileException(exception,CorruptImageError,
734 "UnexpectedEndOfFile",image->filename);
737 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
739 if (q == (Quantum *) NULL)
741 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
742 quantum_info,GreenQuantum,pixels,exception);
743 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
745 if (((y-image->extract_info.y) >= 0) &&
746 ((y-image->extract_info.y) < (ssize_t) image->rows))
748 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
749 canvas_image->columns,1,exception);
750 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
751 image->columns,1,exception);
752 if ((p == (const Quantum *) NULL) ||
753 (q == (Quantum *) NULL))
755 for (x=0; x < (ssize_t) image->columns; x++)
757 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
758 p+=GetPixelChannels(canvas_image);
759 q+=GetPixelChannels(image);
761 if (SyncAuthenticPixels(image,exception) == MagickFalse)
764 count=ReadBlob(image,length,pixels);
766 if (image->previous == (Image *) NULL)
768 status=SetImageProgress(image,LoadImageTag,2,5);
769 if (status == MagickFalse)
772 (void) CloseBlob(image);
773 AppendImageFormat("B",image->filename);
774 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
775 if (status == MagickFalse)
777 canvas_image=DestroyImageList(canvas_image);
778 image=DestroyImageList(image);
779 return((Image *) NULL);
781 length=GetQuantumExtent(canvas_image,quantum_info,BlueQuantum);
782 for (i=0; i < (ssize_t) scene; i++)
783 for (y=0; y < (ssize_t) image->extract_info.height; y++)
784 if (ReadBlob(image,length,pixels) != (ssize_t) length)
786 ThrowFileException(exception,CorruptImageError,
787 "UnexpectedEndOfFile",image->filename);
790 count=ReadBlob(image,length,pixels);
791 for (y=0; y < (ssize_t) image->extract_info.height; y++)
793 register const Quantum
802 if (count != (ssize_t) length)
804 ThrowFileException(exception,CorruptImageError,
805 "UnexpectedEndOfFile",image->filename);
808 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
810 if (q == (Quantum *) NULL)
812 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
813 quantum_info,BlueQuantum,pixels,exception);
814 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
816 if (((y-image->extract_info.y) >= 0) &&
817 ((y-image->extract_info.y) < (ssize_t) image->rows))
819 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
820 canvas_image->columns,1,exception);
821 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
822 image->columns,1,exception);
823 if ((p == (const Quantum *) NULL) ||
824 (q == (Quantum *) NULL))
826 for (x=0; x < (ssize_t) image->columns; x++)
828 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
829 p+=GetPixelChannels(canvas_image);
830 q+=GetPixelChannels(image);
832 if (SyncAuthenticPixels(image,exception) == MagickFalse)
835 count=ReadBlob(image,length,pixels);
837 if (image->previous == (Image *) NULL)
839 status=SetImageProgress(image,LoadImageTag,3,5);
840 if (status == MagickFalse)
843 if (image->matte != MagickFalse)
845 (void) CloseBlob(image);
846 AppendImageFormat("A",image->filename);
847 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
848 if (status == MagickFalse)
850 canvas_image=DestroyImageList(canvas_image);
851 image=DestroyImageList(image);
852 return((Image *) NULL);
854 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
855 for (i=0; i < (ssize_t) scene; i++)
856 for (y=0; y < (ssize_t) image->extract_info.height; y++)
857 if (ReadBlob(image,length,pixels) != (ssize_t) length)
859 ThrowFileException(exception,CorruptImageError,
860 "UnexpectedEndOfFile",image->filename);
863 count=ReadBlob(image,length,pixels);
864 for (y=0; y < (ssize_t) image->extract_info.height; y++)
866 register const Quantum
875 if (count != (ssize_t) length)
877 ThrowFileException(exception,CorruptImageError,
878 "UnexpectedEndOfFile",image->filename);
881 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
883 if (q == (Quantum *) NULL)
885 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
886 quantum_info,BlueQuantum,pixels,exception);
887 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
889 if (((y-image->extract_info.y) >= 0) &&
890 ((y-image->extract_info.y) < (ssize_t) image->rows))
892 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
893 0,canvas_image->columns,1,exception);
894 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
895 image->columns,1,exception);
896 if ((p == (const Quantum *) NULL) ||
897 (q == (Quantum *) NULL))
899 for (x=0; x < (ssize_t) image->columns; x++)
901 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
902 p+=GetPixelChannels(canvas_image);
903 q+=GetPixelChannels(image);
905 if (SyncAuthenticPixels(image,exception) == MagickFalse)
908 count=ReadBlob(image,length,pixels);
910 if (image->previous == (Image *) NULL)
912 status=SetImageProgress(image,LoadImageTag,4,5);
913 if (status == MagickFalse)
917 (void) CloseBlob(image);
918 if (image->previous == (Image *) NULL)
920 status=SetImageProgress(image,LoadImageTag,5,5);
921 if (status == MagickFalse)
927 SetQuantumImageType(image,quantum_type);
929 Proceed to next image.
931 if (image_info->number_scenes != 0)
932 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
934 if (count == (ssize_t) length)
937 Allocate next image structure.
939 AcquireNextImage(image_info,image,exception);
940 if (GetNextImageInList(image) == (Image *) NULL)
942 image=DestroyImageList(image);
943 return((Image *) NULL);
945 image=SyncNextImageInList(image);
946 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
948 if (status == MagickFalse)
952 } while (count == (ssize_t) length);
953 quantum_info=DestroyQuantumInfo(quantum_info);
954 canvas_image=DestroyImage(canvas_image);
955 (void) CloseBlob(image);
956 return(GetFirstImageInList(image));
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
964 % R e g i s t e r R G B I m a g e %
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
970 % RegisterRGBImage() adds attributes for the RGB image format to
971 % the list of supported formats. The attributes include the image format
972 % tag, a method to read and/or write the format, whether the format
973 % supports the saving of more than one frame to the same file or blob,
974 % whether the format supports native in-memory I/O, and a brief
975 % description of the format.
977 % The format of the RegisterRGBImage method is:
979 % size_t RegisterRGBImage(void)
982 ModuleExport size_t RegisterRGBImage(void)
987 entry=SetMagickInfo("RGB");
988 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
989 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
990 entry->raw=MagickTrue;
991 entry->endian_support=MagickTrue;
992 entry->description=ConstantString("Raw red, green, and blue samples");
993 entry->module=ConstantString("RGB");
994 (void) RegisterMagickInfo(entry);
995 entry=SetMagickInfo("RGBA");
996 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
997 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
998 entry->raw=MagickTrue;
999 entry->endian_support=MagickTrue;
1000 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
1001 entry->module=ConstantString("RGB");
1002 (void) RegisterMagickInfo(entry);
1003 entry=SetMagickInfo("RGBO");
1004 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
1005 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
1006 entry->raw=MagickTrue;
1007 entry->endian_support=MagickTrue;
1008 entry->description=ConstantString("Raw red, green, blue, and opacity samples");
1009 entry->module=ConstantString("RGB");
1010 (void) RegisterMagickInfo(entry);
1011 return(MagickImageCoderSignature);
1015 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1019 % U n r e g i s t e r R G B I m a g e %
1023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1025 % UnregisterRGBImage() removes format registrations made by the RGB module
1026 % from the list of supported formats.
1028 % The format of the UnregisterRGBImage method is:
1030 % UnregisterRGBImage(void)
1033 ModuleExport void UnregisterRGBImage(void)
1035 (void) UnregisterMagickInfo("RGBO");
1036 (void) UnregisterMagickInfo("RGBA");
1037 (void) UnregisterMagickInfo("RGB");
1041 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1045 % W r i t e R G B I m a g e %
1049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1051 % WriteRGBImage() writes an image to a file in the RGB, RGBA, or RGBO
1052 % rasterfile format.
1054 % The format of the WriteRGBImage method is:
1056 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1057 % Image *image,ExceptionInfo *exception)
1059 % A description of each parameter follows.
1061 % o image_info: the image info.
1063 % o image: The image.
1065 % o exception: return any errors or warnings in this structure.
1068 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,
1069 Image *image,ExceptionInfo *exception)
1094 Allocate memory for pixels.
1096 assert(image_info != (const ImageInfo *) NULL);
1097 assert(image_info->signature == MagickSignature);
1098 assert(image != (Image *) NULL);
1099 assert(image->signature == MagickSignature);
1100 if (image->debug != MagickFalse)
1101 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1102 if (image_info->interlace != PartitionInterlace)
1105 Open output image file.
1107 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
1108 if (status == MagickFalse)
1111 quantum_type=RGBQuantum;
1112 if (LocaleCompare(image_info->magick,"RGBA") == 0)
1114 quantum_type=RGBAQuantum;
1115 if (image->matte == MagickFalse)
1116 SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1118 if (LocaleCompare(image_info->magick,"RGBO") == 0)
1120 quantum_type=RGBOQuantum;
1121 if (image->matte == MagickFalse)
1122 SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1128 Convert MIFF to RGB raster pixels.
1130 if (IsRGBColorspace(image->colorspace) == MagickFalse)
1131 (void) TransformImageColorspace(image,RGBColorspace,exception);
1132 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
1133 (image->matte == MagickFalse))
1134 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
1135 quantum_info=AcquireQuantumInfo(image_info,image);
1136 if (quantum_info == (QuantumInfo *) NULL)
1137 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1138 pixels=GetQuantumPixels(quantum_info);
1139 switch (image_info->interlace)
1145 No interlacing: RGBRGBRGBRGBRGBRGB...
1147 for (y=0; y < (ssize_t) image->rows; y++)
1149 register const Quantum
1152 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1153 if (p == (const Quantum *) NULL)
1155 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1156 quantum_type,pixels,exception);
1157 count=WriteBlob(image,length,pixels);
1158 if (count != (ssize_t) length)
1160 if (image->previous == (Image *) NULL)
1162 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1164 if (status == MagickFalse)
1173 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
1175 for (y=0; y < (ssize_t) image->rows; y++)
1177 register const Quantum
1180 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1181 if (p == (const Quantum *) NULL)
1183 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1184 RedQuantum,pixels,exception);
1185 count=WriteBlob(image,length,pixels);
1186 if (count != (ssize_t) length)
1188 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1189 GreenQuantum,pixels,exception);
1190 count=WriteBlob(image,length,pixels);
1191 if (count != (ssize_t) length)
1193 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1194 BlueQuantum,pixels,exception);
1195 count=WriteBlob(image,length,pixels);
1196 if (count != (ssize_t) length)
1198 if (quantum_type == RGBAQuantum)
1200 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1201 AlphaQuantum,pixels,exception);
1202 count=WriteBlob(image,length,pixels);
1203 if (count != (ssize_t) length)
1206 if (quantum_type == RGBOQuantum)
1208 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1209 OpacityQuantum,pixels,exception);
1210 count=WriteBlob(image,length,pixels);
1211 if (count != (ssize_t) length)
1214 if (image->previous == (Image *) NULL)
1216 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
1218 if (status == MagickFalse)
1224 case PlaneInterlace:
1227 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
1229 for (y=0; y < (ssize_t) image->rows; y++)
1231 register const Quantum
1234 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1235 if (p == (const Quantum *) NULL)
1237 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1238 RedQuantum,pixels,exception);
1239 count=WriteBlob(image,length,pixels);
1240 if (count != (ssize_t) length)
1243 if (image->previous == (Image *) NULL)
1245 status=SetImageProgress(image,SaveImageTag,1,6);
1246 if (status == MagickFalse)
1249 for (y=0; y < (ssize_t) image->rows; y++)
1251 register const Quantum
1254 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1255 if (p == (const Quantum *) NULL)
1257 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1258 GreenQuantum,pixels,exception);
1259 count=WriteBlob(image,length,pixels);
1260 if (count != (ssize_t) length)
1263 if (image->previous == (Image *) NULL)
1265 status=SetImageProgress(image,SaveImageTag,2,6);
1266 if (status == MagickFalse)
1269 for (y=0; y < (ssize_t) image->rows; y++)
1271 register const Quantum
1274 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1275 if (p == (const Quantum *) NULL)
1277 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1278 BlueQuantum,pixels,exception);
1279 count=WriteBlob(image,length,pixels);
1280 if (count != (ssize_t) length)
1283 if (image->previous == (Image *) NULL)
1285 status=SetImageProgress(image,SaveImageTag,3,6);
1286 if (status == MagickFalse)
1289 if (quantum_type == RGBAQuantum)
1291 for (y=0; y < (ssize_t) image->rows; y++)
1293 register const Quantum
1296 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1297 if (p == (const Quantum *) NULL)
1299 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1300 AlphaQuantum,pixels,exception);
1301 count=WriteBlob(image,length,pixels);
1302 if (count != (ssize_t) length)
1305 if (image->previous == (Image *) NULL)
1307 status=SetImageProgress(image,SaveImageTag,5,6);
1308 if (status == MagickFalse)
1312 if (image_info->interlace == PartitionInterlace)
1313 (void) CopyMagickString(image->filename,image_info->filename,
1315 if (image->previous == (Image *) NULL)
1317 status=SetImageProgress(image,SaveImageTag,6,6);
1318 if (status == MagickFalse)
1323 case PartitionInterlace:
1326 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1328 AppendImageFormat("R",image->filename);
1329 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1330 AppendBinaryBlobMode,exception);
1331 if (status == MagickFalse)
1333 for (y=0; y < (ssize_t) image->rows; y++)
1335 register const Quantum
1338 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1339 if (p == (const Quantum *) NULL)
1341 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1342 RedQuantum,pixels,exception);
1343 count=WriteBlob(image,length,pixels);
1344 if (count != (ssize_t) length)
1347 if (image->previous == (Image *) NULL)
1349 status=SetImageProgress(image,SaveImageTag,1,6);
1350 if (status == MagickFalse)
1353 (void) CloseBlob(image);
1354 AppendImageFormat("G",image->filename);
1355 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1356 AppendBinaryBlobMode,exception);
1357 if (status == MagickFalse)
1359 for (y=0; y < (ssize_t) image->rows; y++)
1361 register const Quantum
1364 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1365 if (p == (const Quantum *) NULL)
1367 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1368 GreenQuantum,pixels,exception);
1369 count=WriteBlob(image,length,pixels);
1370 if (count != (ssize_t) length)
1373 if (image->previous == (Image *) NULL)
1375 status=SetImageProgress(image,SaveImageTag,2,6);
1376 if (status == MagickFalse)
1379 (void) CloseBlob(image);
1380 AppendImageFormat("B",image->filename);
1381 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1382 AppendBinaryBlobMode,exception);
1383 if (status == MagickFalse)
1385 for (y=0; y < (ssize_t) image->rows; y++)
1387 register const Quantum
1390 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1391 if (p == (const Quantum *) NULL)
1393 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1394 BlueQuantum,pixels,exception);
1395 count=WriteBlob(image,length,pixels);
1396 if (count != (ssize_t) length)
1399 if (image->previous == (Image *) NULL)
1401 status=SetImageProgress(image,SaveImageTag,3,6);
1402 if (status == MagickFalse)
1405 (void) CloseBlob(image);
1406 if (quantum_type == RGBAQuantum)
1408 (void) CloseBlob(image);
1409 AppendImageFormat("A",image->filename);
1410 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1411 AppendBinaryBlobMode,exception);
1412 if (status == MagickFalse)
1414 for (y=0; y < (ssize_t) image->rows; y++)
1416 register const Quantum
1419 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1420 if (p == (const Quantum *) NULL)
1422 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1423 AlphaQuantum,pixels,exception);
1424 count=WriteBlob(image,length,pixels);
1425 if (count != (ssize_t) length)
1428 if (image->previous == (Image *) NULL)
1430 status=SetImageProgress(image,SaveImageTag,5,6);
1431 if (status == MagickFalse)
1435 (void) CloseBlob(image);
1436 (void) CopyMagickString(image->filename,image_info->filename,
1438 if (image->previous == (Image *) NULL)
1440 status=SetImageProgress(image,SaveImageTag,6,6);
1441 if (status == MagickFalse)
1447 quantum_info=DestroyQuantumInfo(quantum_info);
1448 if (GetNextImageInList(image) == (Image *) NULL)
1450 image=SyncNextImageInList(image);
1451 status=SetImageProgress(image,SaveImagesTag,scene++,
1452 GetImageListLength(image));
1453 if (status == MagickFalse)
1455 } while (image_info->adjoin != MagickFalse);
1456 (void) CloseBlob(image);