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 if (LocaleCompare(image_info->magick,"RGBO") == 0)
191 quantum_type=RGBOQuantum;
192 image->matte=MagickTrue;
195 if (image_info->number_scenes != 0)
196 while (image->scene < image_info->scene)
202 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
203 for (y=0; y < (long) image->rows; y++)
205 count=ReadBlob(image,length,pixels);
206 if (count != (ssize_t) length)
210 for (i=0; i < channels; i++)
212 switch(image_info->magick[i])
214 case 'R': quantum_types[i]=RedQuantum; break;
215 case 'G': quantum_types[i]=GreenQuantum; break;
216 case 'B': quantum_types[i]=BlueQuantum; break;
217 case 'A': quantum_types[i]=AlphaQuantum; break;
218 case 'O': quantum_types[i]=OpacityQuantum; break;
227 Read pixels to virtual canvas image then push to image.
229 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
230 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
232 switch (image_info->interlace)
238 No interlacing: RGBRGBRGBRGBRGBRGB...
242 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
243 count=ReadBlob(image,length,pixels);
244 if (count != (ssize_t) length)
247 for (y=0; y < (long) image->extract_info.height; y++)
249 register const PixelPacket
258 if (count != (ssize_t) length)
260 ThrowFileException(exception,CorruptImageError,
261 "UnexpectedEndOfFile",image->filename);
264 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
266 if (q == (PixelPacket *) NULL)
268 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
269 quantum_info,quantum_type,pixels,exception);
270 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
272 if (((y-image->extract_info.y) >= 0) &&
273 ((y-image->extract_info.y) < (long) image->rows))
275 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
276 canvas_image->columns,1,exception);
277 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
278 image->columns,1,exception);
279 if ((p == (const PixelPacket *) NULL) ||
280 (q == (PixelPacket *) NULL))
282 for (x=0; x < (long) image->columns; x++)
287 for (i=0; i < 3; i++)
288 switch(quantum_types[i])
290 case RedQuantum: q->red=qx[i]; break;
291 case GreenQuantum: q->green=qx[i]; break;
292 case BlueQuantum: q->blue=qx[i]; break;
295 q->opacity=OpaqueOpacity;
296 if (image->matte != MagickFalse)
297 q->opacity=p->opacity;
301 if (SyncAuthenticPixels(image,exception) == MagickFalse)
304 if (image->previous == (Image *) NULL)
306 status=SetImageProgress(image,LoadImageTag,y,image->rows);
307 if (status == MagickFalse)
310 count=ReadBlob(image,length,pixels);
317 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
321 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
322 count=ReadBlob(image,length,pixels);
324 for (y=0; y < (long) image->extract_info.height; y++)
326 register const PixelPacket
335 if (count != (ssize_t) length)
337 ThrowFileException(exception,CorruptImageError,
338 "UnexpectedEndOfFile",image->filename);
341 for (i=0; i < channels; i++)
343 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
345 if (q == (PixelPacket *) NULL)
347 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
348 quantum_info,quantum_types[i],pixels,exception);
349 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
351 if (((y-image->extract_info.y) >= 0) &&
352 ((y-image->extract_info.y) < (long) image->rows))
354 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
355 0,canvas_image->columns,1,exception);
356 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
357 image->columns,1,exception);
358 if ((p == (const PixelPacket *) NULL) ||
359 (q == (PixelPacket *) NULL))
361 if (i == (channels - 1))
362 for (x=0; x < (long) image->columns; x++)
367 q->opacity=p->opacity;
371 if (SyncAuthenticPixels(image,exception) == MagickFalse)
374 count=ReadBlob(image,length,pixels);
376 if (image->previous == (Image *) NULL)
378 status=SetImageProgress(image,LoadImageTag,y,image->rows);
379 if (status == MagickFalse)
388 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
392 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[0]);
393 count=ReadBlob(image,length,pixels);
395 for (i=0; i < channels; i++)
397 for (y=0; y < (long) image->extract_info.height; y++)
399 register const PixelPacket
408 if (count != (ssize_t) length)
410 ThrowFileException(exception,CorruptImageError,
411 "UnexpectedEndOfFile",image->filename);
414 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
416 if (q == (PixelPacket *) NULL)
418 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
419 quantum_info,quantum_types[i],pixels,exception);
420 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
422 if (((y-image->extract_info.y) >= 0) &&
423 ((y-image->extract_info.y) < (long) image->rows))
425 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
426 canvas_image->columns,1,exception);
427 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
428 image->columns,1,exception);
429 if ((p == (const PixelPacket *) NULL) ||
430 (q == (PixelPacket *) NULL))
432 for (x=0; x < (long) image->columns; x++)
434 switch(quantum_types[i])
436 case RedQuantum: q->red=p->red; break;
437 case GreenQuantum: q->green=p->green; break;
438 case BlueQuantum: q->blue=p->blue; break;
440 case AlphaQuantum: q->opacity=p->opacity; break;
446 if (SyncAuthenticPixels(image,exception) == MagickFalse)
449 count=ReadBlob(image,length,pixels);
451 if (image->previous == (Image *) NULL)
453 status=SetImageProgress(image,LoadImageTag,(i+1),5);
454 if (status == MagickFalse)
458 if (image->previous == (Image *) NULL)
460 status=SetImageProgress(image,LoadImageTag,5,5);
461 if (status == MagickFalse)
466 case PartitionInterlace:
469 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
471 for (i=0; i < channels; i++)
473 sfx[0]=image_info->magick[i];
474 AppendImageFormat(sfx,image->filename);
475 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
476 if (status == MagickFalse)
478 canvas_image=DestroyImageList(canvas_image);
479 image=DestroyImageList(image);
480 return((Image *) NULL);
483 for (j=0; j < image->offset; j++)
484 if (ReadBlobByte(image) == EOF)
486 ThrowFileException(exception,CorruptImageError,
487 "UnexpectedEndOfFile",image->filename);
490 length=GetQuantumExtent(canvas_image,quantum_info,quantum_types[i]);
491 for (j=0; j < (long) scene; j++)
492 for (y=0; y < (long) image->extract_info.height; y++)
493 if (ReadBlob(image,length,pixels) != (ssize_t) length)
495 ThrowFileException(exception,CorruptImageError,
496 "UnexpectedEndOfFile",image->filename);
499 count=ReadBlob(image,length,pixels);
500 for (y=0; y < (long) image->extract_info.height; y++)
502 register const PixelPacket
511 if (count != (ssize_t) length)
513 ThrowFileException(exception,CorruptImageError,
514 "UnexpectedEndOfFile",image->filename);
517 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
519 if (q == (PixelPacket *) NULL)
521 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
522 quantum_info,quantum_types[i],pixels,exception);
523 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
525 if (((y-image->extract_info.y) >= 0) &&
526 ((y-image->extract_info.y) < (long) image->rows))
528 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
529 canvas_image->columns,1,exception);
530 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
531 image->columns,1,exception);
532 if ((p == (const PixelPacket *) NULL) ||
533 (q == (PixelPacket *) NULL))
535 for (x=0; x < (long) image->columns; x++)
537 switch(quantum_types[i])
539 case RedQuantum: q->red=p->red; break;
540 case GreenQuantum: q->green=p->green; break;
541 case BlueQuantum: q->blue=p->blue; break;
543 case AlphaQuantum: q->opacity=p->opacity; break;
549 if (SyncAuthenticPixels(image,exception) == MagickFalse)
552 count=ReadBlob(image,length,pixels);
554 if (image->previous == (Image *) NULL)
556 status=SetImageProgress(image,LoadImageTag,(i+1),5);
557 if (status == MagickFalse)
560 if (i != (channels-1))
561 (void) CloseBlob(image);
563 if (image->previous == (Image *) NULL)
565 status=SetImageProgress(image,LoadImageTag,5,5);
566 if (status == MagickFalse)
572 SetQuantumImageType(image,quantum_type);
574 Proceed to next image.
576 if (image_info->number_scenes != 0)
577 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
579 if (count == (ssize_t) length)
582 Allocate next image structure.
584 AcquireNextImage(image_info,image);
585 if (GetNextImageInList(image) == (Image *) NULL)
587 image=DestroyImageList(image);
588 return((Image *) NULL);
590 image=SyncNextImageInList(image);
591 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
593 if (status == MagickFalse)
597 } while (count == (ssize_t) length);
598 quantum_info=DestroyQuantumInfo(quantum_info);
599 InheritException(&image->exception,&canvas_image->exception);
600 canvas_image=DestroyImage(canvas_image);
601 (void) CloseBlob(image);
602 return(GetFirstImageInList(image));
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 % R e g i s t e r R G B I m a g e %
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616 % RegisterRGBImage() adds attributes for the RGB or RGBA image format to
617 % the list of supported formats. The attributes include the image format
618 % tag, a method to read and/or write the format, whether the format
619 % supports the saving of more than one frame to the same file or blob,
620 % whether the format supports native in-memory I/O, and a brief
621 % description of the format.
623 % The format of the RegisterRGBImage method is:
625 % unsigned long RegisterRGBImage(void)
628 ModuleExport unsigned long RegisterRGBImage(void)
633 entry=SetMagickInfo("RGB");
634 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
635 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
636 entry->raw=MagickTrue;
637 entry->endian_support=MagickTrue;
638 entry->format_type=ExplicitFormatType;
639 entry->description=ConstantString("Raw red, green, and blue samples");
640 entry->module=ConstantString("RGB");
641 (void) RegisterMagickInfo(entry);
642 entry=SetMagickInfo("RBG");
643 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
644 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
645 entry->raw=MagickTrue;
646 entry->endian_support=MagickTrue;
647 entry->format_type=ExplicitFormatType;
648 entry->description=ConstantString("Raw red, blue, and green samples");
649 entry->module=ConstantString("RGB");
650 (void) RegisterMagickInfo(entry);
651 entry=SetMagickInfo("GRB");
652 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
653 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
654 entry->raw=MagickTrue;
655 entry->endian_support=MagickTrue;
656 entry->format_type=ExplicitFormatType;
657 entry->description=ConstantString("Raw green, red, and blue samples");
658 entry->module=ConstantString("RGB");
659 (void) RegisterMagickInfo(entry);
660 entry=SetMagickInfo("GBR");
661 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
662 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
663 entry->raw=MagickTrue;
664 entry->endian_support=MagickTrue;
665 entry->format_type=ExplicitFormatType;
666 entry->description=ConstantString("Raw green, blue, and red samples");
667 entry->module=ConstantString("RGB");
668 (void) RegisterMagickInfo(entry);
669 entry=SetMagickInfo("BRG");
670 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
671 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
672 entry->raw=MagickTrue;
673 entry->endian_support=MagickTrue;
674 entry->format_type=ExplicitFormatType;
675 entry->description=ConstantString("Raw blue, red, and green samples");
676 entry->module=ConstantString("RGB");
677 (void) RegisterMagickInfo(entry);
678 entry=SetMagickInfo("BGR");
679 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
680 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
681 entry->raw=MagickTrue;
682 entry->endian_support=MagickTrue;
683 entry->format_type=ExplicitFormatType;
684 entry->description=ConstantString("Raw blue, green, and red samples");
685 entry->module=ConstantString("RGB");
686 (void) RegisterMagickInfo(entry);
687 entry=SetMagickInfo("RGBA");
688 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
689 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
690 entry->raw=MagickTrue;
691 entry->endian_support=MagickTrue;
692 entry->format_type=ExplicitFormatType;
693 entry->description=ConstantString("Raw red, green, blue, and alpha samples");
694 entry->module=ConstantString("RGB");
695 (void) RegisterMagickInfo(entry);
696 entry=SetMagickInfo("RGBO");
697 entry->decoder=(DecodeImageHandler *) ReadRGBImage;
698 entry->encoder=(EncodeImageHandler *) WriteRGBImage;
699 entry->raw=MagickTrue;
700 entry->endian_support=MagickTrue;
701 entry->format_type=ExplicitFormatType;
702 entry->description=ConstantString("Raw red, green, blue, and opacity "
704 entry->module=ConstantString("RGB");
705 (void) RegisterMagickInfo(entry);
706 return(MagickImageCoderSignature);
710 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714 % U n r e g i s t e r R G B I m a g e %
718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720 % UnregisterRGBImage() removes format registrations made by the
721 % RGB module from the list of supported formats.
723 % The format of the UnregisterRGBImage method is:
725 % UnregisterRGBImage(void)
728 ModuleExport void UnregisterRGBImage(void)
730 (void) UnregisterMagickInfo("RGBO");
731 (void) UnregisterMagickInfo("RGBA");
732 (void) UnregisterMagickInfo("BGR");
733 (void) UnregisterMagickInfo("BRG");
734 (void) UnregisterMagickInfo("GBR");
735 (void) UnregisterMagickInfo("GRB");
736 (void) UnregisterMagickInfo("RBG");
737 (void) UnregisterMagickInfo("RGB");
741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745 % W r i t e R G B I m a g e %
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
751 % WriteRGBImage() writes an image to a file in the RGB or RGBA rasterfile
754 % The format of the WriteRGBImage method is:
756 % MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
758 % A description of each parameter follows.
760 % o image_info: the image info.
762 % o image: The image.
765 static MagickBooleanType WriteRGBImage(const ImageInfo *image_info,Image *image)
799 Allocate memory for pixels.
801 assert(image_info != (const ImageInfo *) NULL);
802 assert(image_info->signature == MagickSignature);
803 assert(image != (Image *) NULL);
804 assert(image->signature == MagickSignature);
805 if (image->debug != MagickFalse)
806 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
807 if (image_info->interlace != PartitionInterlace)
810 Open output image file.
812 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
813 if (status == MagickFalse)
816 quantum_type=RGBQuantum;
818 if (LocaleCompare(image_info->magick,"RGBA") == 0)
820 quantum_type=RGBAQuantum;
821 image->matte=MagickTrue;
824 if (LocaleCompare(image_info->magick,"RGBO") == 0)
826 quantum_type=RGBOQuantum;
827 image->matte=MagickTrue;
830 for (i=0; i < (long) channels; i++)
832 switch (image_info->magick[i])
834 case 'R': quantum_types[i]=RedQuantum; break;
835 case 'G': quantum_types[i]=GreenQuantum; break;
836 case 'B': quantum_types[i]=BlueQuantum; break;
837 case 'A': quantum_types[i]=AlphaQuantum; break;
838 case 'O': quantum_types[i]=OpacityQuantum; break;
845 Convert MIFF to RGB raster pixels.
847 if (image->colorspace != RGBColorspace)
848 (void) TransformImageColorspace(image,RGBColorspace);
849 if ((LocaleCompare(image_info->magick,"RGBA") == 0) &&
850 (image->matte == MagickFalse))
851 (void) SetImageAlphaChannel(image,ResetAlphaChannel);
852 quantum_info=AcquireQuantumInfo(image_info,image);
853 if (quantum_info == (QuantumInfo *) NULL)
854 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
855 pixels=GetQuantumPixels(quantum_info);
856 switch (image_info->interlace)
871 No interlacing: RGBRGBRGBRGBRGBRGB...
873 image_view=AcquireCacheView(image);
874 for (y=0; y < (long) image->rows; y++)
882 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
884 if (q == (PixelPacket *) NULL)
886 for (x=0; x < (long) image->columns; x++)
892 for (i=0; i < 3; i++)
893 switch (quantum_types[i])
895 case RedQuantum: *qx[i]=px.red; break;
896 case GreenQuantum: *qx[i]=px.green; break;
897 case BlueQuantum: *qx[i]=px.blue; break;
902 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
903 pixels,&image->exception);
904 count=WriteBlob(image,length,pixels);
905 if (count != (ssize_t) length)
907 if (image->previous == (Image *) NULL)
909 status=SetImageProgress(image,SaveImageTag,y,image->rows);
910 if (status == MagickFalse)
914 image_view=DestroyCacheView(image_view);
920 Line interlacing: RRR...GGG...BBB...RRR...GGG...BBB...
922 for (y=0; y < (long) image->rows; y++)
924 register const PixelPacket
927 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
928 if (p == (const PixelPacket *) NULL)
930 for (i=0; i < (long) channels; i++)
932 length=ExportQuantumPixels(image,(const CacheView *) NULL,
933 quantum_info,quantum_types[i],pixels,&image->exception);
934 count=WriteBlob(image,length,pixels);
935 if (count != (ssize_t) length)
938 if (image->previous == (Image *) NULL)
940 status=SetImageProgress(image,SaveImageTag,y,image->rows);
941 if (status == MagickFalse)
950 Plane interlacing: RRRRRR...GGGGGG...BBBBBB...
952 for (i=0; i < (long) channels; i++)
954 for (y=0; y < (long) image->rows; y++)
956 register const PixelPacket
959 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
960 if (p == (const PixelPacket *) NULL)
962 length=ExportQuantumPixels(image,(const CacheView *) NULL,
963 quantum_info,quantum_types[i],pixels,&image->exception);
964 count=WriteBlob(image,length,pixels);
965 if (count != (ssize_t) length)
968 if (image->previous == (Image *) NULL)
970 status=SetImageProgress(image,SaveImageTag,(i+1),5);
971 if (status == MagickFalse)
975 if (image->previous == (Image *) NULL)
977 status=SetImageProgress(image,SaveImageTag,5,5);
978 if (status == MagickFalse)
983 case PartitionInterlace:
989 Partition interlacing: RRRRRR..., GGGGGG..., BBBBBB...
991 for (i=0; i < (long) channels; i++)
993 sfx[0]=image_info->magick[i];
994 AppendImageFormat(sfx,image->filename);
995 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
996 AppendBinaryBlobMode,&image->exception);
997 if (status == MagickFalse)
999 for (y=0; y < (long) 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)
1019 (void) CloseBlob(image);
1021 (void) CopyMagickString(image->filename,image_info->filename,
1023 if (image->previous == (Image *) NULL)
1025 status=SetImageProgress(image,SaveImageTag,5,5);
1026 if (status == MagickFalse)
1032 quantum_info=DestroyQuantumInfo(quantum_info);
1033 if (GetNextImageInList(image) == (Image *) NULL)
1035 image=SyncNextImageInList(image);
1036 status=SetImageProgress(image,SaveImagesTag,scene++,
1037 GetImageListLength(image));
1038 if (status == MagickFalse)
1040 } while (image_info->adjoin != MagickFalse);
1041 (void) CloseBlob(image);