2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Read/Write Sun Rasterfile Image Format %
20 % Copyright 1999-2010 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/color.h"
47 #include "magick/color-private.h"
48 #include "magick/colorspace.h"
49 #include "magick/exception.h"
50 #include "magick/exception-private.h"
51 #include "magick/image.h"
52 #include "magick/image-private.h"
53 #include "magick/list.h"
54 #include "magick/magick.h"
55 #include "magick/memory_.h"
56 #include "magick/monitor.h"
57 #include "magick/monitor-private.h"
58 #include "magick/quantum-private.h"
59 #include "magick/static.h"
60 #include "magick/string_.h"
61 #include "magick/module.h"
66 static MagickBooleanType
67 WriteSUNImage(const ImageInfo *,Image *);
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 % IsSUN() returns MagickTrue if the image format type, identified by the
81 % magick string, is SUN.
83 % The format of the IsSUN method is:
85 % MagickBooleanType IsSUN(const unsigned char *magick,const size_t length)
87 % A description of each parameter follows:
89 % o magick: compare image format pattern against these bytes.
91 % o length: Specifies the length of the magick string.
94 static MagickBooleanType IsSUN(const unsigned char *magick,const size_t length)
98 if (memcmp(magick,"\131\246\152\225",4) == 0)
104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 % D e c o d e I m a g e %
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 % DecodeImage unpacks the packed image pixels into runlength-encoded pixel
117 % The format of the DecodeImage method is:
119 % MagickBooleanType DecodeImage(const unsigned char *compressed_pixels,
120 % const size_t length,unsigned char *pixels)
122 % A description of each parameter follows:
124 % o compressed_pixels: The address of a byte (8 bits) array of compressed
127 % o length: An integer value that is the total number of bytes of the
128 % source image (as just read by ReadBlob)
130 % o pixels: The address of a byte (8 bits) array of pixel data created by
131 % the uncompression process. The number of bytes in this array
132 % must be at least equal to the number columns times the number of rows
133 % of the source pixels.
136 static MagickBooleanType DecodeImage(const unsigned char *compressed_pixels,
137 const size_t length,unsigned char *pixels,size_t maxpixels)
139 register const unsigned char
142 register unsigned char
151 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
152 assert(compressed_pixels != (unsigned char *) NULL);
153 assert(pixels != (unsigned char *) NULL);
157 while (((size_t) (p-compressed_pixels) < length) && (q < l))
165 Runlength-encoded packet: <count><byte>
167 count=(ssize_t) (*p++);
170 while ((count >= 0) && (q < l))
181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 % R e a d S U N I m a g e %
189 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191 % ReadSUNImage() reads a SUN image file and returns it. It allocates
192 % the memory necessary for the new Image structure and returns a pointer to
195 % The format of the ReadSUNImage method is:
197 % Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
199 % A description of each parameter follows:
201 % o image_info: the image info.
203 % o exception: return any errors or warnings in this structure.
206 static Image *ReadSUNImage(const ImageInfo *image_info,ExceptionInfo *exception)
208 #define RMT_EQUAL_RGB 1
211 #define RT_STANDARD 1
213 #define RT_FORMAT_RGB 3
215 typedef struct _SUNInfo
255 register unsigned char
277 assert(image_info != (const ImageInfo *) NULL);
278 assert(image_info->signature == MagickSignature);
279 if (image_info->debug != MagickFalse)
280 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
281 image_info->filename);
282 assert(exception != (ExceptionInfo *) NULL);
283 assert(exception->signature == MagickSignature);
284 image=AcquireImage(image_info);
285 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
286 if (status == MagickFalse)
288 image=DestroyImageList(image);
289 return((Image *) NULL);
292 Read SUN raster header.
294 (void) ResetMagickMemory(&sun_info,0,sizeof(sun_info));
295 sun_info.magic=ReadBlobMSBLong(image);
299 Verify SUN identifier.
301 if (sun_info.magic != 0x59a66a95)
302 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
303 sun_info.width=ReadBlobMSBLong(image);
304 sun_info.height=ReadBlobMSBLong(image);
305 sun_info.depth=ReadBlobMSBLong(image);
306 sun_info.length=ReadBlobMSBLong(image);
307 sun_info.type=ReadBlobMSBLong(image);
308 sun_info.maptype=ReadBlobMSBLong(image);
309 sun_info.maplength=ReadBlobMSBLong(image);
310 image->columns=sun_info.width;
311 image->rows=sun_info.height;
312 if ((sun_info.depth == 0) || (sun_info.depth > 32))
313 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
314 image->depth=sun_info.depth <= 8 ? sun_info.depth :
315 MAGICKCORE_QUANTUM_DEPTH;
316 if (sun_info.depth < 24)
318 image->storage_class=PseudoClass;
319 image->colors=sun_info.maplength;
320 if (sun_info.maptype == RMT_NONE)
321 image->colors=1 << sun_info.depth;
322 if (sun_info.maptype == RMT_EQUAL_RGB)
323 image->colors=sun_info.maplength/3;
325 switch (sun_info.maptype)
329 if (sun_info.depth < 24)
332 Create linear color ramp.
334 if (AcquireImageColormap(image,image->colors) == MagickFalse)
335 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
345 Read SUN raster colormap.
347 if (AcquireImageColormap(image,image->colors) == MagickFalse)
348 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
349 sun_colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
350 sizeof(*sun_colormap));
351 if (sun_colormap == (unsigned char *) NULL)
352 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
353 count=ReadBlob(image,image->colors,sun_colormap);
354 for (i=0; i < (long) image->colors; i++)
355 image->colormap[i].red=ScaleCharToQuantum(sun_colormap[i]);
356 count=ReadBlob(image,image->colors,sun_colormap);
357 for (i=0; i < (long) image->colors; i++)
358 image->colormap[i].green=ScaleCharToQuantum(sun_colormap[i]);
359 count=ReadBlob(image,image->colors,sun_colormap);
360 for (i=0; i < (long) image->colors; i++)
361 image->colormap[i].blue=ScaleCharToQuantum(sun_colormap[i]);
362 sun_colormap=(unsigned char *) RelinquishMagickMemory(sun_colormap);
371 Read SUN raster colormap.
373 sun_colormap=(unsigned char *) AcquireQuantumMemory(sun_info.maplength,
374 sizeof(*sun_colormap));
375 if (sun_colormap == (unsigned char *) NULL)
376 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
377 count=ReadBlob(image,sun_info.maplength,sun_colormap);
378 sun_colormap=(unsigned char *) RelinquishMagickMemory(sun_colormap);
382 ThrowReaderException(CoderError,"ColormapTypeNotSupported");
384 image->matte=sun_info.depth == 32 ? MagickTrue : MagickFalse;
385 image->columns=sun_info.width;
386 image->rows=sun_info.height;
387 if (image_info->ping != MagickFalse)
389 (void) CloseBlob(image);
390 return(GetFirstImageInList(image));
392 if ((sun_info.length*sizeof(*sun_data))/sizeof(*sun_data) !=
393 sun_info.length || !sun_info.length)
394 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
395 number_pixels=(MagickSizeType) image->columns*image->rows;
396 if ((sun_info.depth >= 8) &&
397 ((number_pixels*((sun_info.depth+7)/8)) > sun_info.length))
398 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
399 sun_data=(unsigned char *) AcquireQuantumMemory((size_t) sun_info.length,
401 if (sun_data == (unsigned char *) NULL)
402 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
403 count=(ssize_t) ReadBlob(image,sun_info.length,sun_data);
404 if ((count == 0) && (sun_info.type != RT_ENCODED))
405 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
408 if (sun_info.type == RT_ENCODED)
414 Read run-length encoded raster pixels.
416 height=sun_info.height;
417 bytes_per_line=sun_info.width*sun_info.depth;
418 if ((height == 0) || (sun_info.width == 0) || (sun_info.depth == 0) ||
419 ((bytes_per_line/sun_info.depth) != sun_info.width))
420 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
423 if ((bytes_per_line >> 1) != (sun_info.width*sun_info.depth+15))
424 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
426 sun_pixels=(unsigned char *) AcquireQuantumMemory(height,
427 bytes_per_line*sizeof(*sun_pixels));
428 if (sun_pixels == (unsigned char *) NULL)
429 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
430 (void) DecodeImage(sun_data,sun_info.length,sun_pixels,
431 bytes_per_line*height);
432 sun_data=(unsigned char *) RelinquishMagickMemory(sun_data);
435 Convert SUN raster image to pixel packets.
438 if (sun_info.depth == 1)
439 for (y=0; y < (long) image->rows; y++)
441 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
442 if (q == (PixelPacket *) NULL)
444 indexes=GetAuthenticIndexQueue(image);
445 for (x=0; x < ((long) image->columns-7); x+=8)
447 for (bit=7; bit >= 0; bit--)
448 indexes[x+7-bit]=(IndexPacket) ((*p) & (0x01 << bit) ? 0x00 : 0x01);
451 if ((image->columns % 8) != 0)
453 for (bit=7; bit >= (long) (8-(image->columns % 8)); bit--)
454 indexes[x+7-bit]=(IndexPacket)
455 ((*p) & (0x01 << bit) ? 0x00 : 0x01);
458 if ((((image->columns/8)+(image->columns % 8 ? 1 : 0)) % 2) != 0)
460 if (SyncAuthenticPixels(image,exception) == MagickFalse)
462 if (image->previous == (Image *) NULL)
464 status=SetImageProgress(image,LoadImageTag,y,image->rows);
465 if (status == MagickFalse)
470 if (image->storage_class == PseudoClass)
472 length=image->rows*(image->columns+image->columns % 2);
473 if (((sun_info.type == RT_ENCODED) &&
474 (length > (bytes_per_line*image->rows))) ||
475 ((sun_info.type != RT_ENCODED) && (length > sun_info.length)))
476 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
477 for (y=0; y < (long) image->rows; y++)
479 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
480 if (q == (PixelPacket *) NULL)
482 indexes=GetAuthenticIndexQueue(image);
483 for (x=0; x < (long) image->columns; x++)
484 indexes[x]=(IndexPacket) (*p++);
485 if ((image->columns % 2) != 0)
487 if (SyncAuthenticPixels(image,exception) == MagickFalse)
489 if (image->previous == (Image *) NULL)
491 status=SetImageProgress(image,LoadImageTag,y,image->rows);
492 if (status == MagickFalse)
503 if (image->matte != MagickFalse)
505 length=image->rows*((bytes_per_line*image->columns)+
507 if (((sun_info.type == RT_ENCODED) &&
508 (length > (bytes_per_line*image->rows))) ||
509 ((sun_info.type != RT_ENCODED) && (length > sun_info.length)))
510 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
511 for (y=0; y < (long) image->rows; y++)
513 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
514 if (q == (PixelPacket *) NULL)
516 for (x=0; x < (long) image->columns; x++)
518 if (image->matte != MagickFalse)
519 q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
520 if (sun_info.type == RT_STANDARD)
522 q->blue=ScaleCharToQuantum(*p++);
523 q->green=ScaleCharToQuantum(*p++);
524 q->red=ScaleCharToQuantum(*p++);
528 q->red=ScaleCharToQuantum(*p++);
529 q->green=ScaleCharToQuantum(*p++);
530 q->blue=ScaleCharToQuantum(*p++);
532 if (image->colors != 0)
534 q->red=image->colormap[(long) q->red].red;
535 q->green=image->colormap[(long) q->green].green;
536 q->blue=image->colormap[(long) q->blue].blue;
540 if (((bytes_per_pixel*image->columns) % 2) != 0)
542 if (SyncAuthenticPixels(image,exception) == MagickFalse)
544 if (image->previous == (Image *) NULL)
546 status=SetImageProgress(image,LoadImageTag,y,image->rows);
547 if (status == MagickFalse)
552 if (image->storage_class == PseudoClass)
553 (void) SyncImage(image);
554 sun_pixels=(unsigned char *) RelinquishMagickMemory(sun_pixels);
555 if (EOFBlob(image) != MagickFalse)
557 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
562 Proceed to next image.
564 if (image_info->number_scenes != 0)
565 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
567 sun_info.magic=ReadBlobMSBLong(image);
568 if (sun_info.magic == 0x59a66a95)
571 Allocate next image structure.
573 AcquireNextImage(image_info,image);
574 if (GetNextImageInList(image) == (Image *) NULL)
576 image=DestroyImageList(image);
577 return((Image *) NULL);
579 image=SyncNextImageInList(image);
580 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
582 if (status == MagickFalse)
585 } while (sun_info.magic == 0x59a66a95);
586 (void) CloseBlob(image);
587 return(GetFirstImageInList(image));
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 % R e g i s t e r S U N I m a g e %
599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 % RegisterSUNImage() adds attributes for the SUN image format to
602 % the list of supported formats. The attributes include the image format
603 % tag, a method to read and/or write the format, whether the format
604 % supports the saving of more than one frame to the same file or blob,
605 % whether the format supports native in-memory I/O, and a brief
606 % description of the format.
608 % The format of the RegisterSUNImage method is:
610 % unsigned long RegisterSUNImage(void)
613 ModuleExport unsigned long RegisterSUNImage(void)
618 entry=SetMagickInfo("RAS");
619 entry->decoder=(DecodeImageHandler *) ReadSUNImage;
620 entry->encoder=(EncodeImageHandler *) WriteSUNImage;
621 entry->magick=(IsImageFormatHandler *) IsSUN;
622 entry->description=ConstantString("SUN Rasterfile");
623 entry->module=ConstantString("SUN");
624 (void) RegisterMagickInfo(entry);
625 entry=SetMagickInfo("SUN");
626 entry->decoder=(DecodeImageHandler *) ReadSUNImage;
627 entry->encoder=(EncodeImageHandler *) WriteSUNImage;
628 entry->description=ConstantString("SUN Rasterfile");
629 entry->module=ConstantString("SUN");
630 (void) RegisterMagickInfo(entry);
631 return(MagickImageCoderSignature);
635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 % U n r e g i s t e r S U N I m a g e %
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 % UnregisterSUNImage() removes format registrations made by the
646 % SUN module from the list of supported formats.
648 % The format of the UnregisterSUNImage method is:
650 % UnregisterSUNImage(void)
653 ModuleExport void UnregisterSUNImage(void)
655 (void) UnregisterMagickInfo("RAS");
656 (void) UnregisterMagickInfo("SUN");
660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 % W r i t e S U N I m a g e %
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 % WriteSUNImage() writes an image in the SUN rasterfile format.
672 % The format of the WriteSUNImage method is:
674 % MagickBooleanType WriteSUNImage(const ImageInfo *image_info,Image *image)
676 % A description of each parameter follows.
678 % o image_info: the image info.
680 % o image: The image.
683 static MagickBooleanType WriteSUNImage(const ImageInfo *image_info,Image *image)
685 #define RMT_EQUAL_RGB 1
688 #define RT_STANDARD 1
689 #define RT_FORMAT_RGB 3
691 typedef struct _SUNInfo
716 register const IndexPacket
719 register const PixelPacket
732 Open output image file.
734 assert(image_info != (const ImageInfo *) NULL);
735 assert(image_info->signature == MagickSignature);
736 assert(image != (Image *) NULL);
737 assert(image->signature == MagickSignature);
738 if (image->debug != MagickFalse)
739 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
740 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
741 if (status == MagickFalse)
747 Initialize SUN raster file header.
749 if (image->colorspace != RGBColorspace)
750 (void) TransformImageColorspace(image,RGBColorspace);
751 sun_info.magic=0x59a66a95;
752 if ((image->columns != (unsigned int) image->columns) ||
753 (image->rows != (unsigned int) image->rows))
754 ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
755 sun_info.width=(unsigned int) image->columns;
756 sun_info.height=(unsigned int) image->rows;
757 sun_info.type=(unsigned int)
758 (image->storage_class == DirectClass ? RT_FORMAT_RGB : RT_STANDARD);
759 sun_info.maptype=RMT_NONE;
760 sun_info.maplength=0;
761 number_pixels=(MagickSizeType) image->columns*image->rows;
762 if ((4*number_pixels) != (size_t) (4*number_pixels))
763 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
764 if (image->storage_class == DirectClass)
767 Full color SUN raster.
769 sun_info.depth=image->matte ? 32U : 24U;
770 sun_info.length=(unsigned int) ((image->matte ? 4 : 3)*number_pixels);
771 sun_info.length+=sun_info.length & 0x01 ? image->rows : 0;
774 if (IsMonochromeImage(image,&image->exception))
777 Monochrome SUN raster.
780 sun_info.length=(unsigned int) (((image->columns+7) >> 3)*
782 sun_info.length+=((image->columns/8)+(image->columns % 8 ? 1 : 0)) %
788 Colormapped SUN raster.
791 sun_info.length=(unsigned int) number_pixels;
792 sun_info.length+=image->columns & 0x01 ? image->rows : 0;
793 sun_info.maptype=RMT_EQUAL_RGB;
794 sun_info.maplength=(unsigned int) (3*image->colors);
799 (void) WriteBlobMSBLong(image,sun_info.magic);
800 (void) WriteBlobMSBLong(image,sun_info.width);
801 (void) WriteBlobMSBLong(image,sun_info.height);
802 (void) WriteBlobMSBLong(image,sun_info.depth);
803 (void) WriteBlobMSBLong(image,sun_info.length);
804 (void) WriteBlobMSBLong(image,sun_info.type);
805 (void) WriteBlobMSBLong(image,sun_info.maptype);
806 (void) WriteBlobMSBLong(image,sun_info.maplength);
808 Convert MIFF to SUN raster pixels.
812 if (image->storage_class == DirectClass)
814 register unsigned char
825 Allocate memory for pixels.
828 if (image->matte != MagickFalse)
830 length=image->columns;
831 pixels=(unsigned char *) AcquireQuantumMemory(length,4*sizeof(*pixels));
832 if (pixels == (unsigned char *) NULL)
833 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
835 Convert DirectClass packet to SUN RGB pixel.
837 for (y=0; y < (long) image->rows; y++)
839 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
840 if (p == (const PixelPacket *) NULL)
843 for (x=0; x < (long) image->columns; x++)
845 if (image->matte != MagickFalse)
846 *q++=ScaleQuantumToChar((Quantum) (QuantumRange-p->opacity));
847 *q++=ScaleQuantumToChar(p->red);
848 *q++=ScaleQuantumToChar(p->green);
849 *q++=ScaleQuantumToChar(p->blue);
852 if (((bytes_per_pixel*image->columns) & 0x01) != 0)
853 *q++='\0'; /* pad scanline */
854 (void) WriteBlob(image,(size_t) (q-pixels),pixels);
855 if (image->previous == (Image *) NULL)
857 status=SetImageProgress(image,SaveImageTag,y,image->rows);
858 if (status == MagickFalse)
862 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
865 if (IsMonochromeImage(image,&image->exception))
867 register unsigned char
872 Convert PseudoClass image to a SUN monochrome image.
874 (void) SetImageType(image,BilevelType);
875 for (y=0; y < (long) image->rows; y++)
877 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
878 if (p == (const PixelPacket *) NULL)
880 indexes=GetVirtualIndexQueue(image);
883 for (x=0; x < (long) image->columns; x++)
886 if (PixelIntensity(p) < (MagickRealType) (QuantumRange/2.0))
891 (void) WriteBlobByte(image,byte);
898 (void) WriteBlobByte(image,(unsigned char) (byte << (8-bit)));
899 if ((((image->columns/8)+
900 (image->columns % 8 ? 1 : 0)) % 2) != 0)
901 (void) WriteBlobByte(image,0); /* pad scanline */
902 if (image->previous == (Image *) NULL)
904 status=SetImageProgress(image,SaveImageTag,y,image->rows);
905 if (status == MagickFalse)
913 Dump colormap to file.
915 for (i=0; i < (long) image->colors; i++)
916 (void) WriteBlobByte(image,
917 ScaleQuantumToChar(image->colormap[i].red));
918 for (i=0; i < (long) image->colors; i++)
919 (void) WriteBlobByte(image,
920 ScaleQuantumToChar(image->colormap[i].green));
921 for (i=0; i < (long) image->colors; i++)
922 (void) WriteBlobByte(image,
923 ScaleQuantumToChar(image->colormap[i].blue));
925 Convert PseudoClass packet to SUN colormapped pixel.
927 for (y=0; y < (long) image->rows; y++)
929 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
930 if (p == (const PixelPacket *) NULL)
932 indexes=GetVirtualIndexQueue(image);
933 for (x=0; x < (long) image->columns; x++)
935 (void) WriteBlobByte(image,(unsigned char) indexes[x]);
938 if (image->columns & 0x01)
939 (void) WriteBlobByte(image,0); /* pad scanline */
940 if (image->previous == (Image *) NULL)
942 status=SetImageProgress(image,SaveImageTag,y,image->rows);
943 if (status == MagickFalse)
948 if (GetNextImageInList(image) == (Image *) NULL)
950 image=SyncNextImageInList(image);
951 status=SetImageProgress(image,SaveImagesTag,scene++,
952 GetImageListLength(image));
953 if (status == MagickFalse)
955 } while (image_info->adjoin != MagickFalse);
956 (void) CloseBlob(image);