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 < (long) 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 < (long) 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) < (long) 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 < (long) 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,y,image->rows);
313 if (status == MagickFalse)
316 count=ReadBlob(image,length,pixels);
323 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
327 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
328 count=ReadBlob(image,length,pixels);
330 for (y=0; y < (long) image->extract_info.height; y++)
332 register const PixelPacket
341 if (count != (ssize_t) length)
343 ThrowFileException(exception,CorruptImageError,
344 "UnexpectedEndOfFile",image->filename);
347 for (i=0; i < channels; i++)
349 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
351 if (q == (PixelPacket *) NULL)
353 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
354 quantum_info,quantum_types[i],pixels,exception);
355 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
357 if (((y-image->extract_info.y) >= 0) &&
358 ((y-image->extract_info.y) < (long) image->rows))
360 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
361 0,canvas_image->columns,1,exception);
362 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
363 image->columns,1,exception);
364 if ((p == (const PixelPacket *) NULL) ||
365 (q == (PixelPacket *) NULL))
367 if (i == (channels - 1))
368 for (x=0; x < (long) image->columns; x++)
370 SetRedPixelComponent(q,GetRedPixelComponent(p));
371 SetGreenPixelComponent(q,GetGreenPixelComponent(p));
372 SetBluePixelComponent(q,GetBluePixelComponent(p));
373 SetOpacityPixelComponent(q,GetOpacityPixelComponent(p));
377 if (SyncAuthenticPixels(image,exception) == MagickFalse)
380 count=ReadBlob(image,length,pixels);
382 if (image->previous == (Image *) NULL)
384 status=SetImageProgress(image,LoadImageTag,y,image->rows);
385 if (status == MagickFalse)
394 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
398 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
399 count=ReadBlob(image,length,pixels);
401 for (i=0; i < channels; i++)
403 for (y=0; y < (long) image->extract_info.height; y++)
405 register const PixelPacket
414 if (count != (ssize_t) length)
416 ThrowFileException(exception,CorruptImageError,
417 "UnexpectedEndOfFile",image->filename);
420 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
422 if (q == (PixelPacket *) NULL)
424 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
425 quantum_info,quantum_types[i],pixels,exception);
426 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
428 if (((y-image->extract_info.y) >= 0) &&
429 ((y-image->extract_info.y) < (long) image->rows))
431 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
432 canvas_image->columns,1,exception);
433 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
434 image->columns,1,exception);
435 if ((p == (const PixelPacket *) NULL) ||
436 (q == (PixelPacket *) NULL))
438 for (x=0; x < (long) image->columns; x++)
440 switch(quantum_types[i])
442 case RedQuantum: SetRedPixelComponent(q,GetRedPixelComponent(p)); break;
443 case GreenQuantum: SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break;
444 case BlueQuantum: SetBluePixelComponent(q,GetBluePixelComponent(p)); break;
446 case AlphaQuantum: SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break;
452 if (SyncAuthenticPixels(image,exception) == MagickFalse)
455 count=ReadBlob(image,length,pixels);
457 if (image->previous == (Image *) NULL)
459 status=SetImageProgress(image,LoadImageTag,(i+1),5);
460 if (status == MagickFalse)
464 if (image->previous == (Image *) NULL)
466 status=SetImageProgress(image,LoadImageTag,5,5);
467 if (status == MagickFalse)
472 case PartitionInterlace:
475 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
477 for (i=0; i < channels; i++)
479 sfx[0]=image_info->magick[i];
480 AppendImageFormat(sfx,image->filename);
481 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
482 if (status == MagickFalse)
484 canvas_image=DestroyImageList(canvas_image);
485 image=DestroyImageList(image);
486 return((Image *) NULL);
489 for (j=0; j < image->offset; j++)
490 if (ReadBlobByte(image) == EOF)
492 ThrowFileException(exception,CorruptImageError,
493 "UnexpectedEndOfFile",image->filename);
496 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[i]);
497 for (j=0; j < (long) scene; j++)
498 for (y=0; y < (long) image->extract_info.height; y++)
499 if (ReadBlob(image,length,pixels) != (ssize_t) length)
501 ThrowFileException(exception,CorruptImageError,
502 "UnexpectedEndOfFile",image->filename);
505 count=ReadBlob(image,length,pixels);
506 for (y=0; y < (long) image->extract_info.height; y++)
508 register const PixelPacket
517 if (count != (ssize_t) length)
519 ThrowFileException(exception,CorruptImageError,
520 "UnexpectedEndOfFile",image->filename);
523 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
525 if (q == (PixelPacket *) NULL)
527 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
528 quantum_info,quantum_types[i],pixels,exception);
529 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
531 if (((y-image->extract_info.y) >= 0) &&
532 ((y-image->extract_info.y) < (long) image->rows))
534 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
535 canvas_image->columns,1,exception);
536 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
537 image->columns,1,exception);
538 if ((p == (const PixelPacket *) NULL) ||
539 (q == (PixelPacket *) NULL))
541 for (x=0; x < (long) image->columns; x++)
543 switch(quantum_types[i])
545 case RedQuantum: SetRedPixelComponent(q,GetRedPixelComponent(p)); break;
546 case GreenQuantum: SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break;
547 case BlueQuantum: SetBluePixelComponent(q,GetBluePixelComponent(p)); break;
549 case AlphaQuantum: SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break;
555 if (SyncAuthenticPixels(image,exception) == MagickFalse)
558 count=ReadBlob(image,length,pixels);
560 if (image->previous == (Image *) NULL)
562 status=SetImageProgress(image,LoadImageTag,(i+1),5);
563 if (status == MagickFalse)
566 if (i != (channels-1))
567 (void) CloseBlob(image);
569 if (image->previous == (Image *) NULL)
571 status=SetImageProgress(image,LoadImageTag,5,5);
572 if (status == MagickFalse)
578 SetQuantumImageType(image,quantum_type);
580 Proceed to next image.
582 if (image_info->number_scenes != 0)
583 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
585 if (count == (ssize_t) length)
588 Allocate next image structure.
590 AcquireNextImage(image_info,image);
591 if (GetNextImageInList(image) == (Image *) NULL)
593 image=DestroyImageList(image);
594 return((Image *) NULL);
596 image=SyncNextImageInList(image);
597 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
599 if (status == MagickFalse)
603 } while (count == (ssize_t) length);
604 quantum_info=DestroyQuantumInfo(quantum_info);
605 InheritException(&image->exception,&canvas_image->exception);
606 canvas_image=DestroyImage(canvas_image);
607 (void) CloseBlob(image);
608 return(GetFirstImageInList(image));
612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 % R e g i s t e r R G B I m a g e %
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622 % RegisterRGBImage() adds attributes for the RGB or RGBA image format to
623 % the list of supported formats. The attributes include the image format
624 % tag, a method to read and/or write the format, whether the format
625 % supports the saving of more than one frame to the same file or blob,
626 % whether the format supports native in-memory I/O, and a brief
627 % description of the format.
629 % The format of the RegisterRGBImage method is:
631 % unsigned long RegisterRGBImage(void)
634 ModuleExport unsigned long RegisterRGBImage(void)
639 entry=SetMagickInfo("RGB");
640 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
641 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
642 entry->raw=MagickTrue;
643 entry->endian_support=MagickTrue;
644 entry->format_type=ExplicitFormatType;
645 entry->description=ConstantString("Raw red, green, and blue samples");
646 entry->module=ConstantString("RGB");
647 (void) RegisterMagickInfo(entry);
648 entry=SetMagickInfo("RBG");
649 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
650 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
651 entry->raw=MagickTrue;
652 entry->endian_support=MagickTrue;
653 entry->format_type=ExplicitFormatType;
654 entry->description=ConstantString("Raw red, blue, and green samples");
655 entry->module=ConstantString("RGB");
656 (void) RegisterMagickInfo(entry);
657 entry=SetMagickInfo("GRB");
658 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
659 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
660 entry->raw=MagickTrue;
661 entry->endian_support=MagickTrue;
662 entry->format_type=ExplicitFormatType;
663 entry->description=ConstantString("Raw green, red, and blue samples");
664 entry->module=ConstantString("RGB");
665 (void) RegisterMagickInfo(entry);
666 entry=SetMagickInfo("GBR");
667 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
668 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
669 entry->raw=MagickTrue;
670 entry->endian_support=MagickTrue;
671 entry->format_type=ExplicitFormatType;
672 entry->description=ConstantString("Raw green, blue, and red samples");
673 entry->module=ConstantString("RGB");
674 (void) RegisterMagickInfo(entry);
675 entry=SetMagickInfo("BRG");
676 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
677 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
678 entry->raw=MagickTrue;
679 entry->endian_support=MagickTrue;
680 entry->format_type=ExplicitFormatType;
681 entry->description=ConstantString("Raw blue, red, and green samples");
682 entry->module=ConstantString("RGB");
683 (void) RegisterMagickInfo(entry);
684 entry=SetMagickInfo("BGR");
685 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
686 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
687 entry->raw=MagickTrue;
688 entry->endian_support=MagickTrue;
689 entry->format_type=ExplicitFormatType;
690 entry->description=ConstantString("Raw blue, green, and red samples");
691 entry->module=ConstantString("RGB");
692 (void) RegisterMagickInfo(entry);
693 entry=SetMagickInfo("BGRA");
694 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
695 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
696 entry->raw=MagickTrue;
697 entry->endian_support=MagickTrue;
698 entry->format_type=ExplicitFormatType;
699 entry->description=ConstantString("Raw blue, green, red and alpha samples");
700 entry->module=ConstantString("RGB");
701 (void) RegisterMagickInfo(entry);
702 entry=SetMagickInfo("RGBA");
703 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
704 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
705 entry->raw=MagickTrue;
706 entry->endian_support=MagickTrue;
707 entry->format_type=ExplicitFormatType;
708 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
709 entry->module=ConstantString("RGB");
710 (void) RegisterMagickInfo(entry);
711 entry=SetMagickInfo("RGBO");
712 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
713 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
714 entry->raw=MagickTrue;
715 entry->endian_support=MagickTrue;
716 entry->format_type=ExplicitFormatType;
717 entry->description=ConstantString("Raw red, green, blue, and opacity "
719 entry->module=ConstantString("RGB");
720 (void) RegisterMagickInfo(entry);
721 return(MagickImageCoderSignature);
725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
729 % U n r e g i s t e r R G B I m a g e %
733 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
735 % UnregisterRGBImage() removes format registrations made by the
736 % RGB module from the list of supported formats.
738 % The format of the UnregisterRGBImage method is:
740 % UnregisterRGBImage(void)
743 ModuleExport void UnregisterRGBImage(void)
745 (void) UnregisterMagickInfo("RGBO");
746 (void) UnregisterMagickInfo("RGBA");
747 (void) UnregisterMagickInfo("BGR");
748 (void) UnregisterMagickInfo("BGRA");
749 (void) UnregisterMagickInfo("BRG");
750 (void) UnregisterMagickInfo("GBR");
751 (void) UnregisterMagickInfo("GRB");
752 (void) UnregisterMagickInfo("RBG");
753 (void) UnregisterMagickInfo("RGB");
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
761 % W r i t e R G B I m a g e %
765 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 % WriteRGBImage() writes an image to a file in the RGB or RGBA rasterfile
770 % The format of the WriteRGBImage method is:
772 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
774 % A description of each parameter follows.
776 % o image_info: the image info.
778 % o image: The image.
781 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
815 Allocate memory for pixels.
817 assert(image_info != (const ImageInfo *) NULL);
818 assert(image_info->signature == MagickSignature);
819 assert(image != (Image *) NULL);
820 assert(image->signature == MagickSignature);
821 if (image->debug != MagickFalse)
822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
823 if (image_info->interlace != PartitionInterlace)
826 Open output image file.
828 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
829 if (status == MagickFalse)
832 quantum_type=RGBQuantum;
834 if (LocaleCompare(image_info->magick,"RGBA") == 0)
836 quantum_type=RGBAQuantum;
837 image->matte=MagickTrue;
840 if (LocaleCompare(image_info->magick,"RGBO") == 0)
842 quantum_type=RGBOQuantum;
843 image->matte=MagickTrue;
846 for (i=0; i < (long) channels; i++)
848 switch (image_info->magick[i])
850 case 'R': quantum_types[i]=RedQuantum; break;
851 case 'G': quantum_types[i]=GreenQuantum; break;
852 case 'B': quantum_types[i]=BlueQuantum; break;
853 case 'A': quantum_types[i]=AlphaQuantum; break;
854 case 'O': quantum_types[i]=OpacityQuantum; break;
861 Convert MIFF to RGB raster pixels.
863 if (image->colorspace != RGBColorspace)
864 (void) TransformImageColorspace(image,RGBColorspace);
865 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
866 (image->matte == MagickFalse))
867 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
868 quantum_info=AcquireQuantumInfo(image_info,image);
869 if (quantum_info == (QuantumInfo *) NULL)
870 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
871 pixels=GetQuantumPixels(quantum_info);
872 switch (image_info->interlace)
887 No interlacing: RGBRGBRGBRGBRGBRGB...
889 image_view=AcquireCacheView(image);
890 for (y=0; y < (long) image->rows; y++)
898 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
900 if (q == (PixelPacket *) NULL)
902 for (x=0; x < (long) image->columns; x++)
908 for (i=0; i < 3; i++)
909 switch (quantum_types[i])
911 case RedQuantum: *qx[i]=px.red; break;
912 case GreenQuantum: *qx[i]=px.green; break;
913 case BlueQuantum: *qx[i]=px.blue; break;
918 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
919 pixels,&image->exception);
920 count=WriteBlob(image,length,pixels);
921 if (count != (ssize_t) length)
923 if (image->previous == (Image *) NULL)
925 status=SetImageProgress(image,SaveImageTag,y,image->rows);
926 if (status == MagickFalse)
930 image_view=DestroyCacheView(image_view);
936 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
938 for (y=0; y < (long) image->rows; y++)
940 register const PixelPacket
943 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
944 if (p == (const PixelPacket *) NULL)
946 for (i=0; i < (long) channels; i++)
948 length=ExportQuantumPixels(image,(const CacheView *) NULL,
949 quantum_info,quantum_types[i],pixels,&image->exception);
950 count=WriteBlob(image,length,pixels);
951 if (count != (ssize_t) length)
954 if (image->previous == (Image *) NULL)
956 status=SetImageProgress(image,SaveImageTag,y,image->rows);
957 if (status == MagickFalse)
966 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
968 for (i=0; i < (long) channels; i++)
970 for (y=0; y < (long) image->rows; y++)
972 register const PixelPacket
975 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
976 if (p == (const PixelPacket *) NULL)
978 length=ExportQuantumPixels(image,(const CacheView *) NULL,
979 quantum_info,quantum_types[i],pixels,&image->exception);
980 count=WriteBlob(image,length,pixels);
981 if (count != (ssize_t) length)
984 if (image->previous == (Image *) NULL)
986 status=SetImageProgress(image,SaveImageTag,(i+1),5);
987 if (status == MagickFalse)
991 if (image->previous == (Image *) NULL)
993 status=SetImageProgress(image,SaveImageTag,5,5);
994 if (status == MagickFalse)
999 case PartitionInterlace:
1005 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1007 for (i=0; i < (long) channels; i++)
1009 sfx[0]=image_info->magick[i];
1010 AppendImageFormat(sfx,image->filename);
1011 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1012 AppendBinaryBlobMode,&image->exception);
1013 if (status == MagickFalse)
1015 for (y=0; y < (long) image->rows; y++)
1017 register const PixelPacket
1020 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1021 if (p == (const PixelPacket *) NULL)
1023 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1024 quantum_info,quantum_types[i],pixels,&image->exception);
1025 count=WriteBlob(image,length,pixels);
1026 if (count != (ssize_t) length)
1029 if (image->previous == (Image *) NULL)
1031 status=SetImageProgress(image,SaveImageTag,(i+1),5);
1032 if (status == MagickFalse)
1035 (void) CloseBlob(image);
1037 (void) CopyMagickString(image->filename,image_info->filename,
1039 if (image->previous == (Image *) NULL)
1041 status=SetImageProgress(image,SaveImageTag,5,5);
1042 if (status == MagickFalse)
1048 quantum_info=DestroyQuantumInfo(quantum_info);
1049 if (GetNextImageInList(image) == (Image *) NULL)
1051 image=SyncNextImageInList(image);
1052 status=SetImageProgress(image,SaveImagesTag,scene++,
1053 GetImageListLength(image));
1054 if (status == MagickFalse)
1056 } while (image_info->adjoin != MagickFalse);
1057 (void) CloseBlob(image);