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])
566 SetRedPixelComponent(q,GetRedPixelComponent(p));
571 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
576 SetBluePixelComponent(q,GetBluePixelComponent(p));
582 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
591 if (SyncAuthenticPixels(image,exception) == MagickFalse)
594 count=ReadBlob(image,length,pixels);
596 if (image->previous == (Image *) NULL)
598 status=SetImageProgress(image,LoadImageTag,(i+1),5);
599 if (status == MagickFalse)
602 if (i != (channels-1))
603 (void) CloseBlob(image);
605 if (image->previous == (Image *) NULL)
607 status=SetImageProgress(image,LoadImageTag,5,5);
608 if (status == MagickFalse)
614 SetQuantumImageType(image,quantum_type);
616 Proceed to next image.
618 if (image_info->number_scenes != 0)
619 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
621 if (count == (ssize_t) length)
624 Allocate next image structure.
626 AcquireNextImage(image_info,image);
627 if (GetNextImageInList(image) == (Image *) NULL)
629 image=DestroyImageList(image);
630 return((Image *) NULL);
632 image=SyncNextImageInList(image);
633 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
635 if (status == MagickFalse)
639 } while (count == (ssize_t) length);
640 quantum_info=DestroyQuantumInfo(quantum_info);
641 InheritException(&image->exception,&canvas_image->exception);
642 canvas_image=DestroyImage(canvas_image);
643 (void) CloseBlob(image);
644 return(GetFirstImageInList(image));
648 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652 % R e g i s t e r R G B I m a g e %
656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
658 % RegisterRGBImage() adds attributes for the RGB or RGBA image format to
659 % the list of supported formats. The attributes include the image format
660 % tag, a method to read and/or write the format, whether the format
661 % supports the saving of more than one frame to the same file or blob,
662 % whether the format supports native in-memory I/O, and a brief
663 % description of the format.
665 % The format of the RegisterRGBImage method is:
667 % size_t RegisterRGBImage(void)
670 ModuleExport size_t RegisterRGBImage(void)
675 entry=SetMagickInfo("RGB");
676 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
677 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
678 entry->raw=MagickTrue;
679 entry->endian_support=MagickTrue;
680 entry->description=ConstantString("Raw red, green, and blue samples");
681 entry->module=ConstantString("RGB");
682 (void) RegisterMagickInfo(entry);
683 entry=SetMagickInfo("RBG");
684 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
685 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
686 entry->raw=MagickTrue;
687 entry->endian_support=MagickTrue;
688 entry->description=ConstantString("Raw red, blue, and green samples");
689 entry->module=ConstantString("RGB");
690 (void) RegisterMagickInfo(entry);
691 entry=SetMagickInfo("GRB");
692 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
693 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
694 entry->raw=MagickTrue;
695 entry->endian_support=MagickTrue;
696 entry->description=ConstantString("Raw green, red, and blue samples");
697 entry->module=ConstantString("RGB");
698 (void) RegisterMagickInfo(entry);
699 entry=SetMagickInfo("GBR");
700 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
701 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
702 entry->raw=MagickTrue;
703 entry->endian_support=MagickTrue;
704 entry->description=ConstantString("Raw green, blue, and red samples");
705 entry->module=ConstantString("RGB");
706 (void) RegisterMagickInfo(entry);
707 entry=SetMagickInfo("BRG");
708 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
709 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
710 entry->raw=MagickTrue;
711 entry->endian_support=MagickTrue;
712 entry->description=ConstantString("Raw blue, red, and green samples");
713 entry->module=ConstantString("RGB");
714 (void) RegisterMagickInfo(entry);
715 entry=SetMagickInfo("BGR");
716 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
717 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
718 entry->raw=MagickTrue;
719 entry->endian_support=MagickTrue;
720 entry->description=ConstantString("Raw blue, green, and red samples");
721 entry->module=ConstantString("RGB");
722 (void) RegisterMagickInfo(entry);
723 entry=SetMagickInfo("BGRA");
724 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
725 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
726 entry->raw=MagickTrue;
727 entry->endian_support=MagickTrue;
728 entry->description=ConstantString("Raw blue, green, red and alpha samples");
729 entry->module=ConstantString("RGB");
730 (void) RegisterMagickInfo(entry);
731 entry=SetMagickInfo("RGBA");
732 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
733 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
734 entry->raw=MagickTrue;
735 entry->endian_support=MagickTrue;
736 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
737 entry->module=ConstantString("RGB");
738 (void) RegisterMagickInfo(entry);
739 entry=SetMagickInfo("RGBO");
740 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
741 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
742 entry->raw=MagickTrue;
743 entry->endian_support=MagickTrue;
744 entry->description=ConstantString("Raw red, green, blue, and opacity "
746 entry->module=ConstantString("RGB");
747 (void) RegisterMagickInfo(entry);
748 return(MagickImageCoderSignature);
752 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
756 % U n r e g i s t e r R G B I m a g e %
760 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 % UnregisterRGBImage() removes format registrations made by the
763 % RGB module from the list of supported formats.
765 % The format of the UnregisterRGBImage method is:
767 % UnregisterRGBImage(void)
770 ModuleExport void UnregisterRGBImage(void)
772 (void) UnregisterMagickInfo("RGBO");
773 (void) UnregisterMagickInfo("RGBA");
774 (void) UnregisterMagickInfo("BGR");
775 (void) UnregisterMagickInfo("BGRA");
776 (void) UnregisterMagickInfo("BRG");
777 (void) UnregisterMagickInfo("GBR");
778 (void) UnregisterMagickInfo("GRB");
779 (void) UnregisterMagickInfo("RBG");
780 (void) UnregisterMagickInfo("RGB");
784 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
788 % W r i t e R G B I m a g e %
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794 % WriteRGBImage() writes an image to a file in the RGB or RGBA rasterfile
797 % The format of the WriteRGBImage method is:
799 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
801 % A description of each parameter follows.
803 % o image_info: the image info.
805 % o image: The image.
808 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
842 Allocate memory for pixels.
844 assert(image_info != (const ImageInfo *) NULL);
845 assert(image_info->signature == MagickSignature);
846 assert(image != (Image *) NULL);
847 assert(image->signature == MagickSignature);
848 if (image->debug != MagickFalse)
849 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
850 if (image_info->interlace != PartitionInterlace)
853 Open output image file.
855 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
856 if (status == MagickFalse)
859 quantum_type=RGBQuantum;
861 if (LocaleCompare(image_info->magick,"RGBA") == 0)
863 quantum_type=RGBAQuantum;
864 image->matte=MagickTrue;
867 if (LocaleCompare(image_info->magick,"RGBO") == 0)
869 quantum_type=RGBOQuantum;
870 image->matte=MagickTrue;
873 for (i=0; i < (ssize_t) channels; i++)
875 switch (image_info->magick[i])
877 case 'R': quantum_types[i]=RedQuantum; break;
878 case 'G': quantum_types[i]=GreenQuantum; break;
879 case 'B': quantum_types[i]=BlueQuantum; break;
880 case 'A': quantum_types[i]=AlphaQuantum; break;
881 case 'O': quantum_types[i]=OpacityQuantum; break;
888 Convert MIFF to RGB raster pixels.
890 if (image->colorspace != RGBColorspace)
891 (void) TransformImageColorspace(image,RGBColorspace);
892 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
893 (image->matte == MagickFalse))
894 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
895 quantum_info=AcquireQuantumInfo(image_info,image);
896 if (quantum_info == (QuantumInfo *) NULL)
897 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
898 pixels=GetQuantumPixels(quantum_info);
899 switch (image_info->interlace)
914 No interlacing: RGBRGBRGBRGBRGBRGB...
916 image_view=AcquireCacheView(image);
917 for (y=0; y < (ssize_t) image->rows; y++)
925 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
927 if (q == (PixelPacket *) NULL)
929 for (x=0; x < (ssize_t) image->columns; x++)
935 for (i=0; i < 3; i++)
936 switch (quantum_types[i])
938 case RedQuantum: *qx[i]=px.red; break;
939 case GreenQuantum: *qx[i]=px.green; break;
940 case BlueQuantum: *qx[i]=px.blue; break;
945 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
946 pixels,&image->exception);
947 count=WriteBlob(image,length,pixels);
948 if (count != (ssize_t) length)
950 if (image->previous == (Image *) NULL)
952 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
954 if (status == MagickFalse)
958 image_view=DestroyCacheView(image_view);
964 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
966 for (y=0; y < (ssize_t) image->rows; y++)
968 register const PixelPacket
971 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
972 if (p == (const PixelPacket *) NULL)
974 for (i=0; i < (ssize_t) channels; i++)
976 length=ExportQuantumPixels(image,(const CacheView *) NULL,
977 quantum_info,quantum_types[i],pixels,&image->exception);
978 count=WriteBlob(image,length,pixels);
979 if (count != (ssize_t) length)
982 if (image->previous == (Image *) NULL)
984 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
986 if (status == MagickFalse)
995 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
997 for (i=0; i < (ssize_t) channels; i++)
999 for (y=0; y < (ssize_t) image->rows; y++)
1001 register const PixelPacket
1004 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1005 if (p == (const PixelPacket *) NULL)
1007 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1008 quantum_info,quantum_types[i],pixels,&image->exception);
1009 count=WriteBlob(image,length,pixels);
1010 if (count != (ssize_t) length)
1013 if (image->previous == (Image *) NULL)
1015 status=SetImageProgress(image,SaveImageTag,(i+1),5);
1016 if (status == MagickFalse)
1020 if (image->previous == (Image *) NULL)
1022 status=SetImageProgress(image,SaveImageTag,5,5);
1023 if (status == MagickFalse)
1028 case PartitionInterlace:
1034 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1036 for (i=0; i < (ssize_t) channels; i++)
1038 sfx[0]=image_info->magick[i];
1039 AppendImageFormat(sfx,image->filename);
1040 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1041 AppendBinaryBlobMode,&image->exception);
1042 if (status == MagickFalse)
1044 for (y=0; y < (ssize_t) image->rows; y++)
1046 register const PixelPacket
1049 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1050 if (p == (const PixelPacket *) NULL)
1052 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1053 quantum_info,quantum_types[i],pixels,&image->exception);
1054 count=WriteBlob(image,length,pixels);
1055 if (count != (ssize_t) length)
1058 if (image->previous == (Image *) NULL)
1060 status=SetImageProgress(image,SaveImageTag,(i+1),5);
1061 if (status == MagickFalse)
1064 (void) CloseBlob(image);
1066 (void) CopyMagickString(image->filename,image_info->filename,
1068 if (image->previous == (Image *) NULL)
1070 status=SetImageProgress(image,SaveImageTag,5,5);
1071 if (status == MagickFalse)
1077 quantum_info=DestroyQuantumInfo(quantum_info);
1078 if (GetNextImageInList(image) == (Image *) NULL)
1080 image=SyncNextImageInList(image);
1081 status=SetImageProgress(image,SaveImagesTag,scene++,
1082 GetImageListLength(image));
1083 if (status == MagickFalse)
1085 } while (image_info->adjoin != MagickFalse);
1086 (void) CloseBlob(image);