2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Raw GRAY Image Format %
20 % Copyright 1999-2019 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 % https://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 "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache.h"
46 #include "MagickCore/channel.h"
47 #include "MagickCore/colorspace.h"
48 #include "MagickCore/colorspace-private.h"
49 #include "MagickCore/constitute.h"
50 #include "MagickCore/exception.h"
51 #include "MagickCore/exception-private.h"
52 #include "MagickCore/image.h"
53 #include "MagickCore/image-private.h"
54 #include "MagickCore/list.h"
55 #include "MagickCore/magick.h"
56 #include "MagickCore/memory_.h"
57 #include "MagickCore/monitor.h"
58 #include "MagickCore/monitor-private.h"
59 #include "MagickCore/pixel-accessor.h"
60 #include "MagickCore/quantum-private.h"
61 #include "MagickCore/static.h"
62 #include "MagickCore/statistic.h"
63 #include "MagickCore/string_.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/utility.h"
70 static MagickBooleanType
71 WriteGRAYImage(const ImageInfo *,Image *,ExceptionInfo *);
74 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % R e a d G R A Y I m a g e %
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84 % ReadGRAYImage() reads an image of raw GRAY samples and returns it. It
85 % allocates the memory necessary for the new Image structure and returns a
86 % pointer to the new image.
88 % The format of the ReadGRAYImage method is:
90 % Image *ReadGRAYImage(const ImageInfo *image_info,
91 % ExceptionInfo *exception)
93 % A description of each parameter follows:
95 % o image_info: the image info.
97 % o exception: return any errors or warnings in this structure.
100 static Image *ReadGRAYImage(const ImageInfo *image_info,
101 ExceptionInfo *exception)
138 assert(image_info != (const ImageInfo *) NULL);
139 assert(image_info->signature == MagickCoreSignature);
140 if (image_info->debug != MagickFalse)
141 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
142 image_info->filename);
143 assert(exception != (ExceptionInfo *) NULL);
144 assert(exception->signature == MagickCoreSignature);
145 image=AcquireImage(image_info,exception);
146 if ((image->columns == 0) || (image->rows == 0))
147 ThrowReaderException(OptionError,"MustSpecifyImageSize");
148 image->colorspace=GRAYColorspace;
149 if (image_info->interlace != PartitionInterlace)
151 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
152 if (status == MagickFalse)
154 image=DestroyImageList(image);
155 return((Image *) NULL);
157 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
158 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
162 Create virtual canvas to support cropping (i.e. image.rgb[100x100+10+20]).
164 canvas_image=CloneImage(image,image->extract_info.width,1,MagickFalse,
166 if(canvas_image == (Image *) NULL)
167 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
168 (void) SetImageVirtualPixelMethod(canvas_image,BlackVirtualPixelMethod,
170 quantum_info=AcquireQuantumInfo(image_info,canvas_image);
171 if (quantum_info == (QuantumInfo *) NULL)
173 canvas_image=DestroyImage(canvas_image);
174 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
176 quantum_type=GrayQuantum;
177 if (LocaleCompare(image_info->magick,"GRAYA") == 0)
179 quantum_type=GrayAlphaQuantum;
180 image->alpha_trait=BlendPixelTrait;
181 canvas_image->alpha_trait=BlendPixelTrait;
183 pixels=GetQuantumPixels(quantum_info);
184 if (image_info->number_scenes != 0)
185 while (image->scene < image_info->scene)
191 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
192 for (y=0; y < (ssize_t) image->rows; y++)
194 stream=ReadBlobStream(image,length,pixels,&count);
195 if (count != (ssize_t) length)
207 Read pixels to virtual canvas image then push to image.
209 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
210 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
212 status=SetImageExtent(image,image->columns,image->rows,exception);
213 if (status == MagickFalse)
215 switch (image_info->interlace)
221 No interlacing: GGG...
225 length=GetQuantumExtent(canvas_image,quantum_info,quantum_type);
226 stream=ReadBlobStream(image,length,pixels,&count);
228 for (y=0; y < (ssize_t) image->extract_info.height; y++)
230 register const Quantum
239 if (count != (ssize_t) length)
242 ThrowFileException(exception,CorruptImageError,
243 "UnexpectedEndOfFile",image->filename);
246 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
248 if (q == (Quantum *) NULL)
250 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
251 quantum_info,quantum_type,stream,exception);
252 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
254 if (((y-image->extract_info.y) >= 0) &&
255 ((y-image->extract_info.y) < (ssize_t) image->rows))
257 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
258 canvas_image->columns,1,exception);
259 q=QueueAuthenticPixels(image,0,y-image->extract_info.y,
260 image->columns,1,exception);
261 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
263 for (x=0; x < (ssize_t) image->columns; x++)
265 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
266 SetPixelGreen(image,GetPixelGreen(canvas_image,p),q);
267 SetPixelBlue(image,GetPixelBlue(canvas_image,p),q);
268 SetPixelAlpha(image,OpaqueAlpha,q);
269 if (image->alpha_trait != UndefinedPixelTrait)
270 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
271 p+=GetPixelChannels(canvas_image);
272 q+=GetPixelChannels(image);
274 if (SyncAuthenticPixels(image,exception) == MagickFalse)
277 if (image->previous == (Image *) NULL)
279 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
281 if (status == MagickFalse)
284 stream=ReadBlobStream(image,length,pixels,&count);
298 Line interlacing: G...G...G...
302 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
303 stream=ReadBlobStream(image,length,pixels,&count);
305 for (y=0; y < (ssize_t) image->extract_info.height; y++)
307 for (i=0; i < (ssize_t) (image->alpha_trait != UndefinedPixelTrait ? 4 : 3); i++)
309 register const Quantum
318 if (count != (ssize_t) length)
321 ThrowFileException(exception,CorruptImageError,
322 "UnexpectedEndOfFile",image->filename);
325 quantum_type=quantum_types[i];
326 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
328 if (q == (Quantum *) NULL)
330 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
331 quantum_info,quantum_type,stream,exception);
332 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
334 if (((y-image->extract_info.y) >= 0) &&
335 ((y-image->extract_info.y) < (ssize_t) image->rows))
337 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
338 0,canvas_image->columns,1,exception);
339 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
340 image->columns,1,exception);
341 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
343 for (x=0; x < (ssize_t) image->columns; x++)
345 switch (quantum_type)
349 SetPixelGray(image,GetPixelGray(canvas_image,p),q);
354 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
360 p+=GetPixelChannels(canvas_image);
361 q+=GetPixelChannels(image);
363 if (SyncAuthenticPixels(image,exception) == MagickFalse)
366 stream=ReadBlobStream(image,length,pixels,&count);
368 if (image->previous == (Image *) NULL)
370 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
372 if (status == MagickFalse)
381 Plane interlacing: G...G...G...
385 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
386 stream=ReadBlobStream(image,length,pixels,&count);
388 for (y=0; y < (ssize_t) image->extract_info.height; y++)
390 register const Quantum
399 if (count != (ssize_t) length)
402 ThrowFileException(exception,CorruptImageError,
403 "UnexpectedEndOfFile",image->filename);
406 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
408 if (q == (Quantum *) NULL)
410 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
411 quantum_info,RedQuantum,stream,exception);
412 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
414 if (((y-image->extract_info.y) >= 0) &&
415 ((y-image->extract_info.y) < (ssize_t) image->rows))
417 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
418 canvas_image->columns,1,exception);
419 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
420 image->columns,1,exception);
421 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
423 for (x=0; x < (ssize_t) image->columns; x++)
425 SetPixelGray(image,GetPixelGray(canvas_image,p),q);
426 p+=GetPixelChannels(canvas_image);
427 q+=GetPixelChannels(image);
429 if (SyncAuthenticPixels(image,exception) == MagickFalse)
432 stream=ReadBlobStream(image,length,pixels,&count);
434 if (image->previous == (Image *) NULL)
436 status=SetImageProgress(image,LoadImageTag,1,6);
437 if (status == MagickFalse)
440 if (image->alpha_trait != UndefinedPixelTrait)
442 for (y=0; y < (ssize_t) image->extract_info.height; y++)
444 register const Quantum
453 if (count != (ssize_t) length)
456 ThrowFileException(exception,CorruptImageError,
457 "UnexpectedEndOfFile",image->filename);
460 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
462 if (q == (Quantum *) NULL)
464 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
465 quantum_info,AlphaQuantum,stream,exception);
466 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
468 if (((y-image->extract_info.y) >= 0) &&
469 ((y-image->extract_info.y) < (ssize_t) image->rows))
471 p=GetVirtualPixels(canvas_image,
472 canvas_image->extract_info.x,0,canvas_image->columns,1,
474 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
475 image->columns,1,exception);
476 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
478 for (x=0; x < (ssize_t) image->columns; x++)
480 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
481 p+=GetPixelChannels(canvas_image);
482 q+=GetPixelChannels(image);
484 if (SyncAuthenticPixels(image,exception) == MagickFalse)
487 stream=ReadBlobStream(image,length,pixels,&count);
489 if (image->previous == (Image *) NULL)
491 status=SetImageProgress(image,LoadImageTag,5,6);
492 if (status == MagickFalse)
496 if (image->previous == (Image *) NULL)
498 status=SetImageProgress(image,LoadImageTag,6,6);
499 if (status == MagickFalse)
504 case PartitionInterlace:
507 Partition interlacing: G..., G..., G...
509 AppendImageFormat("G",image->filename);
510 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
511 if (status == MagickFalse)
513 if (DiscardBlobBytes(image,(MagickSizeType) image->offset) == MagickFalse)
516 ThrowFileException(exception,CorruptImageError,
517 "UnexpectedEndOfFile",image->filename);
520 length=GetQuantumExtent(canvas_image,quantum_info,RedQuantum);
521 for (i=0; i < (ssize_t) scene; i++)
523 for (y=0; y < (ssize_t) image->extract_info.height; y++)
525 stream=ReadBlobStream(image,length,pixels,&count);
526 if (count != (ssize_t) length)
529 if (count != (ssize_t) length)
532 stream=ReadBlobStream(image,length,pixels,&count);
533 for (y=0; y < (ssize_t) image->extract_info.height; y++)
535 register const Quantum
544 if (count != (ssize_t) length)
547 ThrowFileException(exception,CorruptImageError,
548 "UnexpectedEndOfFile",image->filename);
551 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
553 if (q == (Quantum *) NULL)
555 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
556 quantum_info,RedQuantum,stream,exception);
557 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
559 if (((y-image->extract_info.y) >= 0) &&
560 ((y-image->extract_info.y) < (ssize_t) image->rows))
562 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,0,
563 canvas_image->columns,1,exception);
564 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
565 image->columns,1,exception);
566 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
568 for (x=0; x < (ssize_t) image->columns; x++)
570 SetPixelRed(image,GetPixelRed(canvas_image,p),q);
571 p+=GetPixelChannels(canvas_image);
572 q+=GetPixelChannels(image);
574 if (SyncAuthenticPixels(image,exception) == MagickFalse)
577 stream=ReadBlobStream(image,length,pixels,&count);
579 if (image->previous == (Image *) NULL)
581 status=SetImageProgress(image,LoadImageTag,1,5);
582 if (status == MagickFalse)
585 (void) CloseBlob(image);
586 if (image->alpha_trait != UndefinedPixelTrait)
588 (void) CloseBlob(image);
589 AppendImageFormat("A",image->filename);
590 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
591 if (status == MagickFalse)
593 length=GetQuantumExtent(canvas_image,quantum_info,AlphaQuantum);
594 for (i=0; i < (ssize_t) scene; i++)
596 for (y=0; y < (ssize_t) image->extract_info.height; y++)
598 stream=ReadBlobStream(image,length,pixels,&count);
599 if (count != (ssize_t) length)
602 if (count != (ssize_t) length)
605 stream=ReadBlobStream(image,length,pixels,&count);
606 for (y=0; y < (ssize_t) image->extract_info.height; y++)
608 register const Quantum
617 if (count != (ssize_t) length)
620 ThrowFileException(exception,CorruptImageError,
621 "UnexpectedEndOfFile",image->filename);
624 q=GetAuthenticPixels(canvas_image,0,0,canvas_image->columns,1,
626 if (q == (Quantum *) NULL)
628 length=ImportQuantumPixels(canvas_image,(CacheView *) NULL,
629 quantum_info,BlueQuantum,stream,exception);
630 if (SyncAuthenticPixels(canvas_image,exception) == MagickFalse)
632 if (((y-image->extract_info.y) >= 0) &&
633 ((y-image->extract_info.y) < (ssize_t) image->rows))
635 p=GetVirtualPixels(canvas_image,canvas_image->extract_info.x,
636 0,canvas_image->columns,1,exception);
637 q=GetAuthenticPixels(image,0,y-image->extract_info.y,
638 image->columns,1,exception);
639 if ((p == (const Quantum *) NULL) || (q == (Quantum *) NULL))
641 for (x=0; x < (ssize_t) image->columns; x++)
643 SetPixelAlpha(image,GetPixelAlpha(canvas_image,p),q);
644 p+=GetPixelChannels(canvas_image);
645 q+=GetPixelChannels(image);
647 if (SyncAuthenticPixels(image,exception) == MagickFalse)
650 stream=ReadBlobStream(image,length,pixels,&count);
652 if (image->previous == (Image *) NULL)
654 status=SetImageProgress(image,LoadImageTag,4,5);
655 if (status == MagickFalse)
659 (void) CloseBlob(image);
660 if (image->previous == (Image *) NULL)
662 status=SetImageProgress(image,LoadImageTag,5,5);
663 if (status == MagickFalse)
669 if (status == MagickFalse)
671 SetQuantumImageType(image,quantum_type);
673 Proceed to next image.
675 if (image_info->number_scenes != 0)
676 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
678 if (count == (ssize_t) length)
681 Allocate next image structure.
683 AcquireNextImage(image_info,image,exception);
684 if (GetNextImageInList(image) == (Image *) NULL)
689 image=SyncNextImageInList(image);
690 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
692 if (status == MagickFalse)
696 } while (count == (ssize_t) length);
697 quantum_info=DestroyQuantumInfo(quantum_info);
698 canvas_image=DestroyImage(canvas_image);
699 (void) CloseBlob(image);
700 if (status == MagickFalse)
701 return(DestroyImageList(image));
702 return(GetFirstImageInList(image));
706 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % R e g i s t e r G R A Y I m a g e %
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716 % RegisterGRAYImage() adds attributes for the GRAY image format to
717 % the list of supported formats. The attributes include the image format
718 % tag, a method to read and/or write the format, whether the format
719 % supports the saving of more than one frame to the same file or blob,
720 % whether the format supports native in-memory I/O, and a brief
721 % description of the format.
723 % The format of the RegisterGRAYImage method is:
725 % size_t RegisterGRAYImage(void)
728 ModuleExport size_t RegisterGRAYImage(void)
733 entry=AcquireMagickInfo("GRAY","GRAY","Raw gray samples");
734 entry->decoder=(DecodeImageHandler *) ReadGRAYImage;
735 entry->encoder=(EncodeImageHandler *) WriteGRAYImage;
736 entry->flags|=CoderRawSupportFlag;
737 entry->flags|=CoderEndianSupportFlag;
738 (void) RegisterMagickInfo(entry);
739 entry=AcquireMagickInfo("GRAY","GRAYA","Raw gray and alpha samples");
740 entry->decoder=(DecodeImageHandler *) ReadGRAYImage;
741 entry->encoder=(EncodeImageHandler *) WriteGRAYImage;
742 entry->flags|=CoderRawSupportFlag;
743 entry->flags|=CoderEndianSupportFlag;
744 (void) RegisterMagickInfo(entry);
745 return(MagickImageCoderSignature);
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
753 % U n r e g i s t e r G R A Y I m a g e %
757 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 % UnregisterGRAYImage() removes format registrations made by the GRAY module
760 % from the list of supported formats.
762 % The format of the UnregisterGRAYImage method is:
764 % UnregisterGRAYImage(void)
767 ModuleExport void UnregisterGRAYImage(void)
769 (void) UnregisterMagickInfo("GRAYA");
770 (void) UnregisterMagickInfo("GRAY");
774 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778 % W r i t e G R A Y I m a g e %
782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784 % WriteGRAYImage() writes an image to a file in the GRAY, GRAYAlpha, or GRAYO
787 % The format of the WriteGRAYImage method is:
789 % MagickBooleanType WriteGRAYImage(const ImageInfo *image_info,
790 % Image *image,ExceptionInfo *exception)
792 % A description of each parameter follows.
794 % o image_info: the image info.
796 % o image: The image.
798 % o exception: return any errors or warnings in this structure.
801 static MagickBooleanType WriteGRAYImage(const ImageInfo *image_info,
802 Image *image,ExceptionInfo *exception)
828 Allocate memory for pixels.
830 assert(image_info != (const ImageInfo *) NULL);
831 assert(image_info->signature == MagickCoreSignature);
832 assert(image != (Image *) NULL);
833 assert(image->signature == MagickCoreSignature);
834 if (image->debug != MagickFalse)
835 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
836 if (image_info->interlace != PartitionInterlace)
839 Open output image file.
841 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
842 if (status == MagickFalse)
845 quantum_type=GrayQuantum;
846 if (LocaleCompare(image_info->magick,"GRAYA") == 0)
847 quantum_type=GrayAlphaQuantum;
849 imageListLength=GetImageListLength(image);
853 Convert MIFF to GRAY raster pixels.
855 (void) TransformImageColorspace(image,GRAYColorspace,exception);
856 if ((LocaleCompare(image_info->magick,"GRAYA") == 0) &&
857 (image->alpha_trait == UndefinedPixelTrait))
858 (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception);
859 quantum_info=AcquireQuantumInfo(image_info,image);
860 if (quantum_info == (QuantumInfo *) NULL)
861 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
862 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
863 switch (image_info->interlace)
869 No interlacing: GGG...
871 for (y=0; y < (ssize_t) image->rows; y++)
873 register const Quantum
876 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
877 if (p == (const Quantum *) NULL)
879 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
880 quantum_type,pixels,exception);
881 count=WriteBlob(image,length,pixels);
882 if (count != (ssize_t) length)
884 if (image->previous == (Image *) NULL)
886 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
888 if (status == MagickFalse)
897 Line interlacing: G...G...G...
899 for (y=0; y < (ssize_t) image->rows; y++)
901 register const Quantum
904 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
905 if (p == (const Quantum *) NULL)
907 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
908 GrayQuantum,pixels,exception);
909 count=WriteBlob(image,length,pixels);
910 if (count != (ssize_t) length)
912 if (quantum_type == GrayAlphaQuantum)
914 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
915 AlphaQuantum,pixels,exception);
916 count=WriteBlob(image,length,pixels);
917 if (count != (ssize_t) length)
920 if (image->previous == (Image *) NULL)
922 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
924 if (status == MagickFalse)
933 Plane interlacing: G...G...G...
935 for (y=0; y < (ssize_t) image->rows; y++)
937 register const Quantum
940 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
941 if (p == (const Quantum *) NULL)
943 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
944 GrayQuantum,pixels,exception);
945 count=WriteBlob(image,length,pixels);
946 if (count != (ssize_t) length)
949 if (image->previous == (Image *) NULL)
951 status=SetImageProgress(image,SaveImageTag,1,6);
952 if (status == MagickFalse)
955 if (quantum_type == GrayAlphaQuantum)
957 for (y=0; y < (ssize_t) image->rows; y++)
959 register const Quantum
962 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
963 if (p == (const Quantum *) NULL)
965 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
966 AlphaQuantum,pixels,exception);
967 count=WriteBlob(image,length,pixels);
968 if (count != (ssize_t) length)
971 if (image->previous == (Image *) NULL)
973 status=SetImageProgress(image,SaveImageTag,5,6);
974 if (status == MagickFalse)
978 if (image_info->interlace == PartitionInterlace)
979 (void) CopyMagickString(image->filename,image_info->filename,
981 if (image->previous == (Image *) NULL)
983 status=SetImageProgress(image,SaveImageTag,6,6);
984 if (status == MagickFalse)
989 case PartitionInterlace:
992 Partition interlacing: G..., G..., G...
994 AppendImageFormat("G",image->filename);
995 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
996 AppendBinaryBlobMode,exception);
997 if (status == MagickFalse)
999 for (y=0; y < (ssize_t) image->rows; y++)
1001 register const Quantum
1004 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1005 if (p == (const Quantum *) NULL)
1007 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1008 RedQuantum,pixels,exception);
1009 count=WriteBlob(image,length,pixels);
1010 if (count != (ssize_t) length)
1013 if (image->previous == (Image *) NULL)
1015 status=SetImageProgress(image,SaveImageTag,1,6);
1016 if (status == MagickFalse)
1019 (void) CloseBlob(image);
1020 if (quantum_type == GrayAlphaQuantum)
1022 (void) CloseBlob(image);
1023 AppendImageFormat("A",image->filename);
1024 status=OpenBlob(image_info,image,scene == 0 ? WriteBinaryBlobMode :
1025 AppendBinaryBlobMode,exception);
1026 if (status == MagickFalse)
1028 for (y=0; y < (ssize_t) image->rows; y++)
1030 register const Quantum
1033 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
1034 if (p == (const Quantum *) NULL)
1036 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1037 AlphaQuantum,pixels,exception);
1038 count=WriteBlob(image,length,pixels);
1039 if (count != (ssize_t) length)
1042 if (image->previous == (Image *) NULL)
1044 status=SetImageProgress(image,SaveImageTag,5,6);
1045 if (status == MagickFalse)
1049 (void) CloseBlob(image);
1050 (void) CopyMagickString(image->filename,image_info->filename,
1052 if (image->previous == (Image *) NULL)
1054 status=SetImageProgress(image,SaveImageTag,6,6);
1055 if (status == MagickFalse)
1061 quantum_info=DestroyQuantumInfo(quantum_info);
1062 if (GetNextImageInList(image) == (Image *) NULL)
1064 image=SyncNextImageInList(image);
1065 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
1066 if (status == MagickFalse)
1068 } while (image_info->adjoin != MagickFalse);
1069 (void) CloseBlob(image);