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 "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/cache.h"
46 #include "magick/colorspace.h"
47 #include "magick/constitute.h"
48 #include "magick/exception.h"
49 #include "magick/exception-private.h"
50 #include "magick/image.h"
51 #include "magick/image-private.h"
52 #include "magick/list.h"
53 #include "magick/magick.h"
54 #include "magick/memory_.h"
55 #include "magick/monitor.h"
56 #include "magick/monitor-private.h"
57 #include "magick/pixel-private.h"
58 #include "magick/quantum-private.h"
59 #include "magick/static.h"
60 #include "magick/statistic.h"
61 #include "magick/string_.h"
62 #include "magick/module.h"
63 #include "magick/utility.h"
68 static MagickBooleanType
69 WriteRGBImage(const ImageInfo *,Image *);
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 % R e a d R G B I m a g e %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 % ReadRGBImage() reads an image of raw RGB or RGBA samples and returns it. It
83 % allocates the memory necessary for the new Image structure and returns a
84 % pointer to the new image.
86 % The format of the ReadRGBImage method is:
88 % Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
90 % A description of each parameter follows:
92 % o image_info: the image info.
94 % o exception: return any errors or warnings in this structure.
97 static Image *ReadRGBImage(const ImageInfo *image_info,ExceptionInfo *exception)
146 assert(image_info != (const ImageInfo *) NULL);
147 assert(image_info->signature == MagickSignature);
148 if (image_info->debug != MagickFalse)
149 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
150 image_info->filename);
151 assert(exception != (ExceptionInfo *) NULL);
152 assert(exception->signature == MagickSignature);
153 image=AcquireImage(image_info);
154 if ((image->columns == 0) || (image->rows == 0))
155 ThrowReaderException(OptionError,"MustSpecifyImageSize");
156 if (image_info->interlace != PartitionInterlace)
158 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
159 if (status == MagickFalse)
161 image=DestroyImageList(image);
162 return((Image *) NULL);
164 for (i=0; i < image->offset; i++)
165 if (ReadBlobByte(image) == EOF)
167 ThrowFileException(exception,CorruptImageError,
168 "UnexpectedEndOfFile",image->filename);
173 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
175 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
177 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod);
178 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
179 if (quantum_info == (QuantumInfo *) NULL)
180 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
181 pixels=GetQuantumPixels(quantum_info);
182 quantum_type=RGBQuantum;
183 if (LocaleCompare(image_info->magick,"RGBA") == 0)
185 quantum_type=RGBAQuantum;
186 image->matte=MagickTrue;
189 else if (LocaleCompare(image_info->magick,"BGRA") == 0)
191 quantum_type=BGRAQuantum;
192 image->matte=MagickTrue;
195 else if (LocaleCompare(image_info->magick,"RGBO") == 0)
197 quantum_type=RGBOQuantum;
198 image->matte=MagickTrue;
201 if (image_info->number_scenes != 0)
202 while (image->scene < image_info->scene)
208 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
209 for (y=0; y < (ssize_t) image->rows; y++)
211 count=ReadBlob(image,length,pixels);
212 if (count != (ssize_t) length)
216 for (i=0; i < channels; i++)
218 switch(image_info->magick[i])
220 case 'R': quantum_types[i]=RedQuantum; break;
221 case 'G': quantum_types[i]=GreenQuantum; break;
222 case 'B': quantum_types[i]=BlueQuantum; break;
223 case 'A': quantum_types[i]=AlphaQuantum; break;
224 case 'O': quantum_types[i]=OpacityQuantum; break;
233 Read pixels to virtual canvas image then push to image.
235 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
236 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
238 switch (image_info->interlace)
244 No interlacing: RGBRGBRGBRGBRGBRGB...
248 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
249 count=ReadBlob(image,length,pixels);
250 if (count != (ssize_t) length)
253 for (y=0; y < (ssize_t) image->extract_info.height; y++)
255 register const PixelPacket
264 if (count != (ssize_t) length)
266 ThrowFileException(exception,CorruptImageError,
267 "UnexpectedEndOfFile",image->filename);
270 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
272 if (q == (PixelPacket *) NULL)
274 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
275 quantum_info,quantum_type,pixels,exception);
276 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
278 if (((y-image->extract_info.y) >= 0) &&
279 ((y-image->extract_info.y) < (ssize_t) image->rows))
281 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
282 canvas_image->columns,1,exception);
283 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
284 image->columns,1,exception);
285 if ((p == (const PixelPacket *) NULL) ||
286 (q == (PixelPacket *) NULL))
288 for (x=0; x < (ssize_t) image->columns; x++)
290 qx[0]=GetRedPixelComponent(p);
291 qx[1]=GetGreenPixelComponent(p);
292 qx[2]=GetBluePixelComponent(p);
293 for (i=0; i < 3; i++)
294 switch(quantum_types[i])
296 case RedQuantum: q->red=qx[i]; break;
297 case GreenQuantum: q->green=qx[i]; break;
298 case BlueQuantum: q->blue=qx[i]; break;
301 SetOpacityPixelComponent(q,OpaqueOpacity);
302 if (image->matte != MagickFalse)
303 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
307 if (SyncAuthenticPixels(image,exception) == MagickFalse)
310 if (image->previous == (Image *) NULL)
312 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
314 if (status == MagickFalse)
317 count=ReadBlob(image,length,pixels);
324 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
328 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
329 count=ReadBlob(image,length,pixels);
331 for (y=0; y < (ssize_t) image->extract_info.height; y++)
333 register const PixelPacket
342 if (count != (ssize_t) length)
344 ThrowFileException(exception,CorruptImageError,
345 "UnexpectedEndOfFile",image->filename);
348 for (i=0; i < channels; i++)
350 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
352 if (q == (PixelPacket *) NULL)
354 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
355 quantum_info,quantum_types[i],pixels,exception);
356 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
358 if (((y-image->extract_info.y) >= 0) &&
359 ((y-image->extract_info.y) < (ssize_t) image->rows))
361 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
362 0,canvas_image->columns,1,exception);
363 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
364 image->columns,1,exception);
365 if ((p == (const PixelPacket *) NULL) ||
366 (q == (PixelPacket *) NULL))
368 if (i == (channels - 1))
369 for (x=0; x < (ssize_t) image->columns; x++)
371 SetRedPixelComponent(q,GetRedPixelComponent(p));
372 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
373 SetBluePixelComponent(q,GetBluePixelComponent(p));
374 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
378 if (SyncAuthenticPixels(image,exception) == MagickFalse)
381 count=ReadBlob(image,length,pixels);
383 if (image->previous == (Image *) NULL)
385 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
387 if (status == MagickFalse)
396 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
400 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
401 count=ReadBlob(image,length,pixels);
403 for (i=0; i < channels; i++)
405 for (y=0; y < (ssize_t) image->extract_info.height; y++)
407 register const PixelPacket
416 if (count != (ssize_t) length)
418 ThrowFileException(exception,CorruptImageError,
419 "UnexpectedEndOfFile",image->filename);
422 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
424 if (q == (PixelPacket *) NULL)
426 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
427 quantum_info,quantum_types[i],pixels,exception);
428 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
430 if (((y-image->extract_info.y) >= 0) &&
431 ((y-image->extract_info.y) < (ssize_t) image->rows))
433 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
434 canvas_image->columns,1,exception);
435 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
436 image->columns,1,exception);
437 if ((p == (const PixelPacket *) NULL) ||
438 (q == (PixelPacket *) NULL))
440 for (x=0; x < (ssize_t) image->columns; x++)
442 switch(quantum_types[i])
446 SetRedPixelComponent(q,GetRedPixelComponent(p));
451 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
456 SetBluePixelComponent(q,GetBluePixelComponent(p));
462 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
471 if (SyncAuthenticPixels(image,exception) == MagickFalse)
474 count=ReadBlob(image,length,pixels);
476 if (image->previous == (Image *) NULL)
478 status=SetImageProgress(image,LoadImageTag,(i+1),5);
479 if (status == MagickFalse)
483 if (image->previous == (Image *) NULL)
485 status=SetImageProgress(image,LoadImageTag,5,5);
486 if (status == MagickFalse)
491 case PartitionInterlace:
494 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
496 for (i=0; i < channels; i++)
498 sfx[0]=image_info->magick[i];
499 AppendImageFormat(sfx,image->filename);
500 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
501 if (status == MagickFalse)
503 canvas_image=DestroyImageList(canvas_image);
504 image=DestroyImageList(image);
505 return((Image *) NULL);
508 for (j=0; j < image->offset; j++)
509 if (ReadBlobByte(image) == EOF)
511 ThrowFileException(exception,CorruptImageError,
512 "UnexpectedEndOfFile",image->filename);
515 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[i]);
516 for (j=0; j < (ssize_t) scene; j++)
517 for (y=0; y < (ssize_t) image->extract_info.height; y++)
518 if (ReadBlob(image,length,pixels) != (ssize_t) length)
520 ThrowFileException(exception,CorruptImageError,
521 "UnexpectedEndOfFile",image->filename);
524 count=ReadBlob(image,length,pixels);
525 for (y=0; y < (ssize_t) image->extract_info.height; y++)
527 register const PixelPacket
536 if (count != (ssize_t) length)
538 ThrowFileException(exception,CorruptImageError,
539 "UnexpectedEndOfFile",image->filename);
542 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
544 if (q == (PixelPacket *) NULL)
546 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
547 quantum_info,quantum_types[i],pixels,exception);
548 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
550 if (((y-image->extract_info.y) >= 0) &&
551 ((y-image->extract_info.y) < (ssize_t) image->rows))
553 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
554 canvas_image->columns,1,exception);
555 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
556 image->columns,1,exception);
557 if ((p == (const PixelPacket *) NULL) ||
558 (q == (PixelPacket *) NULL))
560 for (x=0; x < (ssize_t) image->columns; x++)
562 switch(quantum_types[i])
564 case RedQuantum: SetRedPixelComponent(q,GetRedPixelComponent(p)); break;
565 case GreenQuantum: SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break;
566 case BlueQuantum: SetBluePixelComponent(q,GetBluePixelComponent(p)); break;
568 case AlphaQuantum: SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break;
574 if (SyncAuthenticPixels(image,exception) == MagickFalse)
577 count=ReadBlob(image,length,pixels);
579 if (image->previous == (Image *) NULL)
581 status=SetImageProgress(image,LoadImageTag,(i+1),5);
582 if (status == MagickFalse)
585 if (i != (channels-1))
586 (void) CloseBlob(image);
588 if (image->previous == (Image *) NULL)
590 status=SetImageProgress(image,LoadImageTag,5,5);
591 if (status == MagickFalse)
597 SetQuantumImageType(image,quantum_type);
599 Proceed to next image.
601 if (image_info->number_scenes != 0)
602 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
604 if (count == (ssize_t) length)
607 Allocate next image structure.
609 AcquireNextImage(image_info,image);
610 if (GetNextImageInList(image) == (Image *) NULL)
612 image=DestroyImageList(image);
613 return((Image *) NULL);
615 image=SyncNextImageInList(image);
616 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
618 if (status == MagickFalse)
622 } while (count == (ssize_t) length);
623 quantum_info=DestroyQuantumInfo(quantum_info);
624 InheritException(&image->exception,&canvas_image->exception);
625 canvas_image=DestroyImage(canvas_image);
626 (void) CloseBlob(image);
627 return(GetFirstImageInList(image));
631 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 % R e g i s t e r R G B I m a g e %
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641 % RegisterRGBImage() adds attributes for the RGB or RGBA image format to
642 % the list of supported formats. The attributes include the image format
643 % tag, a method to read and/or write the format, whether the format
644 % supports the saving of more than one frame to the same file or blob,
645 % whether the format supports native in-memory I/O, and a brief
646 % description of the format.
648 % The format of the RegisterRGBImage method is:
650 % size_t RegisterRGBImage(void)
653 ModuleExport size_t RegisterRGBImage(void)
658 entry=SetMagickInfo("RGB");
659 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
660 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
661 entry->raw=MagickTrue;
662 entry->endian_support=MagickTrue;
663 entry->description=ConstantString("Raw red, green, and blue samples");
664 entry->module=ConstantString("RGB");
665 (void) RegisterMagickInfo(entry);
666 entry=SetMagickInfo("RBG");
667 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
668 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
669 entry->raw=MagickTrue;
670 entry->endian_support=MagickTrue;
671 entry->description=ConstantString("Raw red, blue, and green samples");
672 entry->module=ConstantString("RGB");
673 (void) RegisterMagickInfo(entry);
674 entry=SetMagickInfo("GRB");
675 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
676 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
677 entry->raw=MagickTrue;
678 entry->endian_support=MagickTrue;
679 entry->description=ConstantString("Raw green, red, and blue samples");
680 entry->module=ConstantString("RGB");
681 (void) RegisterMagickInfo(entry);
682 entry=SetMagickInfo("GBR");
683 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
684 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
685 entry->raw=MagickTrue;
686 entry->endian_support=MagickTrue;
687 entry->description=ConstantString("Raw green, blue, and red samples");
688 entry->module=ConstantString("RGB");
689 (void) RegisterMagickInfo(entry);
690 entry=SetMagickInfo("BRG");
691 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
692 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
693 entry->raw=MagickTrue;
694 entry->endian_support=MagickTrue;
695 entry->description=ConstantString("Raw blue, red, and green samples");
696 entry->module=ConstantString("RGB");
697 (void) RegisterMagickInfo(entry);
698 entry=SetMagickInfo("BGR");
699 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
700 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
701 entry->raw=MagickTrue;
702 entry->endian_support=MagickTrue;
703 entry->description=ConstantString("Raw blue, green, and red samples");
704 entry->module=ConstantString("RGB");
705 (void) RegisterMagickInfo(entry);
706 entry=SetMagickInfo("BGRA");
707 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
708 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
709 entry->raw=MagickTrue;
710 entry->endian_support=MagickTrue;
711 entry->description=ConstantString("Raw blue, green, red and alpha samples");
712 entry->module=ConstantString("RGB");
713 (void) RegisterMagickInfo(entry);
714 entry=SetMagickInfo("RGBA");
715 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
716 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
717 entry->raw=MagickTrue;
718 entry->endian_support=MagickTrue;
719 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
720 entry->module=ConstantString("RGB");
721 (void) RegisterMagickInfo(entry);
722 entry=SetMagickInfo("RGBO");
723 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
724 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
725 entry->raw=MagickTrue;
726 entry->endian_support=MagickTrue;
727 entry->description=ConstantString("Raw red, green, blue, and opacity "
729 entry->module=ConstantString("RGB");
730 (void) RegisterMagickInfo(entry);
731 return(MagickImageCoderSignature);
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739 % U n r e g i s t e r R G B I m a g e %
743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745 % UnregisterRGBImage() removes format registrations made by the
746 % RGB module from the list of supported formats.
748 % The format of the UnregisterRGBImage method is:
750 % UnregisterRGBImage(void)
753 ModuleExport void UnregisterRGBImage(void)
755 (void) UnregisterMagickInfo("RGBO");
756 (void) UnregisterMagickInfo("RGBA");
757 (void) UnregisterMagickInfo("BGR");
758 (void) UnregisterMagickInfo("BGRA");
759 (void) UnregisterMagickInfo("BRG");
760 (void) UnregisterMagickInfo("GBR");
761 (void) UnregisterMagickInfo("GRB");
762 (void) UnregisterMagickInfo("RBG");
763 (void) UnregisterMagickInfo("RGB");
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771 % W r i t e R G B I m a g e %
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777 % WriteRGBImage() writes an image to a file in the RGB or RGBA rasterfile
780 % The format of the WriteRGBImage method is:
782 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
784 % A description of each parameter follows.
786 % o image_info: the image info.
788 % o image: The image.
791 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
825 Allocate memory for pixels.
827 assert(image_info != (const ImageInfo *) NULL);
828 assert(image_info->signature == MagickSignature);
829 assert(image != (Image *) NULL);
830 assert(image->signature == MagickSignature);
831 if (image->debug != MagickFalse)
832 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
833 if (image_info->interlace != PartitionInterlace)
836 Open output image file.
838 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
839 if (status == MagickFalse)
842 quantum_type=RGBQuantum;
844 if (LocaleCompare(image_info->magick,"RGBA") == 0)
846 quantum_type=RGBAQuantum;
847 image->matte=MagickTrue;
850 if (LocaleCompare(image_info->magick,"RGBO") == 0)
852 quantum_type=RGBOQuantum;
853 image->matte=MagickTrue;
856 for (i=0; i < (ssize_t) channels; i++)
858 switch (image_info->magick[i])
860 case 'R': quantum_types[i]=RedQuantum; break;
861 case 'G': quantum_types[i]=GreenQuantum; break;
862 case 'B': quantum_types[i]=BlueQuantum; break;
863 case 'A': quantum_types[i]=AlphaQuantum; break;
864 case 'O': quantum_types[i]=OpacityQuantum; break;
871 Convert MIFF to RGB raster pixels.
873 if (image->colorspace != RGBColorspace)
874 (void) TransformImageColorspace(image,RGBColorspace);
875 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
876 (image->matte == MagickFalse))
877 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
878 quantum_info=AcquireQuantumInfo(image_info,image);
879 if (quantum_info == (QuantumInfo *) NULL)
880 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
881 pixels=GetQuantumPixels(quantum_info);
882 switch (image_info->interlace)
897 No interlacing: RGBRGBRGBRGBRGBRGB...
899 image_view=AcquireCacheView(image);
900 for (y=0; y < (ssize_t) image->rows; y++)
908 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
910 if (q == (PixelPacket *) NULL)
912 for (x=0; x < (ssize_t) image->columns; x++)
918 for (i=0; i < 3; i++)
919 switch (quantum_types[i])
921 case RedQuantum: *qx[i]=px.red; break;
922 case GreenQuantum: *qx[i]=px.green; break;
923 case BlueQuantum: *qx[i]=px.blue; break;
928 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
929 pixels,&image->exception);
930 count=WriteBlob(image,length,pixels);
931 if (count != (ssize_t) length)
933 if (image->previous == (Image *) NULL)
935 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
937 if (status == MagickFalse)
941 image_view=DestroyCacheView(image_view);
947 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
949 for (y=0; y < (ssize_t) image->rows; y++)
951 register const PixelPacket
954 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
955 if (p == (const PixelPacket *) NULL)
957 for (i=0; i < (ssize_t) channels; i++)
959 length=ExportQuantumPixels(image,(const CacheView *) NULL,
960 quantum_info,quantum_types[i],pixels,&image->exception);
961 count=WriteBlob(image,length,pixels);
962 if (count != (ssize_t) length)
965 if (image->previous == (Image *) NULL)
967 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
969 if (status == MagickFalse)
978 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
980 for (i=0; i < (ssize_t) channels; i++)
982 for (y=0; y < (ssize_t) image->rows; y++)
984 register const PixelPacket
987 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
988 if (p == (const PixelPacket *) NULL)
990 length=ExportQuantumPixels(image,(const CacheView *) NULL,
991 quantum_info,quantum_types[i],pixels,&image->exception);
992 count=WriteBlob(image,length,pixels);
993 if (count != (ssize_t) length)
996 if (image->previous == (Image *) NULL)
998 status=SetImageProgress(image,SaveImageTag,(i+1),5);
999 if (status == MagickFalse)
1003 if (image->previous == (Image *) NULL)
1005 status=SetImageProgress(image,SaveImageTag,5,5);
1006 if (status == MagickFalse)
1011 case PartitionInterlace:
1017 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1019 for (i=0; i < (ssize_t) channels; i++)
1021 sfx[0]=image_info->magick[i];
1022 AppendImageFormat(sfx,image->filename);
1023 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1024 AppendBinaryBlobMode,&image->exception);
1025 if (status == MagickFalse)
1027 for (y=0; y < (ssize_t) image->rows; y++)
1029 register const PixelPacket
1032 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1033 if (p == (const PixelPacket *) NULL)
1035 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1036 quantum_info,quantum_types[i],pixels,&image->exception);
1037 count=WriteBlob(image,length,pixels);
1038 if (count != (ssize_t) length)
1041 if (image->previous == (Image *) NULL)
1043 status=SetImageProgress(image,SaveImageTag,(i+1),5);
1044 if (status == MagickFalse)
1047 (void) CloseBlob(image);
1049 (void) CopyMagickString(image->filename,image_info->filename,
1051 if (image->previous == (Image *) NULL)
1053 status=SetImageProgress(image,SaveImageTag,5,5);
1054 if (status == MagickFalse)
1060 quantum_info=DestroyQuantumInfo(quantum_info);
1061 if (GetNextImageInList(image) == (Image *) NULL)
1063 image=SyncNextImageInList(image);
1064 status=SetImageProgress(image,SaveImagesTag,scene++,
1065 GetImageListLength(image));
1066 if (status == MagickFalse)
1068 } while (image_info->adjoin != MagickFalse);
1069 (void) CloseBlob(image);