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])
444 case RedQuantum: SetRedPixelComponent(q,GetRedPixelComponent(p)); break;
445 case GreenQuantum: SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break;
446 case BlueQuantum: SetBluePixelComponent(q,GetBluePixelComponent(p)); break;
448 case AlphaQuantum: SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break;
454 if (SyncAuthenticPixels(image,exception) == MagickFalse)
457 count=ReadBlob(image,length,pixels);
459 if (image->previous == (Image *) NULL)
461 status=SetImageProgress(image,LoadImageTag,(i+1),5);
462 if (status == MagickFalse)
466 if (image->previous == (Image *) NULL)
468 status=SetImageProgress(image,LoadImageTag,5,5);
469 if (status == MagickFalse)
474 case PartitionInterlace:
477 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
479 for (i=0; i < channels; i++)
481 sfx[0]=image_info->magick[i];
482 AppendImageFormat(sfx,image->filename);
483 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
484 if (status == MagickFalse)
486 canvas_image=DestroyImageList(canvas_image);
487 image=DestroyImageList(image);
488 return((Image *) NULL);
491 for (j=0; j < image->offset; j++)
492 if (ReadBlobByte(image) == EOF)
494 ThrowFileException(exception,CorruptImageError,
495 "UnexpectedEndOfFile",image->filename);
498 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[i]);
499 for (j=0; j < (ssize_t) scene; j++)
500 for (y=0; y < (ssize_t) image->extract_info.height; y++)
501 if (ReadBlob(image,length,pixels) != (ssize_t) length)
503 ThrowFileException(exception,CorruptImageError,
504 "UnexpectedEndOfFile",image->filename);
507 count=ReadBlob(image,length,pixels);
508 for (y=0; y < (ssize_t) image->extract_info.height; y++)
510 register const PixelPacket
519 if (count != (ssize_t) length)
521 ThrowFileException(exception,CorruptImageError,
522 "UnexpectedEndOfFile",image->filename);
525 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
527 if (q == (PixelPacket *) NULL)
529 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
530 quantum_info,quantum_types[i],pixels,exception);
531 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
533 if (((y-image->extract_info.y) >= 0) &&
534 ((y-image->extract_info.y) < (ssize_t) image->rows))
536 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
537 canvas_image->columns,1,exception);
538 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
539 image->columns,1,exception);
540 if ((p == (const PixelPacket *) NULL) ||
541 (q == (PixelPacket *) NULL))
543 for (x=0; x < (ssize_t) image->columns; x++)
545 switch(quantum_types[i])
547 case RedQuantum: SetRedPixelComponent(q,GetRedPixelComponent(p)); break;
548 case GreenQuantum: SetGreenPixelComponent(q,GetGreenPixelComponent(p)); break;
549 case BlueQuantum: SetBluePixelComponent(q,GetBluePixelComponent(p)); break;
551 case AlphaQuantum: SetOpacityPixelComponent(q,GetOpacityPixelComponent(p)); break;
557 if (SyncAuthenticPixels(image,exception) == MagickFalse)
560 count=ReadBlob(image,length,pixels);
562 if (image->previous == (Image *) NULL)
564 status=SetImageProgress(image,LoadImageTag,(i+1),5);
565 if (status == MagickFalse)
568 if (i != (channels-1))
569 (void) CloseBlob(image);
571 if (image->previous == (Image *) NULL)
573 status=SetImageProgress(image,LoadImageTag,5,5);
574 if (status == MagickFalse)
580 SetQuantumImageType(image,quantum_type);
582 Proceed to next image.
584 if (image_info->number_scenes != 0)
585 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
587 if (count == (ssize_t) length)
590 Allocate next image structure.
592 AcquireNextImage(image_info,image);
593 if (GetNextImageInList(image) == (Image *) NULL)
595 image=DestroyImageList(image);
596 return((Image *) NULL);
598 image=SyncNextImageInList(image);
599 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
601 if (status == MagickFalse)
605 } while (count == (ssize_t) length);
606 quantum_info=DestroyQuantumInfo(quantum_info);
607 InheritException(&image->exception,&canvas_image->exception);
608 canvas_image=DestroyImage(canvas_image);
609 (void) CloseBlob(image);
610 return(GetFirstImageInList(image));
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618 % R e g i s t e r R G B I m a g e %
622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624 % RegisterRGBImage() adds attributes for the RGB or RGBA image format to
625 % the list of supported formats. The attributes include the image format
626 % tag, a method to read and/or write the format, whether the format
627 % supports the saving of more than one frame to the same file or blob,
628 % whether the format supports native in-memory I/O, and a brief
629 % description of the format.
631 % The format of the RegisterRGBImage method is:
633 % size_t RegisterRGBImage(void)
636 ModuleExport size_t RegisterRGBImage(void)
641 entry=SetMagickInfo("RGB");
642 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
643 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
644 entry->raw=MagickTrue;
645 entry->endian_support=MagickTrue;
646 entry->format_type=ExplicitFormatType;
647 entry->description=ConstantString("Raw red, green, and blue samples");
648 entry->module=ConstantString("RGB");
649 (void) RegisterMagickInfo(entry);
650 entry=SetMagickInfo("RBG");
651 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
652 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
653 entry->raw=MagickTrue;
654 entry->endian_support=MagickTrue;
655 entry->format_type=ExplicitFormatType;
656 entry->description=ConstantString("Raw red, blue, and green samples");
657 entry->module=ConstantString("RGB");
658 (void) RegisterMagickInfo(entry);
659 entry=SetMagickInfo("GRB");
660 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
661 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
662 entry->raw=MagickTrue;
663 entry->endian_support=MagickTrue;
664 entry->format_type=ExplicitFormatType;
665 entry->description=ConstantString("Raw green, red, and blue samples");
666 entry->module=ConstantString("RGB");
667 (void) RegisterMagickInfo(entry);
668 entry=SetMagickInfo("GBR");
669 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
670 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
671 entry->raw=MagickTrue;
672 entry->endian_support=MagickTrue;
673 entry->format_type=ExplicitFormatType;
674 entry->description=ConstantString("Raw green, blue, and red samples");
675 entry->module=ConstantString("RGB");
676 (void) RegisterMagickInfo(entry);
677 entry=SetMagickInfo("BRG");
678 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
679 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
680 entry->raw=MagickTrue;
681 entry->endian_support=MagickTrue;
682 entry->format_type=ExplicitFormatType;
683 entry->description=ConstantString("Raw blue, red, and green samples");
684 entry->module=ConstantString("RGB");
685 (void) RegisterMagickInfo(entry);
686 entry=SetMagickInfo("BGR");
687 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
688 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
689 entry->raw=MagickTrue;
690 entry->endian_support=MagickTrue;
691 entry->format_type=ExplicitFormatType;
692 entry->description=ConstantString("Raw blue, green, and red samples");
693 entry->module=ConstantString("RGB");
694 (void) RegisterMagickInfo(entry);
695 entry=SetMagickInfo("BGRA");
696 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
697 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
698 entry->raw=MagickTrue;
699 entry->endian_support=MagickTrue;
700 entry->format_type=ExplicitFormatType;
701 entry->description=ConstantString("Raw blue, green, red and alpha samples");
702 entry->module=ConstantString("RGB");
703 (void) RegisterMagickInfo(entry);
704 entry=SetMagickInfo("RGBA");
705 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
706 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
707 entry->raw=MagickTrue;
708 entry->endian_support=MagickTrue;
709 entry->format_type=ExplicitFormatType;
710 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
711 entry->module=ConstantString("RGB");
712 (void) RegisterMagickInfo(entry);
713 entry=SetMagickInfo("RGBO");
714 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
715 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
716 entry->raw=MagickTrue;
717 entry->endian_support=MagickTrue;
718 entry->format_type=ExplicitFormatType;
719 entry->description=ConstantString("Raw red, green, blue, and opacity "
721 entry->module=ConstantString("RGB");
722 (void) RegisterMagickInfo(entry);
723 return(MagickImageCoderSignature);
727 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731 % U n r e g i s t e r R G B I m a g e %
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
737 % UnregisterRGBImage() removes format registrations made by the
738 % RGB module from the list of supported formats.
740 % The format of the UnregisterRGBImage method is:
742 % UnregisterRGBImage(void)
745 ModuleExport void UnregisterRGBImage(void)
747 (void) UnregisterMagickInfo("RGBO");
748 (void) UnregisterMagickInfo("RGBA");
749 (void) UnregisterMagickInfo("BGR");
750 (void) UnregisterMagickInfo("BGRA");
751 (void) UnregisterMagickInfo("BRG");
752 (void) UnregisterMagickInfo("GBR");
753 (void) UnregisterMagickInfo("GRB");
754 (void) UnregisterMagickInfo("RBG");
755 (void) UnregisterMagickInfo("RGB");
759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763 % W r i t e R G B I m a g e %
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769 % WriteRGBImage() writes an image to a file in the RGB or RGBA rasterfile
772 % The format of the WriteRGBImage method is:
774 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
776 % A description of each parameter follows.
778 % o image_info: the image info.
780 % o image: The image.
783 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
817 Allocate memory for pixels.
819 assert(image_info != (const ImageInfo *) NULL);
820 assert(image_info->signature == MagickSignature);
821 assert(image != (Image *) NULL);
822 assert(image->signature == MagickSignature);
823 if (image->debug != MagickFalse)
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
825 if (image_info->interlace != PartitionInterlace)
828 Open output image file.
830 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
831 if (status == MagickFalse)
834 quantum_type=RGBQuantum;
836 if (LocaleCompare(image_info->magick,"RGBA") == 0)
838 quantum_type=RGBAQuantum;
839 image->matte=MagickTrue;
842 if (LocaleCompare(image_info->magick,"RGBO") == 0)
844 quantum_type=RGBOQuantum;
845 image->matte=MagickTrue;
848 for (i=0; i < (ssize_t) channels; i++)
850 switch (image_info->magick[i])
852 case 'R': quantum_types[i]=RedQuantum; break;
853 case 'G': quantum_types[i]=GreenQuantum; break;
854 case 'B': quantum_types[i]=BlueQuantum; break;
855 case 'A': quantum_types[i]=AlphaQuantum; break;
856 case 'O': quantum_types[i]=OpacityQuantum; break;
863 Convert MIFF to RGB raster pixels.
865 if (image->colorspace != RGBColorspace)
866 (void) TransformImageColorspace(image,RGBColorspace);
867 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
868 (image->matte == MagickFalse))
869 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
870 quantum_info=AcquireQuantumInfo(image_info,image);
871 if (quantum_info == (QuantumInfo *) NULL)
872 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
873 pixels=GetQuantumPixels(quantum_info);
874 switch (image_info->interlace)
889 No interlacing: RGBRGBRGBRGBRGBRGB...
891 image_view=AcquireCacheView(image);
892 for (y=0; y < (ssize_t) image->rows; y++)
900 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
902 if (q == (PixelPacket *) NULL)
904 for (x=0; x < (ssize_t) image->columns; x++)
910 for (i=0; i < 3; i++)
911 switch (quantum_types[i])
913 case RedQuantum: *qx[i]=px.red; break;
914 case GreenQuantum: *qx[i]=px.green; break;
915 case BlueQuantum: *qx[i]=px.blue; break;
920 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
921 pixels,&image->exception);
922 count=WriteBlob(image,length,pixels);
923 if (count != (ssize_t) length)
925 if (image->previous == (Image *) NULL)
927 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
929 if (status == MagickFalse)
933 image_view=DestroyCacheView(image_view);
939 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
941 for (y=0; y < (ssize_t) image->rows; y++)
943 register const PixelPacket
946 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
947 if (p == (const PixelPacket *) NULL)
949 for (i=0; i < (ssize_t) channels; i++)
951 length=ExportQuantumPixels(image,(const CacheView *) NULL,
952 quantum_info,quantum_types[i],pixels,&image->exception);
953 count=WriteBlob(image,length,pixels);
954 if (count != (ssize_t) length)
957 if (image->previous == (Image *) NULL)
959 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
961 if (status == MagickFalse)
970 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
972 for (i=0; i < (ssize_t) channels; i++)
974 for (y=0; y < (ssize_t) image->rows; y++)
976 register const PixelPacket
979 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
980 if (p == (const PixelPacket *) NULL)
982 length=ExportQuantumPixels(image,(const CacheView *) NULL,
983 quantum_info,quantum_types[i],pixels,&image->exception);
984 count=WriteBlob(image,length,pixels);
985 if (count != (ssize_t) length)
988 if (image->previous == (Image *) NULL)
990 status=SetImageProgress(image,SaveImageTag,(i+1),5);
991 if (status == MagickFalse)
995 if (image->previous == (Image *) NULL)
997 status=SetImageProgress(image,SaveImageTag,5,5);
998 if (status == MagickFalse)
1003 case PartitionInterlace:
1009 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
1011 for (i=0; i < (ssize_t) channels; i++)
1013 sfx[0]=image_info->magick[i];
1014 AppendImageFormat(sfx,image->filename);
1015 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1016 AppendBinaryBlobMode,&image->exception);
1017 if (status == MagickFalse)
1019 for (y=0; y < (ssize_t) image->rows; y++)
1021 register const PixelPacket
1024 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
1025 if (p == (const PixelPacket *) NULL)
1027 length=ExportQuantumPixels(image,(const CacheView *) NULL,
1028 quantum_info,quantum_types[i],pixels,&image->exception);
1029 count=WriteBlob(image,length,pixels);
1030 if (count != (ssize_t) length)
1033 if (image->previous == (Image *) NULL)
1035 status=SetImageProgress(image,SaveImageTag,(i+1),5);
1036 if (status == MagickFalse)
1039 (void) CloseBlob(image);
1041 (void) CopyMagickString(image->filename,image_info->filename,
1043 if (image->previous == (Image *) NULL)
1045 status=SetImageProgress(image,SaveImageTag,5,5);
1046 if (status == MagickFalse)
1052 quantum_info=DestroyQuantumInfo(quantum_info);
1053 if (GetNextImageInList(image) == (Image *) NULL)
1055 image=SyncNextImageInList(image);
1056 status=SetImageProgress(image,SaveImagesTag,scene++,
1057 GetImageListLength(image));
1058 if (status == MagickFalse)
1060 } while (image_info->adjoin != MagickFalse);
1061 (void) CloseBlob(image);