2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % M M IIIII FFFFF FFFFF %
13 % Read/Write MIFF 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/attribute.h"
44 #include "MagickCore/blob.h"
45 #include "MagickCore/blob-private.h"
46 #include "MagickCore/cache.h"
47 #include "MagickCore/color.h"
48 #include "MagickCore/color-private.h"
49 #include "MagickCore/colormap.h"
50 #include "MagickCore/colormap-private.h"
51 #include "MagickCore/colorspace.h"
52 #include "MagickCore/colorspace-private.h"
53 #include "MagickCore/constitute.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/geometry.h"
57 #include "MagickCore/image.h"
58 #include "MagickCore/image-private.h"
59 #include "MagickCore/linked-list.h"
60 #include "MagickCore/list.h"
61 #include "MagickCore/magick.h"
62 #include "MagickCore/memory_.h"
63 #include "MagickCore/memory-private.h"
64 #include "MagickCore/module.h"
65 #include "MagickCore/monitor.h"
66 #include "MagickCore/monitor-private.h"
67 #include "MagickCore/option.h"
68 #include "MagickCore/pixel.h"
69 #include "MagickCore/pixel-accessor.h"
70 #include "MagickCore/profile.h"
71 #include "MagickCore/property.h"
72 #include "MagickCore/quantum-private.h"
73 #include "MagickCore/static.h"
74 #include "MagickCore/statistic.h"
75 #include "MagickCore/string_.h"
76 #include "MagickCore/string-private.h"
77 #if defined(MAGICKCORE_BZLIB_DELEGATE)
80 #if defined(MAGICKCORE_LZMA_DELEGATE)
83 #if defined(MAGICKCORE_ZLIB_DELEGATE)
97 static MagickBooleanType
98 WriteMIFFImage(const ImageInfo *,Image *,ExceptionInfo *);
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
111 % IsMIFF() returns MagickTrue if the image format type, identified by the
112 % magick string, is MIFF.
114 % The format of the IsMIFF method is:
116 % MagickBooleanType IsMIFF(const unsigned char *magick,const size_t length)
118 % A description of each parameter follows:
120 % o magick: compare image format pattern against these bytes.
122 % o length: Specifies the length of the magick string.
125 static MagickBooleanType IsMIFF(const unsigned char *magick,const size_t length)
129 if (LocaleNCompare((const char *) magick,"id=ImageMagick",14) == 0)
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 % R e a d M I F F I m a g e %
143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 % ReadMIFFImage() reads a MIFF image file and returns it. It allocates the
146 % memory necessary for the new Image structure and returns a pointer to the
149 % The format of the ReadMIFFImage method is:
151 % Image *ReadMIFFImage(const ImageInfo *image_info,
152 % ExceptionInfo *exception)
154 % Decompression code contributed by Kyle Shorter.
156 % A description of each parameter follows:
158 % o image_info: the image info.
160 % o exception: return any errors or warnings in this structure.
164 #if defined(MAGICKCORE_BZLIB_DELEGATE) || defined(MAGICKCORE_LZMA_DELEGATE) || defined(MAGICKCORE_ZLIB_DELEGATE)
165 static void *AcquireCompressionMemory(void *context,const size_t items,
172 if (HeapOverflowSanityCheck(items,size) != MagickFalse)
173 return((void *) NULL);
175 if (extent > GetMaxMemoryRequest())
176 return((void *) NULL);
177 return(AcquireMagickMemory(extent));
181 #if defined(MAGICKCORE_BZLIB_DELEGATE)
182 static void *AcquireBZIPMemory(void *,int,int) magick_attribute((__malloc__));
184 static void *AcquireBZIPMemory(void *context,int items,int size)
186 return(AcquireCompressionMemory(context,(size_t) items,(size_t) size));
190 #if defined(MAGICKCORE_LZMA_DELEGATE)
191 static void *AcquireLZMAMemory(void *,size_t,size_t)
192 magick_attribute((__malloc__));
194 static void *AcquireLZMAMemory(void *context,size_t items,size_t size)
196 return(AcquireCompressionMemory(context,items,size));
200 #if defined(MAGICKCORE_ZLIB_DELEGATE)
201 static voidpf AcquireZIPMemory(voidpf,unsigned int,unsigned int)
202 magick_attribute((__malloc__));
204 static voidpf AcquireZIPMemory(voidpf context,unsigned int items,
207 return((voidpf) AcquireCompressionMemory(context,(size_t) items,
212 static void PushRunlengthPacket(Image *image,const unsigned char *pixels,
213 size_t *length,PixelInfo *pixel,ExceptionInfo *exception)
219 if (image->storage_class == PseudoClass)
222 switch (image->depth)
227 pixel->index=(MagickRealType) ConstrainColormapIndex(image,(ssize_t)
228 (((size_t) *p << 24) | ((size_t) *(p+1) << 16) |
229 ((size_t) *(p+2) << 8) | (size_t) *(p+3)),exception);
235 pixel->index=(MagickRealType) ConstrainColormapIndex(image,(ssize_t)
236 (((size_t) *p << 8) | (size_t) *(p+1)),exception);
242 pixel->index=(MagickRealType) ConstrainColormapIndex(image,
243 (ssize_t) *p,exception);
248 switch (image->depth)
255 if (image->alpha_trait != UndefinedPixelTrait)
257 p=PushCharPixel(p,&quantum);
258 pixel->alpha=(MagickRealType) ScaleCharToQuantum(quantum);
267 if (image->alpha_trait != UndefinedPixelTrait)
269 p=PushShortPixel(MSBEndian,p,&quantum);
270 pixel->alpha=(MagickRealType) ((size_t) quantum >> (image->depth-
271 MAGICKCORE_QUANTUM_DEPTH));
281 if (image->alpha_trait != UndefinedPixelTrait)
283 p=PushLongPixel(MSBEndian,p,&quantum);
284 pixel->alpha=(MagickRealType) ((size_t) quantum >> (image->depth-
285 MAGICKCORE_QUANTUM_DEPTH));
290 *length=((size_t) *p++)+1;
293 switch (image->depth)
300 p=PushCharPixel(p,&quantum);
301 pixel->red=(MagickRealType) ScaleCharToQuantum(quantum);
302 pixel->green=pixel->red;
303 pixel->blue=pixel->red;
304 if (IsGrayColorspace(image->colorspace) == MagickFalse)
306 p=PushCharPixel(p,&quantum);
307 pixel->green=(MagickRealType) ScaleCharToQuantum(quantum);
308 p=PushCharPixel(p,&quantum);
309 pixel->blue=(MagickRealType) ScaleCharToQuantum(quantum);
311 if (image->colorspace == CMYKColorspace)
313 p=PushCharPixel(p,&quantum);
314 pixel->black=(MagickRealType) ScaleCharToQuantum(quantum);
316 if (image->alpha_trait != UndefinedPixelTrait)
318 p=PushCharPixel(p,&quantum);
319 pixel->alpha=(MagickRealType) ScaleCharToQuantum(quantum);
328 p=PushShortPixel(MSBEndian,p,&quantum);
329 pixel->red=(MagickRealType) ((size_t) quantum >> (image->depth-
330 MAGICKCORE_QUANTUM_DEPTH));
331 pixel->green=pixel->red;
332 pixel->blue=pixel->red;
333 if (IsGrayColorspace(image->colorspace) == MagickFalse)
335 p=PushShortPixel(MSBEndian,p,&quantum);
336 pixel->green=(MagickRealType) ((size_t) quantum >> (image->depth-
337 MAGICKCORE_QUANTUM_DEPTH));
338 p=PushShortPixel(MSBEndian,p,&quantum);
339 pixel->blue=(MagickRealType) ((size_t) quantum >> (image->depth-
340 MAGICKCORE_QUANTUM_DEPTH));
342 if (image->colorspace == CMYKColorspace)
344 p=PushShortPixel(MSBEndian,p,&quantum);
345 pixel->black=(MagickRealType) ((size_t) quantum >> (image->depth-
346 MAGICKCORE_QUANTUM_DEPTH));
348 if (image->alpha_trait != UndefinedPixelTrait)
350 p=PushShortPixel(MSBEndian,p,&quantum);
351 pixel->alpha=(MagickRealType) ((size_t) quantum >> (image->depth-
352 MAGICKCORE_QUANTUM_DEPTH));
362 p=PushLongPixel(MSBEndian,p,&quantum);
363 pixel->red=(MagickRealType) ((size_t) quantum >> (image->depth-
364 MAGICKCORE_QUANTUM_DEPTH));
365 pixel->green=pixel->red;
366 pixel->blue=pixel->red;
367 if (IsGrayColorspace(image->colorspace) == MagickFalse)
369 p=PushLongPixel(MSBEndian,p,&quantum);
370 pixel->green=(MagickRealType) ((size_t) quantum >> (image->depth-
371 MAGICKCORE_QUANTUM_DEPTH));
372 p=PushLongPixel(MSBEndian,p,&quantum);
373 pixel->blue=(MagickRealType) ((size_t) quantum >> (image->depth-
374 MAGICKCORE_QUANTUM_DEPTH));
376 if (image->colorspace == CMYKColorspace)
378 p=PushLongPixel(MSBEndian,p,&quantum);
379 pixel->black=(MagickRealType) ((size_t) quantum >> (image->depth-
380 MAGICKCORE_QUANTUM_DEPTH));
382 if (image->alpha_trait != UndefinedPixelTrait)
384 p=PushLongPixel(MSBEndian,p,&quantum);
385 pixel->alpha=(MagickRealType) ((size_t) quantum >> (image->depth-
386 MAGICKCORE_QUANTUM_DEPTH));
391 *length=(size_t) (*p++)+1;
394 #if defined(MAGICKCORE_BZLIB_DELEGATE)
395 static void RelinquishBZIPMemory(void *context,void *memory)
398 memory=RelinquishMagickMemory(memory);
402 #if defined(MAGICKCORE_LZMA_DELEGATE)
403 static void RelinquishLZMAMemory(void *context,void *memory)
406 memory=RelinquishMagickMemory(memory);
410 #if defined(MAGICKCORE_ZLIB_DELEGATE)
411 static void RelinquishZIPMemory(voidpf context,voidpf memory)
414 memory=RelinquishMagickMemory(memory);
418 static Image *ReadMIFFImage(const ImageInfo *image_info,
419 ExceptionInfo *exception)
421 #define BZipMaxExtent(x) ((x)+((x)/100)+600)
422 #define LZMAMaxExtent(x) ((x)+((x)/3)+128)
423 #define ThrowMIFFException(exception,message) \
425 if (quantum_info != (QuantumInfo *) NULL) \
426 quantum_info=DestroyQuantumInfo(quantum_info); \
427 if (compress_pixels != (unsigned char *) NULL) \
428 compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); \
429 ThrowReaderException((exception),(message)); \
431 #define ZipMaxExtent(x) ((x)+(((x)+7) >> 3)+(((x)+63) >> 6)+11)
433 #if defined(MAGICKCORE_BZLIB_DELEGATE)
439 id[MagickPathExtent],
440 keyword[MagickPathExtent],
458 #if defined(MAGICKCORE_LZMA_DELEGATE)
460 initialize_lzma = LZMA_STREAM_INIT,
507 #if defined(MAGICKCORE_ZLIB_DELEGATE)
515 assert(image_info != (const ImageInfo *) NULL);
516 assert(image_info->signature == MagickCoreSignature);
517 if (image_info->debug != MagickFalse)
518 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
519 image_info->filename);
520 assert(exception != (ExceptionInfo *) NULL);
521 assert(exception->signature == MagickCoreSignature);
522 image=AcquireImage(image_info,exception);
523 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
524 if (status == MagickFalse)
526 image=DestroyImageList(image);
527 return((Image *) NULL);
530 Decode image header; header terminates one character beyond a ':'.
532 c=ReadBlobByte(image);
534 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
536 compress_pixels=(unsigned char *) NULL;
537 quantum_info=(QuantumInfo *) NULL;
538 (void) memset(keyword,0,sizeof(keyword));
544 Decode image header; header terminates one character beyond a ':'.
546 SetGeometryInfo(&geometry_info);
547 length=MagickPathExtent;
548 options=AcquireString((char *) NULL);
549 quantum_format=UndefinedQuantumFormat;
550 profiles=(LinkedListInfo *) NULL;
553 image->compression=NoCompression;
554 while ((isgraph(c) != MagickFalse) && (c != (int) ':'))
565 Read comment-- any text between { }.
567 length=MagickPathExtent;
568 comment=AcquireString((char *) NULL);
569 for (p=comment; comment != (char *) NULL; p++)
571 c=ReadBlobByte(image);
573 c=ReadBlobByte(image);
575 if ((c == EOF) || (c == (int) '}'))
577 if ((size_t) (p-comment+1) >= length)
581 comment=(char *) ResizeQuantumMemory(comment,length+
582 MagickPathExtent,sizeof(*comment));
583 if (comment == (char *) NULL)
585 p=comment+strlen(comment);
589 if (comment == (char *) NULL)
591 options=DestroyString(options);
592 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
595 (void) SetImageProperty(image,"comment",comment,exception);
596 comment=DestroyString(comment);
597 c=ReadBlobByte(image);
600 if (isalnum(c) != MagickFalse)
605 length=MagickPathExtent-1;
611 if ((size_t) (p-keyword) < (MagickPathExtent-1))
613 c=ReadBlobByte(image);
617 while ((isspace((int) ((unsigned char) c)) != 0) && (c != EOF))
618 c=ReadBlobByte(image);
622 Get the keyword value.
624 c=ReadBlobByte(image);
625 while ((c != (int) '}') && (c != EOF))
627 if ((size_t) (p-options+1) >= length)
631 options=(char *) ResizeQuantumMemory(options,length+
632 MagickPathExtent,sizeof(*options));
633 if (options == (char *) NULL)
635 p=options+strlen(options);
638 c=ReadBlobByte(image);
641 c=ReadBlobByte(image);
645 c=ReadBlobByte(image);
649 if (isspace((int) ((unsigned char) c)) != 0)
652 if (options == (char *) NULL)
653 ThrowMIFFException(ResourceLimitError,
654 "MemoryAllocationFailed");
658 (void) CopyMagickString(options,options+1,strlen(options));
660 Assign a value to the specified keyword.
667 if (LocaleCompare(keyword,"alpha-trait") == 0)
672 alpha_trait=ParseCommandOption(MagickPixelTraitOptions,
673 MagickFalse,options);
676 image->alpha_trait=(PixelTrait) alpha_trait;
679 (void) SetImageProperty(image,keyword,options,exception);
685 if (LocaleCompare(keyword,"background-color") == 0)
687 (void) QueryColorCompliance(options,AllCompliance,
688 &image->background_color,exception);
691 if (LocaleCompare(keyword,"blue-primary") == 0)
693 flags=ParseGeometry(options,&geometry_info);
694 image->chromaticity.blue_primary.x=geometry_info.rho;
695 image->chromaticity.blue_primary.y=geometry_info.sigma;
696 if ((flags & SigmaValue) == 0)
697 image->chromaticity.blue_primary.y=
698 image->chromaticity.blue_primary.x;
701 if (LocaleCompare(keyword,"border-color") == 0)
703 (void) QueryColorCompliance(options,AllCompliance,
704 &image->border_color,exception);
707 (void) SetImageProperty(image,keyword,options,exception);
713 if (LocaleCompare(keyword,"class") == 0)
718 storage_class=ParseCommandOption(MagickClassOptions,
719 MagickFalse,options);
720 if (storage_class < 0)
722 image->storage_class=(ClassType) storage_class;
725 if (LocaleCompare(keyword,"colors") == 0)
727 colors=StringToUnsignedLong(options);
730 if (LocaleCompare(keyword,"colorspace") == 0)
735 colorspace=ParseCommandOption(MagickColorspaceOptions,
736 MagickFalse,options);
739 image->colorspace=(ColorspaceType) colorspace;
742 if (LocaleCompare(keyword,"compression") == 0)
747 compression=ParseCommandOption(MagickCompressOptions,
748 MagickFalse,options);
751 image->compression=(CompressionType) compression;
754 if (LocaleCompare(keyword,"columns") == 0)
756 image->columns=StringToUnsignedLong(options);
759 (void) SetImageProperty(image,keyword,options,exception);
765 if (LocaleCompare(keyword,"delay") == 0)
767 image->delay=StringToUnsignedLong(options);
770 if (LocaleCompare(keyword,"depth") == 0)
772 image->depth=StringToUnsignedLong(options);
775 if (LocaleCompare(keyword,"dispose") == 0)
780 dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse,
784 image->dispose=(DisposeType) dispose;
787 (void) SetImageProperty(image,keyword,options,exception);
793 if (LocaleCompare(keyword,"endian") == 0)
798 endian=ParseCommandOption(MagickEndianOptions,MagickFalse,
802 image->endian=(EndianType) endian;
805 (void) SetImageProperty(image,keyword,options,exception);
811 if (LocaleCompare(keyword,"gamma") == 0)
813 image->gamma=StringToDouble(options,(char **) NULL);
816 if (LocaleCompare(keyword,"gravity") == 0)
821 gravity=ParseCommandOption(MagickGravityOptions,MagickFalse,
825 image->gravity=(GravityType) gravity;
828 if (LocaleCompare(keyword,"green-primary") == 0)
830 flags=ParseGeometry(options,&geometry_info);
831 image->chromaticity.green_primary.x=geometry_info.rho;
832 image->chromaticity.green_primary.y=geometry_info.sigma;
833 if ((flags & SigmaValue) == 0)
834 image->chromaticity.green_primary.y=
835 image->chromaticity.green_primary.x;
838 (void) SetImageProperty(image,keyword,options,exception);
844 if (LocaleCompare(keyword,"id") == 0)
846 (void) CopyMagickString(id,options,MagickPathExtent);
849 if (LocaleCompare(keyword,"iterations") == 0)
851 image->iterations=StringToUnsignedLong(options);
854 (void) SetImageProperty(image,keyword,options,exception);
860 if (LocaleCompare(keyword,"matte") == 0)
865 matte=ParseCommandOption(MagickBooleanOptions,MagickFalse,
869 image->alpha_trait=matte == 0 ? UndefinedPixelTrait :
873 if (LocaleCompare(keyword,"mattecolor") == 0)
875 (void) QueryColorCompliance(options,AllCompliance,
876 &image->matte_color,exception);
879 if (LocaleCompare(keyword,"montage") == 0)
881 (void) CloneString(&image->montage,options);
884 (void) SetImageProperty(image,keyword,options,exception);
890 if (LocaleCompare(keyword,"orientation") == 0)
895 orientation=ParseCommandOption(MagickOrientationOptions,
896 MagickFalse,options);
899 image->orientation=(OrientationType) orientation;
902 (void) SetImageProperty(image,keyword,options,exception);
908 if (LocaleCompare(keyword,"page") == 0)
913 geometry=GetPageGeometry(options);
914 (void) ParseAbsoluteGeometry(geometry,&image->page);
915 geometry=DestroyString(geometry);
918 if (LocaleCompare(keyword,"pixel-intensity") == 0)
923 intensity=ParseCommandOption(MagickPixelIntensityOptions,
924 MagickFalse,options);
927 image->intensity=(PixelIntensityMethod) intensity;
930 if (LocaleCompare(keyword,"profile") == 0)
932 if (profiles == (LinkedListInfo *) NULL)
933 profiles=NewLinkedList(0);
934 (void) AppendValueToLinkedList(profiles,
935 AcquireString(options));
938 (void) SetImageProperty(image,keyword,options,exception);
944 if (LocaleCompare(keyword,"quality") == 0)
946 image->quality=StringToUnsignedLong(options);
949 if ((LocaleCompare(keyword,"quantum-format") == 0) ||
950 (LocaleCompare(keyword,"quantum:format") == 0))
955 format=ParseCommandOption(MagickQuantumFormatOptions,
956 MagickFalse,options);
959 quantum_format=(QuantumFormatType) format;
962 (void) SetImageProperty(image,keyword,options,exception);
968 if (LocaleCompare(keyword,"red-primary") == 0)
970 flags=ParseGeometry(options,&geometry_info);
971 image->chromaticity.red_primary.x=geometry_info.rho;
972 image->chromaticity.red_primary.y=geometry_info.sigma;
973 if ((flags & SigmaValue) == 0)
974 image->chromaticity.red_primary.y=
975 image->chromaticity.red_primary.x;
978 if (LocaleCompare(keyword,"rendering-intent") == 0)
983 rendering_intent=ParseCommandOption(MagickIntentOptions,
984 MagickFalse,options);
985 if (rendering_intent < 0)
987 image->rendering_intent=(RenderingIntent) rendering_intent;
990 if (LocaleCompare(keyword,"resolution") == 0)
992 flags=ParseGeometry(options,&geometry_info);
993 image->resolution.x=geometry_info.rho;
994 image->resolution.y=geometry_info.sigma;
995 if ((flags & SigmaValue) == 0)
996 image->resolution.y=image->resolution.x;
999 if (LocaleCompare(keyword,"rows") == 0)
1001 image->rows=StringToUnsignedLong(options);
1004 (void) SetImageProperty(image,keyword,options,exception);
1010 if (LocaleCompare(keyword,"scene") == 0)
1012 image->scene=StringToUnsignedLong(options);
1015 (void) SetImageProperty(image,keyword,options,exception);
1021 if (LocaleCompare(keyword,"ticks-per-second") == 0)
1023 image->ticks_per_second=(ssize_t) StringToLong(options);
1026 if (LocaleCompare(keyword,"tile-offset") == 0)
1031 geometry=GetPageGeometry(options);
1032 (void) ParseAbsoluteGeometry(geometry,&image->tile_offset);
1033 geometry=DestroyString(geometry);
1036 if (LocaleCompare(keyword,"type") == 0)
1041 type=ParseCommandOption(MagickTypeOptions,MagickFalse,
1045 image->type=(ImageType) type;
1048 (void) SetImageProperty(image,keyword,options,exception);
1054 if (LocaleCompare(keyword,"units") == 0)
1059 units=ParseCommandOption(MagickResolutionOptions,
1060 MagickFalse,options);
1063 image->units=(ResolutionType) units;
1066 (void) SetImageProperty(image,keyword,options,exception);
1072 if (LocaleCompare(keyword,"version") == 0)
1074 version=StringToDouble(options,(char **) NULL);
1077 (void) SetImageProperty(image,keyword,options,exception);
1083 if (LocaleCompare(keyword,"white-point") == 0)
1085 flags=ParseGeometry(options,&geometry_info);
1086 image->chromaticity.white_point.x=geometry_info.rho;
1087 image->chromaticity.white_point.y=geometry_info.sigma;
1088 if ((flags & SigmaValue) == 0)
1089 image->chromaticity.white_point.y=
1090 image->chromaticity.white_point.x;
1093 (void) SetImageProperty(image,keyword,options,exception);
1098 (void) SetImageProperty(image,keyword,options,exception);
1104 c=ReadBlobByte(image);
1105 while (isspace((int) ((unsigned char) c)) != 0)
1106 c=ReadBlobByte(image);
1108 options=DestroyString(options);
1109 (void) ReadBlobByte(image);
1111 Verify that required image information is defined.
1113 if ((LocaleCompare(id,"ImageMagick") != 0) ||
1114 (image->storage_class == UndefinedClass) ||
1115 (image->compression == UndefinedCompression) ||
1116 (image->colorspace == UndefinedColorspace) ||
1117 (image->columns == 0) || (image->rows == 0) ||
1118 (image->depth == 0) || (image->depth > 64))
1120 if (profiles != (LinkedListInfo *) NULL)
1121 profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
1122 if (image->previous == (Image *) NULL)
1123 ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1124 DeleteImageFromList(&image);
1125 (void) ThrowMagickException(exception,GetMagickModule(),
1126 CorruptImageError,"ImproperImageHeader","`%s'",image->filename);
1129 if (image->montage != (char *) NULL)
1137 extent=MagickPathExtent;
1138 image->directory=AcquireString((char *) NULL);
1144 if ((length+MagickPathExtent) >= extent)
1147 Allocate more memory for the image directory.
1150 image->directory=(char *) ResizeQuantumMemory(image->directory,
1151 extent+MagickPathExtent,sizeof(*image->directory));
1152 if (image->directory == (char *) NULL)
1153 ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1154 p=image->directory+length;
1156 c=ReadBlobByte(image);
1161 } while (c != (int) '\0');
1163 if (profiles != (LinkedListInfo *) NULL)
1172 Read image profiles.
1174 ResetLinkedListIterator(profiles);
1175 name=(const char *) GetNextValueInLinkedList(profiles);
1176 while (name != (const char *) NULL)
1178 length=ReadBlobMSBLong(image);
1179 if ((MagickSizeType) length > GetBlobSize(image))
1181 profile=AcquireStringInfo(length);
1182 if (profile == (StringInfo *) NULL)
1184 count=ReadBlob(image,length,GetStringInfoDatum(profile));
1185 if (count != (ssize_t) length)
1187 profile=DestroyStringInfo(profile);
1190 status=SetImageProfile(image,name,profile,exception);
1191 profile=DestroyStringInfo(profile);
1192 if (status == MagickFalse)
1194 name=(const char *) GetNextValueInLinkedList(profiles);
1196 profiles=DestroyLinkedList(profiles,RelinquishMagickMemory);
1198 image->depth=GetImageQuantumDepth(image,MagickFalse);
1199 if (image->storage_class == PseudoClass)
1205 Create image colormap.
1207 packet_size=(size_t) (3UL*image->depth/8UL);
1208 if ((MagickSizeType) colors > GetBlobSize(image))
1209 ThrowMIFFException(CorruptImageError,"InsufficientImageDataInFile");
1210 if (((MagickSizeType) packet_size*colors) > GetBlobSize(image))
1211 ThrowMIFFException(CorruptImageError,"InsufficientImageDataInFile");
1212 status=AcquireImageColormap(image,colors != 0 ? colors : 256,exception);
1213 if (status == MagickFalse)
1214 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1221 Read image colormap from file.
1223 colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
1224 packet_size*sizeof(*colormap));
1225 if (colormap == (unsigned char *) NULL)
1226 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1227 count=ReadBlob(image,packet_size*image->colors,colormap);
1229 switch (image->depth)
1236 for (i=0; i < (ssize_t) image->colors; i++)
1238 p=PushCharPixel(p,&char_pixel);
1239 image->colormap[i].red=(MagickRealType)
1240 ScaleCharToQuantum(char_pixel);
1241 p=PushCharPixel(p,&char_pixel);
1242 image->colormap[i].green=(MagickRealType)
1243 ScaleCharToQuantum(char_pixel);
1244 p=PushCharPixel(p,&char_pixel);
1245 image->colormap[i].blue=(MagickRealType)
1246 ScaleCharToQuantum(char_pixel);
1255 for (i=0; i < (ssize_t) image->colors; i++)
1257 p=PushShortPixel(MSBEndian,p,&short_pixel);
1258 image->colormap[i].red=(MagickRealType)
1259 ScaleShortToQuantum(short_pixel);
1260 p=PushShortPixel(MSBEndian,p,&short_pixel);
1261 image->colormap[i].green=(MagickRealType)
1262 ScaleShortToQuantum(short_pixel);
1263 p=PushShortPixel(MSBEndian,p,&short_pixel);
1264 image->colormap[i].blue=(MagickRealType)
1265 ScaleShortToQuantum(short_pixel);
1275 for (i=0; i < (ssize_t) image->colors; i++)
1277 p=PushLongPixel(MSBEndian,p,&long_pixel);
1278 image->colormap[i].red=(MagickRealType)
1279 ScaleLongToQuantum(long_pixel);
1280 p=PushLongPixel(MSBEndian,p,&long_pixel);
1281 image->colormap[i].green=(MagickRealType)
1282 ScaleLongToQuantum(long_pixel);
1283 p=PushLongPixel(MSBEndian,p,&long_pixel);
1284 image->colormap[i].blue=(MagickRealType)
1285 ScaleLongToQuantum(long_pixel);
1290 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
1293 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
1294 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1296 status=SetImageExtent(image,image->columns,image->rows,exception);
1297 if (status == MagickFalse)
1298 return(DestroyImageList(image));
1299 status=ResetImagePixels(image,exception);
1300 if (status == MagickFalse)
1301 return(DestroyImageList(image));
1303 Allocate image pixels.
1305 quantum_info=AcquireQuantumInfo(image_info,image);
1306 if (quantum_info == (QuantumInfo *) NULL)
1307 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1308 if (quantum_format != UndefinedQuantumFormat)
1310 status=SetQuantumFormat(image,quantum_info,quantum_format);
1311 if (status == MagickFalse)
1312 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1314 packet_size=(size_t) (quantum_info->depth/8);
1315 if (image->storage_class == DirectClass)
1316 packet_size=(size_t) (3*quantum_info->depth/8);
1317 if (IsGrayColorspace(image->colorspace) != MagickFalse)
1318 packet_size=quantum_info->depth/8;
1319 if (image->alpha_trait != UndefinedPixelTrait)
1320 packet_size+=quantum_info->depth/8;
1321 if (image->colorspace == CMYKColorspace)
1322 packet_size+=quantum_info->depth/8;
1323 if (image->compression == RLECompression)
1325 compress_extent=MagickMax(MagickMax(BZipMaxExtent(packet_size*
1326 image->columns),LZMAMaxExtent(packet_size*image->columns)),
1327 ZipMaxExtent(packet_size*image->columns));
1328 if (compress_extent < (packet_size*image->columns))
1329 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1330 compress_pixels=(unsigned char *) AcquireQuantumMemory(compress_extent,
1331 sizeof(*compress_pixels));
1332 if (compress_pixels == (unsigned char *) NULL)
1333 ThrowMIFFException(ResourceLimitError,"MemoryAllocationFailed");
1337 quantum_type=RGBQuantum;
1338 if (image->alpha_trait != UndefinedPixelTrait)
1339 quantum_type=RGBAQuantum;
1340 if (image->colorspace == CMYKColorspace)
1342 quantum_type=CMYKQuantum;
1343 if (image->alpha_trait != UndefinedPixelTrait)
1344 quantum_type=CMYKAQuantum;
1346 if (IsGrayColorspace(image->colorspace) != MagickFalse)
1348 quantum_type=GrayQuantum;
1349 if (image->alpha_trait != UndefinedPixelTrait)
1350 quantum_type=GrayAlphaQuantum;
1352 if (image->storage_class == PseudoClass)
1354 quantum_type=IndexQuantum;
1355 if (image->alpha_trait != UndefinedPixelTrait)
1356 quantum_type=IndexAlphaQuantum;
1359 GetPixelInfo(image,&pixel);
1360 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1361 (void) memset(&bzip_info,0,sizeof(bzip_info));
1363 #if defined(MAGICKCORE_LZMA_DELEGATE)
1364 (void) memset(&allocator,0,sizeof(allocator));
1366 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1367 (void) memset(&zip_info,0,sizeof(zip_info));
1369 switch (image->compression)
1371 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1372 case BZipCompression:
1377 bzip_info.bzalloc=AcquireBZIPMemory;
1378 bzip_info.bzfree=RelinquishBZIPMemory;
1379 bzip_info.opaque=(void *) image;
1380 code=BZ2_bzDecompressInit(&bzip_info,(int) image_info->verbose,
1387 #if defined(MAGICKCORE_LZMA_DELEGATE)
1388 case LZMACompression:
1393 allocator.alloc=AcquireLZMAMemory;
1394 allocator.free=RelinquishLZMAMemory;
1395 allocator.opaque=(void *) image;
1396 lzma_info=initialize_lzma;
1397 lzma_info.allocator=(&allocator);
1398 code=lzma_auto_decoder(&lzma_info,(uint64_t) -1,0);
1399 if (code != LZMA_OK)
1404 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1405 case LZWCompression:
1406 case ZipCompression:
1411 zip_info.zalloc=AcquireZIPMemory;
1412 zip_info.zfree=RelinquishZIPMemory;
1413 zip_info.opaque=(voidpf) image;
1414 code=inflateInit(&zip_info);
1420 case RLECompression:
1425 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
1427 for (y=0; y < (ssize_t) image->rows; y++)
1435 if (status == MagickFalse)
1437 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
1438 if (q == (Quantum *) NULL)
1441 switch (image->compression)
1443 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1444 case BZipCompression:
1446 bzip_info.next_out=(char *) pixels;
1447 bzip_info.avail_out=(unsigned int) (packet_size*image->columns);
1453 if (bzip_info.avail_in == 0)
1455 bzip_info.next_in=(char *) compress_pixels;
1456 length=(size_t) BZipMaxExtent(packet_size*image->columns);
1458 length=(size_t) ReadBlobMSBLong(image);
1459 if (length <= compress_extent)
1460 bzip_info.avail_in=(unsigned int) ReadBlob(image,length,
1461 (unsigned char *) bzip_info.next_in);
1462 if ((length > compress_extent) ||
1463 ((size_t) bzip_info.avail_in != length))
1465 (void) BZ2_bzDecompressEnd(&bzip_info);
1466 ThrowMIFFException(CorruptImageError,
1467 "UnableToReadImageData");
1470 code=BZ2_bzDecompress(&bzip_info);
1471 if ((code != BZ_OK) && (code != BZ_STREAM_END))
1476 if (code == BZ_STREAM_END)
1478 } while (bzip_info.avail_out != 0);
1479 extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1480 quantum_type,pixels,exception);
1484 #if defined(MAGICKCORE_LZMA_DELEGATE)
1485 case LZMACompression:
1487 lzma_info.next_out=pixels;
1488 lzma_info.avail_out=packet_size*image->columns;
1494 if (lzma_info.avail_in == 0)
1496 lzma_info.next_in=compress_pixels;
1497 length=(size_t) ReadBlobMSBLong(image);
1498 if (length <= compress_extent)
1499 lzma_info.avail_in=(unsigned int) ReadBlob(image,length,
1500 (unsigned char *) lzma_info.next_in);
1501 if ((length > compress_extent) ||
1502 (lzma_info.avail_in != length))
1504 lzma_end(&lzma_info);
1505 ThrowMIFFException(CorruptImageError,
1506 "UnableToReadImageData");
1509 code=lzma_code(&lzma_info,LZMA_RUN);
1510 if ((code != LZMA_OK) && (code != LZMA_STREAM_END))
1515 if (code == LZMA_STREAM_END)
1517 } while (lzma_info.avail_out != 0);
1518 extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1519 quantum_type,pixels,exception);
1523 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1524 case LZWCompression:
1525 case ZipCompression:
1527 zip_info.next_out=pixels;
1528 zip_info.avail_out=(uInt) (packet_size*image->columns);
1534 if (zip_info.avail_in == 0)
1536 zip_info.next_in=compress_pixels;
1537 length=(size_t) ZipMaxExtent(packet_size*image->columns);
1539 length=(size_t) ReadBlobMSBLong(image);
1540 if (length <= compress_extent)
1541 zip_info.avail_in=(unsigned int) ReadBlob(image,length,
1543 if ((length > compress_extent) ||
1544 ((size_t) zip_info.avail_in != length))
1546 (void) inflateEnd(&zip_info);
1547 ThrowMIFFException(CorruptImageError,
1548 "UnableToReadImageData");
1551 code=inflate(&zip_info,Z_SYNC_FLUSH);
1552 if ((code != Z_OK) && (code != Z_STREAM_END))
1557 if (code == Z_STREAM_END)
1559 } while (zip_info.avail_out != 0);
1560 extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1561 quantum_type,pixels,exception);
1565 case RLECompression:
1567 for (x=0; x < (ssize_t) image->columns; x++)
1571 count=ReadBlob(image,packet_size,pixels);
1572 if (count != (ssize_t) packet_size)
1573 ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1574 PushRunlengthPacket(image,pixels,&length,&pixel,exception);
1577 if (image->storage_class == PseudoClass)
1578 SetPixelIndex(image,ClampToQuantum(pixel.index),q);
1581 SetPixelRed(image,ClampToQuantum(pixel.red),q);
1582 SetPixelGreen(image,ClampToQuantum(pixel.green),q);
1583 SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
1584 if (image->colorspace == CMYKColorspace)
1585 SetPixelBlack(image,ClampToQuantum(pixel.black),q);
1587 if (image->alpha_trait != UndefinedPixelTrait)
1588 SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
1589 q+=GetPixelChannels(image);
1599 stream=ReadBlobStream(image,packet_size*image->columns,pixels,&count);
1600 if (count != (ssize_t) (packet_size*image->columns))
1601 ThrowMIFFException(CorruptImageError,"UnableToReadImageData");
1602 extent=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
1603 quantum_type,stream,exception);
1607 if (extent < image->columns)
1609 if (SyncAuthenticPixels(image,exception) == MagickFalse)
1612 SetQuantumImageType(image,quantum_type);
1613 switch (image->compression)
1615 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1616 case BZipCompression:
1626 offset=SeekBlob(image,-((MagickOffsetType) bzip_info.avail_in),
1630 (void) BZ2_bzDecompressEnd(&bzip_info);
1631 ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1634 code=BZ2_bzDecompressEnd(&bzip_info);
1640 #if defined(MAGICKCORE_LZMA_DELEGATE)
1641 case LZMACompression:
1646 code=lzma_code(&lzma_info,LZMA_FINISH);
1647 if ((code != LZMA_STREAM_END) && (code != LZMA_OK))
1649 lzma_end(&lzma_info);
1653 #if defined(MAGICKCORE_ZLIB_DELEGATE)
1654 case LZWCompression:
1655 case ZipCompression:
1665 offset=SeekBlob(image,-((MagickOffsetType) zip_info.avail_in),
1669 (void) inflateEnd(&zip_info);
1670 ThrowMIFFException(CorruptImageError,"ImproperImageHeader");
1673 code=inflateEnd(&zip_info);
1682 quantum_info=DestroyQuantumInfo(quantum_info);
1683 compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
1684 if (((y != (ssize_t) image->rows)) || (status == MagickFalse))
1686 image=DestroyImageList(image);
1687 return((Image *) NULL);
1689 if (EOFBlob(image) != MagickFalse)
1691 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
1696 Proceed to next image.
1698 if (image_info->number_scenes != 0)
1699 if (image->scene >= (image_info->scene+image_info->number_scenes-1))
1703 c=ReadBlobByte(image);
1704 } while ((isgraph(c) == MagickFalse) && (c != EOF));
1708 Allocate next image structure.
1710 AcquireNextImage(image_info,image,exception);
1711 if (GetNextImageInList(image) == (Image *) NULL)
1716 image=SyncNextImageInList(image);
1717 status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
1718 GetBlobSize(image));
1719 if (status == MagickFalse)
1723 (void) CloseBlob(image);
1724 if (status == MagickFalse)
1725 return(DestroyImageList(image));
1726 return(GetFirstImageInList(image));
1730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1734 % R e g i s t e r M I F F I m a g e %
1738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1740 % RegisterMIFFImage() adds properties for the MIFF image format to the list of
1741 % supported formats. The properties include the image format tag, a method to
1742 % read and/or write the format, whether the format supports the saving of more
1743 % than one frame to the same file or blob, whether the format supports native
1744 % in-memory I/O, and a brief description of the format.
1746 % The format of the RegisterMIFFImage method is:
1748 % size_t RegisterMIFFImage(void)
1751 ModuleExport size_t RegisterMIFFImage(void)
1754 version[MagickPathExtent];
1760 #if defined(MagickImageCoderSignatureText)
1761 (void) CopyMagickString(version,MagickLibVersionText,MagickPathExtent);
1762 #if defined(ZLIB_VERSION)
1763 (void) ConcatenateMagickString(version," with Zlib ",MagickPathExtent);
1764 (void) ConcatenateMagickString(version,ZLIB_VERSION,MagickPathExtent);
1766 #if defined(MAGICKCORE_BZLIB_DELEGATE)
1767 (void) ConcatenateMagickString(version," and BZlib",MagickPathExtent);
1770 entry=AcquireMagickInfo("MIFF","MIFF","Magick Image File Format");
1771 entry->decoder=(DecodeImageHandler *) ReadMIFFImage;
1772 entry->encoder=(EncodeImageHandler *) WriteMIFFImage;
1773 entry->magick=(IsImageFormatHandler *) IsMIFF;
1774 entry->flags|=CoderDecoderSeekableStreamFlag;
1775 if (*version != '\0')
1776 entry->version=ConstantString(version);
1777 (void) RegisterMagickInfo(entry);
1778 return(MagickImageCoderSignature);
1782 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1786 % U n r e g i s t e r M I F F I m a g e %
1790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1792 % UnregisterMIFFImage() removes format registrations made by the MIFF module
1793 % from the list of supported formats.
1795 % The format of the UnregisterMIFFImage method is:
1797 % UnregisterMIFFImage(void)
1800 ModuleExport void UnregisterMIFFImage(void)
1802 (void) UnregisterMagickInfo("MIFF");
1806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1810 % W r i t e M I F F I m a g e %
1814 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1816 % WriteMIFFImage() writes a MIFF image to a file.
1818 % The format of the WriteMIFFImage method is:
1820 % MagickBooleanType WriteMIFFImage(const ImageInfo *image_info,
1821 % Image *image,ExceptionInfo *exception)
1823 % Compression code contributed by Kyle Shorter.
1825 % A description of each parameter follows:
1827 % o image_info: the image info.
1829 % o image: the image.
1831 % o exception: return any errors or warnings in this structure.
1835 static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels,
1836 size_t length,PixelInfo *pixel,ExceptionInfo *exception)
1838 if (image->storage_class != DirectClass)
1843 value=(unsigned int) ClampToQuantum(pixel->index);
1844 switch (image->depth)
1849 *pixels++=(unsigned char) (value >> 24);
1850 *pixels++=(unsigned char) (value >> 16);
1853 *pixels++=(unsigned char) (value >> 8);
1856 *pixels++=(unsigned char) value;
1860 switch (image->depth)
1868 if (image->alpha_trait != UndefinedPixelTrait)
1870 long_value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
1871 pixels=PopLongPixel(MSBEndian,long_value,pixels);
1880 if (image->alpha_trait != UndefinedPixelTrait)
1882 short_value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
1883 pixels=PopShortPixel(MSBEndian,short_value,pixels);
1892 if (image->alpha_trait != UndefinedPixelTrait)
1894 char_value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1896 pixels=PopCharPixel(char_value,pixels);
1901 *pixels++=(unsigned char) length;
1904 switch (image->depth)
1912 value=ScaleQuantumToLong(ClampToQuantum(pixel->red));
1913 pixels=PopLongPixel(MSBEndian,value,pixels);
1914 if (IsGrayColorspace(image->colorspace) == MagickFalse)
1916 value=ScaleQuantumToLong(ClampToQuantum(pixel->green));
1917 pixels=PopLongPixel(MSBEndian,value,pixels);
1918 value=ScaleQuantumToLong(ClampToQuantum(pixel->blue));
1919 pixels=PopLongPixel(MSBEndian,value,pixels);
1921 if (image->colorspace == CMYKColorspace)
1923 value=ScaleQuantumToLong(ClampToQuantum(pixel->black));
1924 pixels=PopLongPixel(MSBEndian,value,pixels);
1926 if (image->alpha_trait != UndefinedPixelTrait)
1928 value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha));
1929 pixels=PopLongPixel(MSBEndian,value,pixels);
1938 value=ScaleQuantumToShort(ClampToQuantum(pixel->red));
1939 pixels=PopShortPixel(MSBEndian,value,pixels);
1940 if (IsGrayColorspace(image->colorspace) == MagickFalse)
1942 value=ScaleQuantumToShort(ClampToQuantum(pixel->green));
1943 pixels=PopShortPixel(MSBEndian,value,pixels);
1944 value=ScaleQuantumToShort(ClampToQuantum(pixel->blue));
1945 pixels=PopShortPixel(MSBEndian,value,pixels);
1947 if (image->colorspace == CMYKColorspace)
1949 value=ScaleQuantumToShort(ClampToQuantum(pixel->black));
1950 pixels=PopShortPixel(MSBEndian,value,pixels);
1952 if (image->alpha_trait != UndefinedPixelTrait)
1954 value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha));
1955 pixels=PopShortPixel(MSBEndian,value,pixels);
1964 value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->red));
1965 pixels=PopCharPixel(value,pixels);
1966 if (IsGrayColorspace(image->colorspace) == MagickFalse)
1968 value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1970 pixels=PopCharPixel(value,pixels);
1971 value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->blue));
1972 pixels=PopCharPixel(value,pixels);
1974 if (image->colorspace == CMYKColorspace)
1976 value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1978 pixels=PopCharPixel(value,pixels);
1980 if (image->alpha_trait != UndefinedPixelTrait)
1982 value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(
1984 pixels=PopCharPixel(value,pixels);
1989 *pixels++=(unsigned char) length;
1993 static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info,
1994 Image *image,ExceptionInfo *exception)
1996 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2002 buffer[MagickPathExtent];
2011 #if defined(MAGICKCORE_LZMA_DELEGATE)
2016 initialize_lzma = LZMA_STREAM_INIT,
2052 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2058 Open output image file.
2060 assert(image_info != (const ImageInfo *) NULL);
2061 assert(image_info->signature == MagickCoreSignature);
2062 assert(image != (Image *) NULL);
2063 assert(image->signature == MagickCoreSignature);
2064 if (image->debug != MagickFalse)
2065 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2066 assert(exception != (ExceptionInfo *) NULL);
2067 assert(exception->signature == MagickCoreSignature);
2068 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
2069 if (status == MagickFalse)
2072 imageListLength=GetImageListLength(image);
2076 Allocate image pixels.
2078 if ((image->storage_class == PseudoClass) &&
2079 (image->colors > (size_t) (GetQuantumRange(image->depth)+1)))
2080 (void) SetImageStorageClass(image,DirectClass,exception);
2081 image->depth=image->depth <= 8 ? 8UL : image->depth <= 16 ? 16UL : 32UL;
2082 quantum_info=AcquireQuantumInfo(image_info,image);
2083 if (quantum_info == (QuantumInfo *) NULL)
2084 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2085 if ((image->storage_class != PseudoClass) && (image->depth >= 16) &&
2086 (quantum_info->format == UndefinedQuantumFormat) &&
2087 (IsHighDynamicRangeImage(image,exception) != MagickFalse))
2089 status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat);
2090 if (status == MagickFalse)
2092 quantum_info=DestroyQuantumInfo(quantum_info);
2093 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2097 if (image->depth < 16)
2098 (void) DeleteImageProperty(image,"quantum:format");
2099 compression=UndefinedCompression;
2100 if (image_info->compression != UndefinedCompression)
2101 compression=image_info->compression;
2102 switch (compression)
2104 #if !defined(MAGICKCORE_LZMA_DELEGATE)
2105 case LZMACompression: compression=NoCompression; break;
2107 #if !defined(MAGICKCORE_ZLIB_DELEGATE)
2108 case LZWCompression:
2109 case ZipCompression: compression=NoCompression; break;
2111 #if !defined(MAGICKCORE_BZLIB_DELEGATE)
2112 case BZipCompression: compression=NoCompression; break;
2114 case RLECompression:
2116 if (quantum_info->format == FloatingPointQuantumFormat)
2117 compression=NoCompression;
2118 GetPixelInfo(image,&target);
2124 packet_size=(size_t) (quantum_info->depth/8);
2125 if (image->storage_class == DirectClass)
2126 packet_size=(size_t) (3*quantum_info->depth/8);
2127 if (IsGrayColorspace(image->colorspace) != MagickFalse)
2128 packet_size=(size_t) (quantum_info->depth/8);
2129 if (image->alpha_trait != UndefinedPixelTrait)
2130 packet_size+=quantum_info->depth/8;
2131 if (image->colorspace == CMYKColorspace)
2132 packet_size+=quantum_info->depth/8;
2133 if (compression == RLECompression)
2135 length=MagickMax(BZipMaxExtent(packet_size*image->columns),ZipMaxExtent(
2136 packet_size*image->columns));
2137 if ((compression == BZipCompression) || (compression == ZipCompression))
2138 if (length != (size_t) ((unsigned int) length))
2139 compression=NoCompression;
2140 compress_pixels=(unsigned char *) AcquireQuantumMemory(length,
2141 sizeof(*compress_pixels));
2142 if (compress_pixels == (unsigned char *) NULL)
2143 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2147 (void) WriteBlobString(image,"id=ImageMagick version=1.0\n");
2148 (void) FormatLocaleString(buffer,MagickPathExtent,
2149 "class=%s colors=%.20g alpha-trait=%s\n",CommandOptionToMnemonic(
2150 MagickClassOptions,image->storage_class),(double) image->colors,
2151 CommandOptionToMnemonic(MagickPixelTraitOptions,(ssize_t)
2152 image->alpha_trait));
2153 (void) WriteBlobString(image,buffer);
2154 if (image->alpha_trait != UndefinedPixelTrait)
2155 (void) WriteBlobString(image,"matte=True\n");
2156 (void) FormatLocaleString(buffer,MagickPathExtent,
2157 "columns=%.20g rows=%.20g depth=%.20g\n",(double) image->columns,
2158 (double) image->rows,(double) image->depth);
2159 (void) WriteBlobString(image,buffer);
2160 if (image->type != UndefinedType)
2162 (void) FormatLocaleString(buffer,MagickPathExtent,"type=%s\n",
2163 CommandOptionToMnemonic(MagickTypeOptions,image->type));
2164 (void) WriteBlobString(image,buffer);
2166 if (image->colorspace != UndefinedColorspace)
2168 (void) FormatLocaleString(buffer,MagickPathExtent,"colorspace=%s\n",
2169 CommandOptionToMnemonic(MagickColorspaceOptions,image->colorspace));
2170 (void) WriteBlobString(image,buffer);
2172 if (image->intensity != UndefinedPixelIntensityMethod)
2174 (void) FormatLocaleString(buffer,MagickPathExtent,
2175 "pixel-intensity=%s\n",CommandOptionToMnemonic(
2176 MagickPixelIntensityOptions,image->intensity));
2177 (void) WriteBlobString(image,buffer);
2179 if (image->endian != UndefinedEndian)
2181 (void) FormatLocaleString(buffer,MagickPathExtent,"endian=%s\n",
2182 CommandOptionToMnemonic(MagickEndianOptions,image->endian));
2183 (void) WriteBlobString(image,buffer);
2185 if (compression != UndefinedCompression)
2187 (void) FormatLocaleString(buffer,MagickPathExtent,"compression=%s "
2188 "quality=%.20g\n",CommandOptionToMnemonic(MagickCompressOptions,
2189 compression),(double) image->quality);
2190 (void) WriteBlobString(image,buffer);
2192 if (image->units != UndefinedResolution)
2194 (void) FormatLocaleString(buffer,MagickPathExtent,"units=%s\n",
2195 CommandOptionToMnemonic(MagickResolutionOptions,image->units));
2196 (void) WriteBlobString(image,buffer);
2198 if ((image->resolution.x != 0) || (image->resolution.y != 0))
2200 (void) FormatLocaleString(buffer,MagickPathExtent,
2201 "resolution=%gx%g\n",image->resolution.x,image->resolution.y);
2202 (void) WriteBlobString(image,buffer);
2204 if ((image->page.width != 0) || (image->page.height != 0))
2206 (void) FormatLocaleString(buffer,MagickPathExtent,
2207 "page=%.20gx%.20g%+.20g%+.20g\n",(double) image->page.width,(double)
2208 image->page.height,(double) image->page.x,(double) image->page.y);
2209 (void) WriteBlobString(image,buffer);
2212 if ((image->page.x != 0) || (image->page.y != 0))
2214 (void) FormatLocaleString(buffer,MagickPathExtent,"page=%+ld%+ld\n",
2215 (long) image->page.x,(long) image->page.y);
2216 (void) WriteBlobString(image,buffer);
2218 if ((image->tile_offset.x != 0) || (image->tile_offset.y != 0))
2220 (void) FormatLocaleString(buffer,MagickPathExtent,
2221 "tile-offset=%+ld%+ld\n",(long) image->tile_offset.x,(long)
2222 image->tile_offset.y);
2223 (void) WriteBlobString(image,buffer);
2225 if ((GetNextImageInList(image) != (Image *) NULL) ||
2226 (GetPreviousImageInList(image) != (Image *) NULL))
2228 if (image->scene == 0)
2229 (void) FormatLocaleString(buffer,MagickPathExtent,"iterations=%.20g "
2230 "delay=%.20g ticks-per-second=%.20g\n",(double) image->iterations,
2231 (double) image->delay,(double) image->ticks_per_second);
2233 (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g "
2234 "iterations=%.20g delay=%.20g ticks-per-second=%.20g\n",(double)
2235 image->scene,(double) image->iterations,(double) image->delay,
2236 (double) image->ticks_per_second);
2237 (void) WriteBlobString(image,buffer);
2241 if (image->scene != 0)
2243 (void) FormatLocaleString(buffer,MagickPathExtent,"scene=%.20g\n",
2244 (double) image->scene);
2245 (void) WriteBlobString(image,buffer);
2247 if (image->iterations != 0)
2249 (void) FormatLocaleString(buffer,MagickPathExtent,
2250 "iterations=%.20g\n",(double) image->iterations);
2251 (void) WriteBlobString(image,buffer);
2253 if (image->delay != 0)
2255 (void) FormatLocaleString(buffer,MagickPathExtent,"delay=%.20g\n",
2256 (double) image->delay);
2257 (void) WriteBlobString(image,buffer);
2259 if (image->ticks_per_second != UndefinedTicksPerSecond)
2261 (void) FormatLocaleString(buffer,MagickPathExtent,
2262 "ticks-per-second=%.20g\n",(double) image->ticks_per_second);
2263 (void) WriteBlobString(image,buffer);
2266 if (image->gravity != UndefinedGravity)
2268 (void) FormatLocaleString(buffer,MagickPathExtent,"gravity=%s\n",
2269 CommandOptionToMnemonic(MagickGravityOptions,image->gravity));
2270 (void) WriteBlobString(image,buffer);
2272 if (image->dispose != UndefinedDispose)
2274 (void) FormatLocaleString(buffer,MagickPathExtent,"dispose=%s\n",
2275 CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
2276 (void) WriteBlobString(image,buffer);
2278 if (image->rendering_intent != UndefinedIntent)
2280 (void) FormatLocaleString(buffer,MagickPathExtent,
2281 "rendering-intent=%s\n",CommandOptionToMnemonic(MagickIntentOptions,
2282 image->rendering_intent));
2283 (void) WriteBlobString(image,buffer);
2285 if (image->gamma != 0.0)
2287 (void) FormatLocaleString(buffer,MagickPathExtent,"gamma=%g\n",
2289 (void) WriteBlobString(image,buffer);
2291 if (image->chromaticity.white_point.x != 0.0)
2294 Note chomaticity points.
2296 (void) FormatLocaleString(buffer,MagickPathExtent,"red-primary=%g,"
2297 "%g green-primary=%g,%g blue-primary=%g,%g\n",
2298 image->chromaticity.red_primary.x,image->chromaticity.red_primary.y,
2299 image->chromaticity.green_primary.x,
2300 image->chromaticity.green_primary.y,
2301 image->chromaticity.blue_primary.x,
2302 image->chromaticity.blue_primary.y);
2303 (void) WriteBlobString(image,buffer);
2304 (void) FormatLocaleString(buffer,MagickPathExtent,
2305 "white-point=%g,%g\n",image->chromaticity.white_point.x,
2306 image->chromaticity.white_point.y);
2307 (void) WriteBlobString(image,buffer);
2309 if (image->orientation != UndefinedOrientation)
2311 (void) FormatLocaleString(buffer,MagickPathExtent,"orientation=%s\n",
2312 CommandOptionToMnemonic(MagickOrientationOptions,image->orientation));
2313 (void) WriteBlobString(image,buffer);
2315 if (image->profiles != (void *) NULL)
2324 Write image profile names.
2326 ResetImageProfileIterator(image);
2327 for (name=GetNextImageProfile(image); name != (const char *) NULL; )
2329 profile=GetImageProfile(image,name);
2330 if (profile != (StringInfo *) NULL)
2332 (void) FormatLocaleString(buffer,MagickPathExtent,"profile=%s\n",
2334 (void) WriteBlobString(image,buffer);
2336 name=GetNextImageProfile(image);
2339 if (image->montage != (char *) NULL)
2341 (void) FormatLocaleString(buffer,MagickPathExtent,"montage=%s\n",
2343 (void) WriteBlobString(image,buffer);
2345 if (quantum_info->format == FloatingPointQuantumFormat)
2346 (void) SetImageProperty(image,"quantum:format","floating-point",
2348 ResetImagePropertyIterator(image);
2349 property=GetNextImageProperty(image);
2350 while (property != (const char *) NULL)
2352 (void) FormatLocaleString(buffer,MagickPathExtent,"%s=",property);
2353 (void) WriteBlobString(image,buffer);
2354 value=GetImageProperty(image,property,exception);
2355 if (value != (const char *) NULL)
2357 length=strlen(value);
2358 for (i=0; i < (ssize_t) length; i++)
2359 if ((isspace((int) ((unsigned char) value[i])) != 0) ||
2362 if ((i == (ssize_t) length) && (i != 0))
2363 (void) WriteBlob(image,length,(const unsigned char *) value);
2366 (void) WriteBlobByte(image,'{');
2367 if (strchr(value,'}') == (char *) NULL)
2368 (void) WriteBlob(image,length,(const unsigned char *) value);
2370 for (i=0; i < (ssize_t) length; i++)
2372 if (value[i] == (int) '}')
2373 (void) WriteBlobByte(image,'\\');
2374 (void) WriteBlobByte(image,(unsigned char) value[i]);
2376 (void) WriteBlobByte(image,'}');
2379 (void) WriteBlobByte(image,'\n');
2380 property=GetNextImageProperty(image);
2382 (void) WriteBlobString(image,"\f\n:\032");
2383 if (image->montage != (char *) NULL)
2386 Write montage tile directory.
2388 if (image->directory != (char *) NULL)
2389 (void) WriteBlob(image,strlen(image->directory),(unsigned char *)
2391 (void) WriteBlobByte(image,'\0');
2393 if (image->profiles != 0)
2402 Write image profile blob.
2404 ResetImageProfileIterator(image);
2405 name=GetNextImageProfile(image);
2406 while (name != (const char *) NULL)
2408 profile=GetImageProfile(image,name);
2409 (void) WriteBlobMSBLong(image,(unsigned int)
2410 GetStringInfoLength(profile));
2411 (void) WriteBlob(image,GetStringInfoLength(profile),
2412 GetStringInfoDatum(profile));
2413 name=GetNextImageProfile(image);
2416 if (image->storage_class == PseudoClass)
2427 colormap_size=(size_t) (3*quantum_info->depth/8);
2428 colormap=(unsigned char *) AcquireQuantumMemory(image->colors,
2429 colormap_size*sizeof(*colormap));
2430 if (colormap == (unsigned char *) NULL)
2431 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
2433 Write colormap to file.
2436 for (i=0; i < (ssize_t) image->colors; i++)
2438 switch (quantum_info->depth)
2443 register unsigned int
2446 long_pixel=ScaleQuantumToLong((Quantum)
2447 image->colormap[i].red);
2448 q=PopLongPixel(MSBEndian,long_pixel,q);
2449 long_pixel=ScaleQuantumToLong((Quantum)
2450 image->colormap[i].green);
2451 q=PopLongPixel(MSBEndian,long_pixel,q);
2452 long_pixel=ScaleQuantumToLong((Quantum)
2453 image->colormap[i].blue);
2454 q=PopLongPixel(MSBEndian,long_pixel,q);
2459 register unsigned short
2462 short_pixel=ScaleQuantumToShort((Quantum)
2463 image->colormap[i].red);
2464 q=PopShortPixel(MSBEndian,short_pixel,q);
2465 short_pixel=ScaleQuantumToShort((Quantum)
2466 image->colormap[i].green);
2467 q=PopShortPixel(MSBEndian,short_pixel,q);
2468 short_pixel=ScaleQuantumToShort((Quantum)
2469 image->colormap[i].blue);
2470 q=PopShortPixel(MSBEndian,short_pixel,q);
2475 register unsigned char
2478 char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2479 image->colormap[i].red);
2480 q=PopCharPixel(char_pixel,q);
2481 char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2482 image->colormap[i].green);
2483 q=PopCharPixel(char_pixel,q);
2484 char_pixel=(unsigned char) ScaleQuantumToChar((Quantum)
2485 image->colormap[i].blue);
2486 q=PopCharPixel(char_pixel,q);
2491 (void) WriteBlob(image,colormap_size*image->colors,colormap);
2492 colormap=(unsigned char *) RelinquishMagickMemory(colormap);
2495 Write image pixels to file.
2498 switch (compression)
2500 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2501 case BZipCompression:
2506 (void) memset(&bzip_info,0,sizeof(bzip_info));
2507 bzip_info.bzalloc=AcquireBZIPMemory;
2508 bzip_info.bzfree=RelinquishBZIPMemory;
2509 bzip_info.opaque=(void *) NULL;
2510 code=BZ2_bzCompressInit(&bzip_info,(int) (image->quality ==
2511 UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)),
2512 (int) image_info->verbose,0);
2518 #if defined(MAGICKCORE_LZMA_DELEGATE)
2519 case LZMACompression:
2524 allocator.alloc=AcquireLZMAMemory;
2525 allocator.free=RelinquishLZMAMemory;
2526 allocator.opaque=(void *) NULL;
2527 lzma_info=initialize_lzma;
2528 lzma_info.allocator=&allocator;
2529 code=lzma_easy_encoder(&lzma_info,(uint32_t) (image->quality/10),
2531 if (code != LZMA_OK)
2536 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2537 case LZWCompression:
2538 case ZipCompression:
2543 zip_info.zalloc=AcquireZIPMemory;
2544 zip_info.zfree=RelinquishZIPMemory;
2545 zip_info.opaque=(void *) NULL;
2546 code=deflateInit(&zip_info,(int) (image->quality ==
2547 UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9)));
2556 quantum_type=GetQuantumType(image,exception);
2557 pixels=(unsigned char *) GetQuantumPixels(quantum_info);
2558 for (y=0; y < (ssize_t) image->rows; y++)
2560 register const Quantum
2566 if (status == MagickFalse)
2568 p=GetVirtualPixels(image,0,y,image->columns,1,exception);
2569 if (p == (const Quantum *) NULL)
2572 switch (compression)
2574 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2575 case BZipCompression:
2577 bzip_info.next_in=(char *) pixels;
2578 bzip_info.avail_in=(unsigned int) (packet_size*image->columns);
2579 (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2580 quantum_type,pixels,exception);
2586 bzip_info.next_out=(char *) compress_pixels;
2587 bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size*
2589 code=BZ2_bzCompress(&bzip_info,BZ_FLUSH);
2592 length=(size_t) (bzip_info.next_out-(char *) compress_pixels);
2595 (void) WriteBlobMSBLong(image,(unsigned int) length);
2596 (void) WriteBlob(image,length,compress_pixels);
2598 } while (bzip_info.avail_in != 0);
2602 #if defined(MAGICKCORE_LZMA_DELEGATE)
2603 case LZMACompression:
2605 lzma_info.next_in=pixels;
2606 lzma_info.avail_in=packet_size*image->columns;
2607 (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2608 quantum_type,pixels,exception);
2614 lzma_info.next_out=compress_pixels;
2615 lzma_info.avail_out=LZMAMaxExtent(packet_size*image->columns);
2616 code=lzma_code(&lzma_info,LZMA_RUN);
2617 if (code != LZMA_OK)
2619 length=(size_t) (lzma_info.next_out-compress_pixels);
2622 (void) WriteBlobMSBLong(image,(unsigned int) length);
2623 (void) WriteBlob(image,length,compress_pixels);
2625 } while (lzma_info.avail_in != 0);
2629 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2630 case LZWCompression:
2631 case ZipCompression:
2633 zip_info.next_in=pixels;
2634 zip_info.avail_in=(uInt) (packet_size*image->columns);
2635 (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2636 quantum_type,pixels,exception);
2642 zip_info.next_out=compress_pixels;
2643 zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns);
2644 code=deflate(&zip_info,Z_SYNC_FLUSH);
2647 length=(size_t) (zip_info.next_out-compress_pixels);
2650 (void) WriteBlobMSBLong(image,(unsigned int) length);
2651 (void) WriteBlob(image,length,compress_pixels);
2653 } while (zip_info.avail_in != 0);
2657 case RLECompression:
2660 GetPixelInfoPixel(image,p,&pixel);
2661 p+=GetPixelChannels(image);
2662 for (x=1; x < (ssize_t) image->columns; x++)
2664 GetPixelInfoPixel(image,p,&target);
2665 if ((length < 255) &&
2666 (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse))
2670 q=PopRunlengthPacket(image,q,length,&pixel,exception);
2673 GetPixelInfoPixel(image,p,&pixel);
2674 p+=GetPixelChannels(image);
2676 q=PopRunlengthPacket(image,q,length,&pixel,exception);
2677 (void) WriteBlob(image,(size_t) (q-pixels),pixels);
2682 (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
2683 quantum_type,pixels,exception);
2684 (void) WriteBlob(image,packet_size*image->columns,pixels);
2688 if (image->previous == (Image *) NULL)
2690 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
2692 if (status == MagickFalse)
2696 switch (compression)
2698 #if defined(MAGICKCORE_BZLIB_DELEGATE)
2699 case BZipCompression:
2706 if (status == MagickFalse)
2708 bzip_info.next_out=(char *) compress_pixels;
2709 bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size*
2711 code=BZ2_bzCompress(&bzip_info,BZ_FINISH);
2712 length=(size_t) (bzip_info.next_out-(char *) compress_pixels);
2715 (void) WriteBlobMSBLong(image,(unsigned int) length);
2716 (void) WriteBlob(image,length,compress_pixels);
2718 if (code == BZ_STREAM_END)
2721 code=BZ2_bzCompressEnd(&bzip_info);
2727 #if defined(MAGICKCORE_LZMA_DELEGATE)
2728 case LZMACompression:
2735 if (status == MagickFalse)
2737 lzma_info.next_out=compress_pixels;
2738 lzma_info.avail_out=packet_size*image->columns;
2739 code=lzma_code(&lzma_info,LZMA_FINISH);
2740 length=(size_t) (lzma_info.next_out-compress_pixels);
2743 (void) WriteBlobMSBLong(image,(unsigned int) length);
2744 (void) WriteBlob(image,length,compress_pixels);
2746 if (code == LZMA_STREAM_END)
2749 lzma_end(&lzma_info);
2753 #if defined(MAGICKCORE_ZLIB_DELEGATE)
2754 case LZWCompression:
2755 case ZipCompression:
2762 if (status == MagickFalse)
2764 zip_info.next_out=compress_pixels;
2765 zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns);
2766 code=deflate(&zip_info,Z_FINISH);
2767 length=(size_t) (zip_info.next_out-compress_pixels);
2770 (void) WriteBlobMSBLong(image,(unsigned int) length);
2771 (void) WriteBlob(image,length,compress_pixels);
2773 if (code == Z_STREAM_END)
2776 code=deflateEnd(&zip_info);
2785 quantum_info=DestroyQuantumInfo(quantum_info);
2786 compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels);
2787 if (GetNextImageInList(image) == (Image *) NULL)
2789 image=SyncNextImageInList(image);
2790 status=SetImageProgress(image,SaveImagesTag,scene++,imageListLength);
2791 if (status == MagickFalse)
2793 } while (image_info->adjoin != MagickFalse);
2794 (void) CloseBlob(image);