X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=coders%2Fmiff.c;h=eeabb5da8f03603f9793c7816fc923f263412076;hb=45ef08fd6a09813e4a8f5ddadf85ba9e0ec2cdc7;hp=b979b0711c1ed9a1a91a2cf1f5d3de4787a66086;hpb=7e41fe84a841d7b9d7b36b245b65e9dcb3314943;p=imagemagick diff --git a/coders/miff.c b/coders/miff.c index b979b0711..eeabb5da8 100644 --- a/coders/miff.c +++ b/coders/miff.c @@ -17,7 +17,7 @@ % July 1992 % % % % % -% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -39,50 +39,62 @@ /* Include declarations. */ -#include "magick/studio.h" -#include "magick/attribute.h" -#include "magick/blob.h" -#include "magick/blob-private.h" -#include "magick/cache.h" -#include "magick/color.h" -#include "magick/color-private.h" -#include "magick/colormap.h" -#include "magick/colormap-private.h" -#include "magick/colorspace.h" -#include "magick/constitute.h" -#include "magick/exception.h" -#include "magick/exception-private.h" -#include "magick/hashmap.h" -#include "magick/geometry.h" -#include "magick/image.h" -#include "magick/image-private.h" -#include "magick/list.h" -#include "magick/magick.h" -#include "magick/memory_.h" -#include "magick/module.h" -#include "magick/monitor.h" -#include "magick/monitor-private.h" -#include "magick/option.h" -#include "magick/pixel.h" -#include "magick/profile.h" -#include "magick/property.h" -#include "magick/quantum-private.h" -#include "magick/static.h" -#include "magick/statistic.h" -#include "magick/string_.h" -#include "magick/string-private.h" +#include "MagickCore/studio.h" +#include "MagickCore/attribute.h" +#include "MagickCore/blob.h" +#include "MagickCore/blob-private.h" +#include "MagickCore/cache.h" +#include "MagickCore/color.h" +#include "MagickCore/color-private.h" +#include "MagickCore/colormap.h" +#include "MagickCore/colormap-private.h" +#include "MagickCore/colorspace.h" +#include "MagickCore/colorspace-private.h" +#include "MagickCore/constitute.h" +#include "MagickCore/exception.h" +#include "MagickCore/exception-private.h" +#include "MagickCore/hashmap.h" +#include "MagickCore/geometry.h" +#include "MagickCore/image.h" +#include "MagickCore/image-private.h" +#include "MagickCore/list.h" +#include "MagickCore/magick.h" +#include "MagickCore/memory_.h" +#include "MagickCore/module.h" +#include "MagickCore/monitor.h" +#include "MagickCore/monitor-private.h" +#include "MagickCore/option.h" +#include "MagickCore/pixel.h" +#include "MagickCore/pixel-accessor.h" +#include "MagickCore/profile.h" +#include "MagickCore/property.h" +#include "MagickCore/quantum-private.h" +#include "MagickCore/static.h" +#include "MagickCore/statistic.h" +#include "MagickCore/string_.h" +#include "MagickCore/string-private.h" +#if defined(MAGICKCORE_BZLIB_DELEGATE) +#include "bzlib.h" +#endif +#if defined(MAGICKCORE_LZMA_DELEGATE) +#include "lzma.h" +#endif #if defined(MAGICKCORE_ZLIB_DELEGATE) #include "zlib.h" #endif -#if defined(MAGICKCORE_BZLIB_DELEGATE) -#include "bzlib.h" + +/* + Define declarations. +*/ +#if !defined(LZMA_OK) +#define LZMA_OK 0 #endif /* Forward declarations. */ static MagickBooleanType - WriteMIFFImage(const ImageInfo *,Image *); + WriteMIFFImage(const ImageInfo *,Image *,ExceptionInfo *); /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -156,6 +168,14 @@ static void *AcquireBZIPMemory(void *context,int items,int size) } #endif +#if defined(MAGICKCORE_LZMA_DELEGATE) +static void *AcquireLZMAMemory(void *context,size_t items,size_t size) +{ + (void) context; + return((void *) AcquireQuantumMemory((size_t) items,(size_t) size)); +} +#endif + #if defined(MAGICKCORE_ZLIB_DELEGATE) static voidpf AcquireZIPMemory(voidpf context,unsigned int items, unsigned int size) @@ -180,7 +200,7 @@ static inline size_t MagickMin(const size_t x,const size_t y) } static void PushRunlengthPacket(Image *image,const unsigned char *pixels, - size_t *length,PixelPacket *pixel,IndexPacket *index) + size_t *length,PixelInfo *pixel,ExceptionInfo *exception) { const unsigned char *p; @@ -188,33 +208,33 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, p=pixels; if (image->storage_class == PseudoClass) { - *index=(IndexPacket) 0; + pixel->index=0; switch (image->depth) { case 32: { - *index=ConstrainColormapIndex(image, - (*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3)); + pixel->index=ConstrainColormapIndex(image, + (*p << 24) | (*(p+1) << 16) | (*(p+2) << 8) | *(p+3),exception); p+=4; break; } case 16: { - *index=ConstrainColormapIndex(image,(*p << 8) | *(p+1)); + pixel->index=ConstrainColormapIndex(image,(*p << 8) | *(p+1), + exception); p+=2; break; } case 8: { - *index=ConstrainColormapIndex(image,*p); + pixel->index=ConstrainColormapIndex(image,*p,exception); p++; break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); } - *pixel=image->colormap[(ssize_t) *index]; switch (image->depth) { case 8: @@ -222,10 +242,10 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, unsigned char quantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { p=PushCharPixel(p,&quantum); - pixel->opacity=ScaleCharToQuantum(quantum); + pixel->alpha=ScaleCharToQuantum(quantum); } break; } @@ -234,10 +254,10 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, unsigned short quantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { p=PushShortPixel(MSBEndian,p,&quantum); - pixel->opacity=(Quantum) (quantum >> (image->depth- + pixel->alpha=(Quantum) (quantum >> (image->depth- MAGICKCORE_QUANTUM_DEPTH)); } break; @@ -247,16 +267,16 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, unsigned int quantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { p=PushLongPixel(MSBEndian,p,&quantum); - pixel->opacity=(Quantum) (quantum >> (image->depth- + pixel->alpha=(Quantum) (quantum >> (image->depth- MAGICKCORE_QUANTUM_DEPTH)); } break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); } *length=(size_t) (*p++)+1; @@ -271,19 +291,24 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, p=PushCharPixel(p,&quantum); pixel->red=ScaleCharToQuantum(quantum); - p=PushCharPixel(p,&quantum); - pixel->green=ScaleCharToQuantum(quantum); - p=PushCharPixel(p,&quantum); - pixel->blue=ScaleCharToQuantum(quantum); - if (image->matte != MagickFalse) + pixel->green=pixel->red; + pixel->blue=pixel->red; + if (IsGrayColorspace(image->colorspace) == MagickFalse) { p=PushCharPixel(p,&quantum); - pixel->opacity=ScaleCharToQuantum(quantum); + pixel->green=ScaleCharToQuantum(quantum); + p=PushCharPixel(p,&quantum); + pixel->blue=ScaleCharToQuantum(quantum); } if (image->colorspace == CMYKColorspace) { p=PushCharPixel(p,&quantum); - *index=ScaleCharToQuantum(quantum); + pixel->black=ScaleCharToQuantum(quantum); + } + if (image->alpha_trait == BlendPixelTrait) + { + p=PushCharPixel(p,&quantum); + pixel->alpha=ScaleCharToQuantum(quantum); } break; } @@ -293,24 +318,25 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, quantum; p=PushShortPixel(MSBEndian,p,&quantum); - pixel->red=(Quantum) (quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH)); - p=PushShortPixel(MSBEndian,p,&quantum); - pixel->green=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); - p=PushShortPixel(MSBEndian,p,&quantum); - pixel->blue=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); - if (image->matte != MagickFalse) + pixel->red=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + pixel->green=pixel->red; + pixel->blue=pixel->red; + if (IsGrayColorspace(image->colorspace) == MagickFalse) { p=PushShortPixel(MSBEndian,p,&quantum); - pixel->opacity=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); + pixel->green=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + p=PushShortPixel(MSBEndian,p,&quantum); + pixel->blue=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); } if (image->colorspace == CMYKColorspace) { p=PushShortPixel(MSBEndian,p,&quantum); - *index=(IndexPacket) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); + pixel->black=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + } + if (image->alpha_trait == BlendPixelTrait) + { + p=PushShortPixel(MSBEndian,p,&quantum); + pixel->alpha=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); } break; } @@ -320,44 +346,53 @@ static void PushRunlengthPacket(Image *image,const unsigned char *pixels, quantum; p=PushLongPixel(MSBEndian,p,&quantum); - pixel->red=(Quantum) (quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH)); - p=PushLongPixel(MSBEndian,p,&quantum); - pixel->green=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); - p=PushLongPixel(MSBEndian,p,&quantum); - pixel->blue=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); - if (image->matte != MagickFalse) + pixel->red=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + pixel->green=pixel->red; + pixel->blue=pixel->red; + if (IsGrayColorspace(image->colorspace) == MagickFalse) { p=PushLongPixel(MSBEndian,p,&quantum); - pixel->opacity=(Quantum) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); + pixel->green=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + p=PushLongPixel(MSBEndian,p,&quantum); + pixel->blue=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); } if (image->colorspace == CMYKColorspace) { p=PushLongPixel(MSBEndian,p,&quantum); - *index=(IndexPacket) (quantum >> (image->depth- - MAGICKCORE_QUANTUM_DEPTH)); + pixel->black=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); + } + if (image->alpha_trait == BlendPixelTrait) + { + p=PushLongPixel(MSBEndian,p,&quantum); + pixel->alpha=quantum >> (image->depth-MAGICKCORE_QUANTUM_DEPTH); } break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), - CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); + (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError, + "ImageDepthNotSupported","`%s'",image->filename); } *length=(size_t) (*p++)+1; } -#if defined(MAGICKCORE_ZLIB_DELEGATE) -static void RelinquishZIPMemory(voidpf context,voidpf memory) +#if defined(MAGICKCORE_BZLIB_DELEGATE) +static void RelinquishBZIPMemory(void *context,void *memory) { (void) context; memory=RelinquishMagickMemory(memory); } #endif -#if defined(MAGICKCORE_BZLIB_DELEGATE) -static void RelinquishBZIPMemory(void *context,void *memory) +#if defined(MAGICKCORE_LZMA_DELEGATE) +static void RelinquishLZMAMemory(void *context,void *memory) +{ + (void) context; + memory=RelinquishMagickMemory(memory); +} +#endif + +#if defined(MAGICKCORE_ZLIB_DELEGATE) +static void RelinquishZIPMemory(voidpf context,voidpf memory) { (void) context; memory=RelinquishMagickMemory(memory); @@ -368,6 +403,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ExceptionInfo *exception) { #define BZipMaxExtent(x) ((x)+((x)/100)+600) +#define LZMAMaxExtent(x) ((x)+((x)/3)+128) #define ZipMaxExtent(x) ((x)+(((x)+7) >> 3)+(((x)+63) >> 6)+11) #if defined(MAGICKCORE_BZLIB_DELEGATE) @@ -392,28 +428,30 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, Image *image; - IndexPacket - index; - int - c, - code; + c; LinkedListInfo *profiles; - ssize_t - y; +#if defined(MAGICKCORE_LZMA_DELEGATE) + lzma_stream + initialize_lzma = LZMA_STREAM_INIT, + lzma_info; + + lzma_allocator + allocator; +#endif MagickBooleanType status; + PixelInfo + pixel; + MagickStatusType flags; - PixelPacket - pixel; - QuantumFormatType quantum_format; @@ -440,6 +478,9 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, size_t colors; + ssize_t + y; + #if defined(MAGICKCORE_ZLIB_DELEGATE) z_stream zip_info; @@ -455,7 +496,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image_info->filename); assert(exception != (ExceptionInfo *) NULL); assert(exception->signature == MagickSignature); - image=AcquireImage(image_info); + image=AcquireImage(image_info,exception); status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); if (status == MagickFalse) { @@ -468,10 +509,10 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, c=ReadBlobByte(image); if (c == EOF) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); - code=0; *id='\0'; (void) ResetMagickMemory(keyword,0,sizeof(keyword)); version=0.0; + (void) version; do { /* @@ -502,8 +543,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, for (p=comment; comment != (char *) NULL; p++) { c=ReadBlobByte(image); - if ((c == EOF) || (c == (int) '}')) - break; + if (c == (int) '\\') + c=ReadBlobByte(image); + else + if ((c == EOF) || (c == (int) '}')) + break; if ((size_t) (p-comment+1) >= length) { *p='\0'; @@ -519,7 +563,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, if (comment == (char *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); *p='\0'; - (void) SetImageProperty(image,"comment",comment); + (void) SetImageProperty(image,"comment",comment,exception); comment=DestroyString(comment); c=ReadBlobByte(image); } @@ -532,8 +576,6 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, p=keyword; do { - if (isspace((int) ((unsigned char) c)) != 0) - break; if (c == (int) '=') break; if ((size_t) (p-keyword) < (MaxTextExtent-1)) @@ -567,26 +609,52 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, "MemoryAllocationFailed"); *p++=(char) c; c=ReadBlobByte(image); + if (c == '\\') + { + c=ReadBlobByte(image); + if (c == (int) '}') + { + *p++=(char) c; + c=ReadBlobByte(image); + } + } if (*options != '{') if (isspace((int) ((unsigned char) c)) != 0) break; - } - } + } } *p='\0'; if (*options == '{') - (void) CopyMagickString(options,options+1,MaxTextExtent); + (void) CopyMagickString(options,options+1,strlen(options)); /* Assign a value to the specified keyword. */ switch (*keyword) { + case 'a': + case 'A': + { + if (LocaleCompare(keyword,"alpha-trait") == 0) + { + ssize_t + alpha_trait; + + alpha_trait=ParseCommandOption(MagickPixelTraitOptions, + MagickFalse,options); + if (alpha_trait < 0) + break; + image->alpha_trait=(PixelTrait) alpha_trait; + break; + } + (void) SetImageProperty(image,keyword,options,exception); + break; + } case 'b': case 'B': { if (LocaleCompare(keyword,"background-color") == 0) { - (void) QueryColorDatabase(options,&image->background_color, - exception); + (void) QueryColorCompliance(options,AllCompliance, + &image->background_color,exception); break; } if (LocaleCompare(keyword,"blue-primary") == 0) @@ -601,11 +669,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, } if (LocaleCompare(keyword,"border-color") == 0) { - (void) QueryColorDatabase(options,&image->border_color, - exception); + (void) QueryColorCompliance(options,AllCompliance, + &image->border_color,exception); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'c': @@ -616,7 +684,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t storage_class; - storage_class=ParseMagickOption(MagickClassOptions, + storage_class=ParseCommandOption(MagickClassOptions, MagickFalse,options); if (storage_class < 0) break; @@ -633,11 +701,11 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t colorspace; - colorspace=ParseMagickOption(MagickColorspaceOptions, + colorspace=ParseCommandOption(MagickColorspaceOptions, MagickFalse,options); if (colorspace < 0) break; - image->colorspace=(ColorspaceType) colorspace; + (void) SetImageColorspace(image,(ColorspaceType) colorspace, exception); break; } if (LocaleCompare(keyword,"compression") == 0) @@ -645,7 +713,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t compression; - compression=ParseMagickOption(MagickCompressOptions, + compression=ParseCommandOption(MagickCompressOptions, MagickFalse,options); if (compression < 0) break; @@ -657,7 +725,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image->columns=StringToUnsignedLong(options); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'd': @@ -678,14 +746,14 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t dispose; - dispose=ParseMagickOption(MagickDisposeOptions,MagickFalse, + dispose=ParseCommandOption(MagickDisposeOptions,MagickFalse, options); if (dispose < 0) break; image->dispose=(DisposeType) dispose; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'e': @@ -696,14 +764,14 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t endian; - endian=ParseMagickOption(MagickEndianOptions,MagickFalse, + endian=ParseCommandOption(MagickEndianOptions,MagickFalse, options); if (endian < 0) break; image->endian=(EndianType) endian; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'g': @@ -711,7 +779,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, { if (LocaleCompare(keyword,"gamma") == 0) { - image->gamma=StringToDouble(options); + image->gamma=StringToDouble(options,(char **) NULL); break; } if (LocaleCompare(keyword,"gravity") == 0) @@ -719,7 +787,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t gravity; - gravity=ParseMagickOption(MagickGravityOptions,MagickFalse, + gravity=ParseCommandOption(MagickGravityOptions,MagickFalse, options); if (gravity < 0) break; @@ -736,7 +804,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image->chromaticity.green_primary.x; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'i': @@ -752,7 +820,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image->iterations=StringToUnsignedLong(options); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'm': @@ -763,17 +831,18 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t matte; - matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, + matte=ParseCommandOption(MagickBooleanOptions,MagickFalse, options); if (matte < 0) break; - image->matte=(MagickBooleanType) matte; + image->alpha_trait=matte == 0 ? UndefinedPixelTrait : + BlendPixelTrait; break; } if (LocaleCompare(keyword,"matte-color") == 0) { - (void) QueryColorDatabase(options,&image->matte_color, - exception); + (void) QueryColorCompliance(options,AllCompliance, + &image->matte_color,exception); break; } if (LocaleCompare(keyword,"montage") == 0) @@ -781,37 +850,25 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, (void) CloneString(&image->montage,options); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'o': case 'O': { - if (LocaleCompare(keyword,"opaque") == 0) - { - ssize_t - matte; - - matte=ParseMagickOption(MagickBooleanOptions,MagickFalse, - options); - if (matte < 0) - break; - image->matte=(MagickBooleanType) matte; - break; - } if (LocaleCompare(keyword,"orientation") == 0) { ssize_t orientation; - orientation=ParseMagickOption(MagickOrientationOptions, + orientation=ParseCommandOption(MagickOrientationOptions, MagickFalse,options); if (orientation < 0) break; image->orientation=(OrientationType) orientation; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'p': @@ -837,12 +894,16 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, profiles=NewLinkedList(0); (void) AppendValueToLinkedList(profiles, AcquireString(keyword+8)); - profile=AcquireStringInfo((size_t) StringToLong(options)); - (void) SetImageProfile(image,keyword+8,profile); + profile=BlobToStringInfo((const void *) NULL,(size_t) + StringToLong(options)); + if (profile == (StringInfo *) NULL) + ThrowReaderException(ResourceLimitError, + "MemoryAllocationFailed"); + (void) SetImageProfile(image,keyword+8,profile,exception); profile=DestroyStringInfo(profile); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'q': @@ -859,14 +920,14 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t format; - format=ParseMagickOption(MagickQuantumFormatOptions, + format=ParseCommandOption(MagickQuantumFormatOptions, MagickFalse,options); if (format < 0) break; quantum_format=(QuantumFormatType) format; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'r': @@ -887,7 +948,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t rendering_intent; - rendering_intent=ParseMagickOption(MagickIntentOptions, + rendering_intent=ParseCommandOption(MagickIntentOptions, MagickFalse,options); if (rendering_intent < 0) break; @@ -897,10 +958,10 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, if (LocaleCompare(keyword,"resolution") == 0) { flags=ParseGeometry(options,&geometry_info); - image->x_resolution=geometry_info.rho; - image->y_resolution=geometry_info.sigma; + image->resolution.x=geometry_info.rho; + image->resolution.y=geometry_info.sigma; if ((flags & SigmaValue) == 0) - image->y_resolution=image->x_resolution; + image->resolution.y=image->resolution.x; break; } if (LocaleCompare(keyword,"rows") == 0) @@ -908,7 +969,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image->rows=StringToUnsignedLong(options); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 's': @@ -919,7 +980,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, image->scene=StringToUnsignedLong(options); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 't': @@ -945,14 +1006,14 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t type; - type=ParseMagickOption(MagickTypeOptions,MagickFalse, + type=ParseCommandOption(MagickTypeOptions,MagickFalse, options); if (type < 0) break; image->type=(ImageType) type; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'u': @@ -963,14 +1024,14 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, ssize_t units; - units=ParseMagickOption(MagickResolutionOptions,MagickFalse, - options); + units=ParseCommandOption(MagickResolutionOptions, + MagickFalse,options); if (units < 0) break; image->units=(ResolutionType) units; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'v': @@ -978,10 +1039,10 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, { if (LocaleCompare(keyword,"version") == 0) { - version=StringToDouble(options); + version=StringToDouble(options,(char **) NULL); break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } case 'w': @@ -991,18 +1052,18 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, { flags=ParseGeometry(options,&geometry_info); image->chromaticity.white_point.x=geometry_info.rho; - image->chromaticity.white_point.y=geometry_info.rho; - if ((flags & SigmaValue) != 0) + image->chromaticity.white_point.y=geometry_info.sigma; + if ((flags & SigmaValue) == 0) image->chromaticity.white_point.y= image->chromaticity.white_point.x; break; } - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } default: { - (void) SetImageProperty(image,keyword,options); + (void) SetImageProperty(image,keyword,options,exception); break; } } @@ -1074,6 +1135,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, p=GetStringInfoDatum(profile); count=ReadBlob(image,GetStringInfoLength(profile),p); + (void) count; } name=(const char *) GetNextValueInLinkedList(profiles); } @@ -1085,7 +1147,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, /* Create image colormap. */ - status=AcquireImageColormap(image,colors != 0 ? colors : 256); + status=AcquireImageColormap(image,colors != 0 ? colors : 256,exception); if (status == MagickFalse) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); if (colors != 0) @@ -1181,15 +1243,18 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, packet_size=(size_t) (quantum_info->depth/8); if (image->storage_class == DirectClass) packet_size=(size_t) (3*quantum_info->depth/8); - if (image->matte != MagickFalse) + if (IsGrayColorspace(image->colorspace) != MagickFalse) + packet_size=quantum_info->depth/8; + if (image->alpha_trait == BlendPixelTrait) packet_size+=quantum_info->depth/8; if (image->colorspace == CMYKColorspace) packet_size+=quantum_info->depth/8; if (image->compression == RLECompression) packet_size++; length=image->columns; - length=MagickMax(BZipMaxExtent(packet_size*image->columns),ZipMaxExtent( - packet_size*image->columns)); + length=MagickMax(MagickMax(BZipMaxExtent(packet_size*image->columns), + LZMAMaxExtent(packet_size*image->columns)),ZipMaxExtent(packet_size* + image->columns)); compress_pixels=(unsigned char *) AcquireQuantumMemory(length, sizeof(*compress_pixels)); if (compress_pixels == (unsigned char *) NULL) @@ -1198,145 +1263,180 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, Read image pixels. */ quantum_type=RGBQuantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) quantum_type=RGBAQuantum; if (image->colorspace == CMYKColorspace) { quantum_type=CMYKQuantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) quantum_type=CMYKAQuantum; } + if (IsGrayColorspace(image->colorspace) != MagickFalse) + { + quantum_type=GrayQuantum; + if (image->alpha_trait == BlendPixelTrait) + quantum_type=GrayAlphaQuantum; + } if (image->storage_class == PseudoClass) { quantum_type=IndexQuantum; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) quantum_type=IndexAlphaQuantum; } - if (image->colorspace == GRAYColorspace) + status=MagickTrue; + switch (image->compression) + { +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: { - quantum_type=GrayQuantum; - if (image->matte != MagickFalse) - quantum_type=GrayAlphaQuantum; + int + code; + + (void) ResetMagickMemory(&bzip_info,0,sizeof(bzip_info)); + bzip_info.bzalloc=AcquireBZIPMemory; + bzip_info.bzfree=RelinquishBZIPMemory; + bzip_info.opaque=(void *) NULL; + code=BZ2_bzDecompressInit(&bzip_info,(int) image_info->verbose, + MagickFalse); + if (code != BZ_OK) + status=MagickFalse; + break; } +#endif +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: + { + int + code; + + (void) ResetMagickMemory(&allocator,0,sizeof(allocator)); + allocator.alloc=AcquireLZMAMemory; + allocator.free=RelinquishLZMAMemory; + lzma_info=initialize_lzma; + lzma_info.allocator=(&allocator); + code=lzma_auto_decoder(&lzma_info,-1,0); + if (code != LZMA_OK) + status=MagickFalse; + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + int + code; + + (void) ResetMagickMemory(&zip_info,0,sizeof(zip_info)); + zip_info.zalloc=AcquireZIPMemory; + zip_info.zfree=RelinquishZIPMemory; + zip_info.opaque=(voidpf) NULL; + code=inflateInit(&zip_info); + if (code != Z_OK) + status=MagickFalse; + break; + } +#endif + case RLECompression: + { + GetPixelInfo(image,&pixel); + break; + } + default: + break; + } pixels=GetQuantumPixels(quantum_info); - index=(IndexPacket) 0; length=0; for (y=0; y < (ssize_t) image->rows; y++) { - register IndexPacket - *restrict indexes; - register ssize_t x; - register PixelPacket + register Quantum *restrict q; + if (status == MagickFalse) + break; q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); - if (q == (PixelPacket *) NULL) + if (q == (Quantum *) NULL) break; - indexes=GetAuthenticIndexQueue(image); switch (image->compression) { -#if defined(MAGICKCORE_ZLIB_DELEGATE) - case LZWCompression: - case ZipCompression: +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: { - if (y == 0) - { - zip_info.zalloc=AcquireZIPMemory; - zip_info.zfree=RelinquishZIPMemory; - zip_info.opaque=(voidpf) NULL; - code=inflateInit(&zip_info); - if (code >= 0) - status=MagickTrue; - zip_info.avail_in=0; - } - zip_info.next_out=pixels; - zip_info.avail_out=(uInt) (packet_size*image->columns); + bzip_info.next_out=(char *) pixels; + bzip_info.avail_out=(unsigned int) (packet_size*image->columns); do { - if (zip_info.avail_in == 0) + if (bzip_info.avail_in == 0) { - zip_info.next_in=compress_pixels; - length=(size_t) ZipMaxExtent(packet_size*image->columns); - if (version != 0) + bzip_info.next_in=(char *) compress_pixels; + length=(size_t) BZipMaxExtent(packet_size*image->columns); + if (version != 0.0) length=(size_t) ReadBlobMSBLong(image); - zip_info.avail_in=(unsigned int) ReadBlob(image,length, - zip_info.next_in); + bzip_info.avail_in=(unsigned int) ReadBlob(image,length, + (unsigned char *) bzip_info.next_in); } - if (inflate(&zip_info,Z_SYNC_FLUSH) == Z_STREAM_END) + if (BZ2_bzDecompress(&bzip_info) == BZ_STREAM_END) break; - } while (zip_info.avail_out != 0); - if (y == (ssize_t) (image->rows-1)) - { - if (version == 0) - { - MagickOffsetType - offset; - - offset=SeekBlob(image,-((MagickOffsetType) zip_info.avail_in), - SEEK_CUR); - if (offset < 0) - ThrowReaderException(CorruptImageError, - "ImproperImageHeader"); - } - code=inflateEnd(&zip_info); - if (code >= 0) - status=MagickTrue; - } + } while (bzip_info.avail_out != 0); (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); break; } #endif -#if defined(MAGICKCORE_BZLIB_DELEGATE) - case BZipCompression: +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: { - if (y == 0) - { - bzip_info.bzalloc=AcquireBZIPMemory; - bzip_info.bzfree=RelinquishBZIPMemory; - bzip_info.opaque=(void *) NULL; - code=BZ2_bzDecompressInit(&bzip_info,(int) image_info->verbose, - MagickFalse); - if (code >= 0) - status=MagickTrue; - bzip_info.avail_in=0; - } - bzip_info.next_out=(char *) pixels; - bzip_info.avail_out=(unsigned int) (packet_size*image->columns); + lzma_info.next_out=pixels; + lzma_info.avail_out=packet_size*image->columns; do { - if (bzip_info.avail_in == 0) + int + code; + + if (lzma_info.avail_in == 0) { - bzip_info.next_in=(char *) compress_pixels; - length=(size_t) BZipMaxExtent(packet_size*image->columns); - if (version != 0) + lzma_info.next_in=compress_pixels; + length=(size_t) ReadBlobMSBLong(image); + lzma_info.avail_in=(unsigned int) ReadBlob(image,length, + (unsigned char *) lzma_info.next_in); + } + code=lzma_code(&lzma_info,LZMA_RUN); + if (code < 0) + { + status=MagickFalse; + break; + } + if (code == LZMA_STREAM_END) + break; + } while (lzma_info.avail_out != 0); + (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + zip_info.next_out=pixels; + zip_info.avail_out=(uInt) (packet_size*image->columns); + do + { + if (zip_info.avail_in == 0) + { + zip_info.next_in=compress_pixels; + length=(size_t) ZipMaxExtent(packet_size*image->columns); + if (version != 0.0) length=(size_t) ReadBlobMSBLong(image); - bzip_info.avail_in=(unsigned int) ReadBlob(image,length, - (unsigned char *) bzip_info.next_in); + zip_info.avail_in=(unsigned int) ReadBlob(image,length, + zip_info.next_in); } - if (BZ2_bzDecompress(&bzip_info) == BZ_STREAM_END) + if (inflate(&zip_info,Z_SYNC_FLUSH) == Z_STREAM_END) break; - } while (bzip_info.avail_out != 0); - if (y == (ssize_t) (image->rows-1)) - { - if (version == 0) - { - MagickOffsetType - offset; - - offset=SeekBlob(image,-((MagickOffsetType) - bzip_info.avail_in),SEEK_CUR); - if (offset < 0) - ThrowReaderException(CorruptImageError, - "ImproperImageHeader"); - } - code=BZ2_bzDecompressEnd(&bzip_info); - if (code >= 0) - status=MagickTrue; - } + } while (zip_info.avail_out != 0); (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info, quantum_type,pixels,exception); break; @@ -1344,24 +1444,27 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, #endif case RLECompression: { - if (y == 0) - { - (void) ResetMagickMemory(&pixel,0,sizeof(pixel)); - pixel.opacity=(Quantum) TransparentOpacity; - index=(IndexPacket) 0; - } for (x=0; x < (ssize_t) image->columns; x++) { if (length == 0) { count=ReadBlob(image,packet_size,pixels); - PushRunlengthPacket(image,pixels,&length,&pixel,&index); + PushRunlengthPacket(image,pixels,&length,&pixel,exception); } length--; - if ((image->storage_class == PseudoClass) || - (image->colorspace == CMYKColorspace)) - indexes[x]=index; - *q++=pixel; + if (image->storage_class == PseudoClass) + SetPixelIndex(image,ClampToQuantum(pixel.index),q); + else + { + SetPixelRed(image,ClampToQuantum(pixel.red),q); + SetPixelGreen(image,ClampToQuantum(pixel.green),q); + SetPixelBlue(image,ClampToQuantum(pixel.blue),q); + if (image->colorspace == CMYKColorspace) + SetPixelBlack(image,ClampToQuantum(pixel.black),q); + } + if (image->alpha_trait == BlendPixelTrait) + SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q); + q+=GetPixelChannels(image); } break; } @@ -1377,6 +1480,71 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, break; } SetQuantumImageType(image,quantum_type); + switch (image->compression) + { +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: + { + int + code; + + if (version == 0.0) + { + MagickOffsetType + offset; + + offset=SeekBlob(image,-((MagickOffsetType) + bzip_info.avail_in),SEEK_CUR); + if (offset < 0) + ThrowReaderException(CorruptImageError, + "ImproperImageHeader"); + } + code=BZ2_bzDecompressEnd(&bzip_info); + if (code != BZ_OK) + status=MagickFalse; + break; + } +#endif +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: + { + int + code; + + code=lzma_code(&lzma_info,LZMA_FINISH); + if ((code != LZMA_STREAM_END) && (code != LZMA_OK)) + status=MagickFalse; + lzma_end(&lzma_info); + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + int + code; + + if (version == 0.0) + { + MagickOffsetType + offset; + + offset=SeekBlob(image,-((MagickOffsetType) zip_info.avail_in), + SEEK_CUR); + if (offset < 0) + ThrowReaderException(CorruptImageError, + "ImproperImageHeader"); + } + code=inflateEnd(&zip_info); + if (code != LZMA_OK) + status=MagickFalse; + break; + } +#endif + default: + break; + } quantum_info=DestroyQuantumInfo(quantum_info); compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); if (((y != (ssize_t) image->rows)) || (status == MagickFalse)) @@ -1405,7 +1573,7 @@ static Image *ReadMIFFImage(const ImageInfo *image_info, /* Allocate next image structure. */ - AcquireNextImage(image_info,image); + AcquireNextImage(image_info,image,exception); if (GetNextImageInList(image) == (Image *) NULL) { image=DestroyImageList(image); @@ -1467,6 +1635,7 @@ ModuleExport size_t RegisterMIFFImage(void) entry->decoder=(DecodeImageHandler *) ReadMIFFImage; entry->encoder=(EncodeImageHandler *) WriteMIFFImage; entry->magick=(IsImageFormatHandler *) IsMIFF; + entry->seekable_stream=MagickTrue; entry->description=ConstantString("Magick Image File Format"); if (*version != '\0') entry->version=ConstantString(version); @@ -1515,7 +1684,7 @@ ModuleExport void UnregisterMIFFImage(void) % The format of the WriteMIFFImage method is: % % MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, -% Image *image) +% Image *image,ExceptionInfo *exception) % % Compression code contributed by Kyle Shorter. % @@ -1525,10 +1694,12 @@ ModuleExport void UnregisterMIFFImage(void) % % o image: the image. % +% o exception: return any errors or warnings in this structure. +% */ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, - size_t length,PixelPacket pixel,IndexPacket index) + size_t length,PixelInfo *pixel,ExceptionInfo *exception) { if (image->storage_class != DirectClass) { @@ -1536,18 +1707,18 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, { case 32: { - *pixels++=(unsigned char) ((size_t) index >> 24); - *pixels++=(unsigned char) ((size_t) index >> 16); + *pixels++=(unsigned char) ((size_t) pixel->index >> 24); + *pixels++=(unsigned char) ((size_t) pixel->index >> 16); } case 16: - *pixels++=(unsigned char) ((size_t) index >> 8); + *pixels++=(unsigned char) ((size_t) pixel->index >> 8); case 8: { - *pixels++=(unsigned char) index; + *pixels++=(unsigned char) pixel->index; break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); } switch (image->depth) @@ -1557,9 +1728,9 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned int value; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { - value=ScaleQuantumToLong(pixel.opacity); + value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha)); pixels=PopLongPixel(MSBEndian,value,pixels); } break; @@ -1569,9 +1740,9 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned short value; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { - value=ScaleQuantumToShort(pixel.opacity); + value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha)); pixels=PopShortPixel(MSBEndian,value,pixels); } break; @@ -1581,15 +1752,16 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned char value; - if (image->matte != MagickFalse) + if (image->alpha_trait == BlendPixelTrait) { - value=(unsigned char) ScaleQuantumToChar(pixel.opacity); + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum( + pixel->alpha)); pixels=PopCharPixel(value,pixels); } break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), + (void) ThrowMagickException(exception,GetMagickModule(), CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); } *pixels++=(unsigned char) length; @@ -1602,20 +1774,23 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned int value; - value=ScaleQuantumToLong(pixel.red); - pixels=PopLongPixel(MSBEndian,value,pixels); - value=ScaleQuantumToLong(pixel.green); + value=ScaleQuantumToLong(ClampToQuantum(pixel->red)); pixels=PopLongPixel(MSBEndian,value,pixels); - value=ScaleQuantumToLong(pixel.blue); - pixels=PopLongPixel(MSBEndian,value,pixels); - if (image->matte != MagickFalse) + if (IsGrayColorspace(image->colorspace) == MagickFalse) { - value=ScaleQuantumToLong(pixel.opacity); + value=ScaleQuantumToLong(ClampToQuantum(pixel->green)); + pixels=PopLongPixel(MSBEndian,value,pixels); + value=ScaleQuantumToLong(ClampToQuantum(pixel->blue)); pixels=PopLongPixel(MSBEndian,value,pixels); } if (image->colorspace == CMYKColorspace) { - value=ScaleQuantumToLong(index); + value=ScaleQuantumToLong(ClampToQuantum(pixel->black)); + pixels=PopLongPixel(MSBEndian,value,pixels); + } + if (image->alpha_trait == BlendPixelTrait) + { + value=ScaleQuantumToLong(ClampToQuantum(pixel->alpha)); pixels=PopLongPixel(MSBEndian,value,pixels); } break; @@ -1625,20 +1800,23 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned short value; - value=ScaleQuantumToShort(pixel.red); - pixels=PopShortPixel(MSBEndian,value,pixels); - value=ScaleQuantumToShort(pixel.green); - pixels=PopShortPixel(MSBEndian,value,pixels); - value=ScaleQuantumToShort(pixel.blue); + value=ScaleQuantumToShort(ClampToQuantum(pixel->red)); pixels=PopShortPixel(MSBEndian,value,pixels); - if (image->matte != MagickFalse) + if (IsGrayColorspace(image->colorspace) == MagickFalse) { - value=ScaleQuantumToShort(pixel.opacity); + value=ScaleQuantumToShort(ClampToQuantum(pixel->green)); + pixels=PopShortPixel(MSBEndian,value,pixels); + value=ScaleQuantumToShort(ClampToQuantum(pixel->blue)); pixels=PopShortPixel(MSBEndian,value,pixels); } if (image->colorspace == CMYKColorspace) { - value=ScaleQuantumToShort(index); + value=ScaleQuantumToShort(ClampToQuantum(pixel->black)); + pixels=PopShortPixel(MSBEndian,value,pixels); + } + if (image->alpha_trait == BlendPixelTrait) + { + value=ScaleQuantumToShort(ClampToQuantum(pixel->alpha)); pixels=PopShortPixel(MSBEndian,value,pixels); } break; @@ -1648,34 +1826,40 @@ static unsigned char *PopRunlengthPacket(Image *image,unsigned char *pixels, unsigned char value; - value=(unsigned char) ScaleQuantumToChar(pixel.red); - pixels=PopCharPixel(value,pixels); - value=(unsigned char) ScaleQuantumToChar(pixel.green); - pixels=PopCharPixel(value,pixels); - value=(unsigned char) ScaleQuantumToChar(pixel.blue); + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->red)); pixels=PopCharPixel(value,pixels); - if (image->matte != MagickFalse) + if (IsGrayColorspace(image->colorspace) == MagickFalse) { - value=(unsigned char) ScaleQuantumToChar(pixel.opacity); + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum( + pixel->green)); + pixels=PopCharPixel(value,pixels); + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum(pixel->blue)); pixels=PopCharPixel(value,pixels); } if (image->colorspace == CMYKColorspace) { - value=(unsigned char) ScaleQuantumToChar(index); + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum( + pixel->black)); + pixels=PopCharPixel(value,pixels); + } + if (image->alpha_trait == BlendPixelTrait) + { + value=(unsigned char) ScaleQuantumToChar(ClampToQuantum( + pixel->alpha)); pixels=PopCharPixel(value,pixels); } break; } default: - (void) ThrowMagickException(&image->exception,GetMagickModule(), - CorruptImageError,"ImageDepthNotSupported","`%s'",image->filename); + (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError, + "ImageDepthNotSupported","`%s'",image->filename); } *pixels++=(unsigned char) length; return(pixels); } static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, - Image *image) + Image *image,ExceptionInfo *exception) { #if defined(MAGICKCORE_BZLIB_DELEGATE) bz_stream @@ -1692,14 +1876,14 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, *property, *value; - IndexPacket - index; - - int - code; +#if defined(MAGICKCORE_LZMA_DELEGATE) + lzma_allocator + allocator; - ssize_t - y; + lzma_stream + initialize_lzma = LZMA_STREAM_INIT, + lzma_info; +#endif MagickBooleanType status; @@ -1707,8 +1891,9 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, MagickOffsetType scene; - PixelPacket - pixel; + PixelInfo + pixel, + target; QuantumInfo *quantum_info; @@ -1723,6 +1908,9 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, length, packet_size; + ssize_t + y; + unsigned char *compress_pixels, *pixels, @@ -1742,10 +1930,11 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, assert(image->signature == MagickSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); - status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception); + assert(exception != (ExceptionInfo *) NULL); + assert(exception->signature == MagickSignature); + status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); if (status == MagickFalse) return(status); - code=0; scene=0; do { @@ -1759,7 +1948,7 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); if ((image->storage_class != PseudoClass) && (image->depth >= 32) && (quantum_info->format == UndefinedQuantumFormat) && - (IsHighDynamicRangeImage(image,&image->exception) != MagickFalse)) + (IsHighDynamicRangeImage(image,exception) != MagickFalse)) { status=SetQuantumFormat(image,quantum_info,FloatingPointQuantumFormat); if (status == MagickFalse) @@ -1767,17 +1956,17 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, } if ((image->storage_class == PseudoClass) && (image->colors > (size_t) (GetQuantumRange(image->depth)+1))) - (void) SetImageStorageClass(image,DirectClass); - if (IsGrayImage(image,&image->exception) != MagickFalse) - { - image->storage_class=DirectClass; - (void) SetImageColorspace(image,GRAYColorspace); - } + (void) SetImageStorageClass(image,DirectClass,exception); + if (IsImageGray(image,exception) != MagickFalse) + (void) SetImageColorspace(image,GRAYColorspace,exception); compression=image->compression; if (image_info->compression != UndefinedCompression) compression=image_info->compression; switch (compression) { +#if !defined(MAGICKCORE_ZLIB_DELEGATE) + case LZMACompression: compression=NoCompression; break; +#endif #if !defined(MAGICKCORE_ZLIB_DELEGATE) case LZWCompression: case ZipCompression: compression=NoCompression; break; @@ -1789,6 +1978,7 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, { if (quantum_info->format == FloatingPointQuantumFormat) compression=NoCompression; + GetPixelInfo(image,&target); break; } default: @@ -1797,7 +1987,9 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, packet_size=(size_t) (quantum_info->depth/8); if (image->storage_class == DirectClass) packet_size=(size_t) (3*quantum_info->depth/8); - if (image->matte != MagickFalse) + if (IsGrayColorspace(image->colorspace) != MagickFalse) + packet_size=(size_t) (quantum_info->depth/8); + if (image->alpha_trait == BlendPixelTrait) packet_size+=quantum_info->depth/8; if (image->colorspace == CMYKColorspace) packet_size+=quantum_info->depth/8; @@ -1817,49 +2009,50 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, Write MIFF header. */ (void) WriteBlobString(image,"id=ImageMagick version=1.0\n"); - (void) FormatMagickString(buffer,MaxTextExtent, - "class=%s colors=%.20g matte=%s\n",MagickOptionToMnemonic( + (void) FormatLocaleString(buffer,MaxTextExtent, + "class=%s colors=%.20g alpha-trait=%s\n",CommandOptionToMnemonic( MagickClassOptions,image->storage_class),(double) image->colors, - MagickOptionToMnemonic(MagickBooleanOptions,(ssize_t) image->matte)); + CommandOptionToMnemonic(MagickPixelTraitOptions,(ssize_t) + image->alpha_trait)); (void) WriteBlobString(image,buffer); - (void) FormatMagickString(buffer,MaxTextExtent,"columns=%.20g rows=%.20g " + (void) FormatLocaleString(buffer,MaxTextExtent,"columns=%.20g rows=%.20g " "depth=%.20g\n",(double) image->columns,(double) image->rows,(double) image->depth); (void) WriteBlobString(image,buffer); if (image->type != UndefinedType) { - (void) FormatMagickString(buffer,MaxTextExtent,"type=%s\n", - MagickOptionToMnemonic(MagickTypeOptions,image->type)); + (void) FormatLocaleString(buffer,MaxTextExtent,"type=%s\n", + CommandOptionToMnemonic(MagickTypeOptions,image->type)); (void) WriteBlobString(image,buffer); } if (image->colorspace != UndefinedColorspace) { - (void) FormatMagickString(buffer,MaxTextExtent,"colorspace=%s\n", - MagickOptionToMnemonic(MagickColorspaceOptions,image->colorspace)); + (void) FormatLocaleString(buffer,MaxTextExtent,"colorspace=%s\n", + CommandOptionToMnemonic(MagickColorspaceOptions,image->colorspace)); (void) WriteBlobString(image,buffer); } if (compression != UndefinedCompression) { - (void) FormatMagickString(buffer,MaxTextExtent,"compression=%s " - "quality=%.20g\n",MagickOptionToMnemonic(MagickCompressOptions, + (void) FormatLocaleString(buffer,MaxTextExtent,"compression=%s " + "quality=%.20g\n",CommandOptionToMnemonic(MagickCompressOptions, compression),(double) image->quality); (void) WriteBlobString(image,buffer); } if (image->units != UndefinedResolution) { - (void) FormatMagickString(buffer,MaxTextExtent,"units=%s\n", - MagickOptionToMnemonic(MagickResolutionOptions,image->units)); + (void) FormatLocaleString(buffer,MaxTextExtent,"units=%s\n", + CommandOptionToMnemonic(MagickResolutionOptions,image->units)); (void) WriteBlobString(image,buffer); } - if ((image->x_resolution != 0) || (image->y_resolution != 0)) + if ((image->resolution.x != 0) || (image->resolution.y != 0)) { - (void) FormatMagickString(buffer,MaxTextExtent, - "resolution=%gx%g\n",image->x_resolution,image->y_resolution); + (void) FormatLocaleString(buffer,MaxTextExtent, + "resolution=%gx%g\n",image->resolution.x,image->resolution.y); (void) WriteBlobString(image,buffer); } if ((image->page.width != 0) || (image->page.height != 0)) { - (void) FormatMagickString(buffer,MaxTextExtent, + (void) FormatLocaleString(buffer,MaxTextExtent, "page=%.20gx%.20g%+.20g%+.20g\n",(double) image->page.width,(double) image->page.height,(double) image->page.x,(double) image->page.y); (void) WriteBlobString(image,buffer); @@ -1867,13 +2060,13 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, else if ((image->page.x != 0) || (image->page.y != 0)) { - (void) FormatMagickString(buffer,MaxTextExtent,"page=%+ld%+ld\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"page=%+ld%+ld\n", (long) image->page.x,(long) image->page.y); (void) WriteBlobString(image,buffer); } if ((image->tile_offset.x != 0) || (image->tile_offset.y != 0)) { - (void) FormatMagickString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"tile-offset=%+ld%+ld\n", (long) image->tile_offset.x,(long) image->tile_offset.y); (void) WriteBlobString(image,buffer); } @@ -1881,11 +2074,11 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, (GetPreviousImageInList(image) != (Image *) NULL)) { if (image->scene == 0) - (void) FormatMagickString(buffer,MaxTextExtent,"iterations=%.20g " + (void) FormatLocaleString(buffer,MaxTextExtent,"iterations=%.20g " "delay=%.20g ticks-per-second=%.20g\n",(double) image->iterations, (double) image->delay,(double) image->ticks_per_second); else - (void) FormatMagickString(buffer,MaxTextExtent,"scene=%.20g " + (void) FormatLocaleString(buffer,MaxTextExtent,"scene=%.20g " "iterations=%.20g delay=%.20g ticks-per-second=%.20g\n",(double) image->scene,(double) image->iterations,(double) image->delay, (double) image->ticks_per_second); @@ -1895,51 +2088,50 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, { if (image->scene != 0) { - (void) FormatMagickString(buffer,MaxTextExtent,"scene=%.20g\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"scene=%.20g\n", (double) image->scene); (void) WriteBlobString(image,buffer); } if (image->iterations != 0) { - (void) FormatMagickString(buffer,MaxTextExtent,"iterations=%.20g\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"iterations=%.20g\n", (double) image->iterations); (void) WriteBlobString(image,buffer); } if (image->delay != 0) { - (void) FormatMagickString(buffer,MaxTextExtent,"delay=%.20g\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"delay=%.20g\n", (double) image->delay); (void) WriteBlobString(image,buffer); } if (image->ticks_per_second != UndefinedTicksPerSecond) { - (void) FormatMagickString(buffer,MaxTextExtent, + (void) FormatLocaleString(buffer,MaxTextExtent, "ticks-per-second=%.20g\n",(double) image->ticks_per_second); (void) WriteBlobString(image,buffer); } } if (image->gravity != UndefinedGravity) { - (void) FormatMagickString(buffer,MaxTextExtent,"gravity=%s\n", - MagickOptionToMnemonic(MagickGravityOptions,image->gravity)); + (void) FormatLocaleString(buffer,MaxTextExtent,"gravity=%s\n", + CommandOptionToMnemonic(MagickGravityOptions,image->gravity)); (void) WriteBlobString(image,buffer); } if (image->dispose != UndefinedDispose) { - (void) FormatMagickString(buffer,MaxTextExtent,"dispose=%s\n", - MagickOptionToMnemonic(MagickDisposeOptions,image->dispose)); + (void) FormatLocaleString(buffer,MaxTextExtent,"dispose=%s\n", + CommandOptionToMnemonic(MagickDisposeOptions,image->dispose)); (void) WriteBlobString(image,buffer); } if (image->rendering_intent != UndefinedIntent) { - (void) FormatMagickString(buffer,MaxTextExtent, - "rendering-intent=%s\n", - MagickOptionToMnemonic(MagickIntentOptions,image->rendering_intent)); + (void) FormatLocaleString(buffer,MaxTextExtent,"rendering-intent=%s\n", + CommandOptionToMnemonic(MagickIntentOptions,image->rendering_intent)); (void) WriteBlobString(image,buffer); } if (image->gamma != 0.0) { - (void) FormatMagickString(buffer,MaxTextExtent,"gamma=%g\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"gamma=%g\n", image->gamma); (void) WriteBlobString(image,buffer); } @@ -1948,7 +2140,7 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, /* Note chomaticity points. */ - (void) FormatMagickString(buffer,MaxTextExtent,"red-primary=%g," + (void) FormatLocaleString(buffer,MaxTextExtent,"red-primary=%g," "%g green-primary=%g,%g blue-primary=%g,%g\n", image->chromaticity.red_primary.x,image->chromaticity.red_primary.y, image->chromaticity.green_primary.x, @@ -1956,15 +2148,15 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, image->chromaticity.blue_primary.x, image->chromaticity.blue_primary.y); (void) WriteBlobString(image,buffer); - (void) FormatMagickString(buffer,MaxTextExtent, + (void) FormatLocaleString(buffer,MaxTextExtent, "white-point=%g,%g\n",image->chromaticity.white_point.x, image->chromaticity.white_point.y); (void) WriteBlobString(image,buffer); } if (image->orientation != UndefinedOrientation) { - (void) FormatMagickString(buffer,MaxTextExtent,"orientation=%s\n", - MagickOptionToMnemonic(MagickOrientationOptions,image->orientation)); + (void) FormatLocaleString(buffer,MaxTextExtent,"orientation=%s\n", + CommandOptionToMnemonic(MagickOrientationOptions,image->orientation)); (void) WriteBlobString(image,buffer); } if (image->profiles != (void *) NULL) @@ -1985,7 +2177,7 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, profile=GetImageProfile(image,name); if (profile != (StringInfo *) NULL) { - (void) FormatMagickString(buffer,MaxTextExtent, + (void) FormatLocaleString(buffer,MaxTextExtent, "profile:%s=%.20g\n",name,(double) GetStringInfoLength(profile)); (void) WriteBlobString(image,buffer); @@ -1995,29 +2187,45 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, } if (image->montage != (char *) NULL) { - (void) FormatMagickString(buffer,MaxTextExtent,"montage=%s\n", + (void) FormatLocaleString(buffer,MaxTextExtent,"montage=%s\n", image->montage); (void) WriteBlobString(image,buffer); } if (quantum_info->format == FloatingPointQuantumFormat) - (void) SetImageProperty(image,"quantum:format","floating-point"); + (void) SetImageProperty(image,"quantum:format","floating-point", + exception); ResetImagePropertyIterator(image); property=GetNextImageProperty(image); while (property != (const char *) NULL) { - (void) FormatMagickString(buffer,MaxTextExtent,"%s=",property); + (void) FormatLocaleString(buffer,MaxTextExtent,"%s=",property); (void) WriteBlobString(image,buffer); - value=GetImageProperty(image,property); + value=GetImageProperty(image,property,exception); if (value != (const char *) NULL) { - for (i=0; i < (ssize_t) strlen(value); i++) + size_t + length; + + length=strlen(value); + for (i=0; i < (ssize_t) length; i++) if (isspace((int) ((unsigned char) value[i])) != 0) break; - if (i <= (ssize_t) strlen(value)) - (void) WriteBlobByte(image,'{'); - (void) WriteBlob(image,strlen(value),(const unsigned char *) value); - if (i <= (ssize_t) strlen(value)) - (void) WriteBlobByte(image,'}'); + if (i == (ssize_t) length) + (void) WriteBlob(image,length,(const unsigned char *) value); + else + { + (void) WriteBlobByte(image,'{'); + if (strchr(value,'}') == (char *) NULL) + (void) WriteBlob(image,length,(const unsigned char *) value); + else + for (i=0; i < (ssize_t) length; i++) + { + if (value[i] == (int) '}') + (void) WriteBlobByte(image,'\\'); + (void) WriteBlobByte(image,value[i]); + } + (void) WriteBlobByte(image,'}'); + } } (void) WriteBlobByte(image,'\n'); property=GetNextImageProperty(image); @@ -2129,173 +2337,191 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, /* Write image pixels to file. */ - quantum_type=GetQuantumType(image,&image->exception); - pixels=GetQuantumPixels(quantum_info); status=MagickTrue; + switch (compression) + { +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: + { + int + code; + + (void) ResetMagickMemory(&bzip_info,0,sizeof(bzip_info)); + bzip_info.bzalloc=AcquireBZIPMemory; + bzip_info.bzfree=RelinquishBZIPMemory; + code=BZ2_bzCompressInit(&bzip_info,(int) (image->quality == + UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10, + 9)),(int) image_info->verbose,0); + if (code != BZ_OK) + status=MagickFalse; + break; + } +#endif +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: + { + int + code; + + (void) ResetMagickMemory(&allocator,0,sizeof(allocator)); + allocator.alloc=AcquireLZMAMemory; + allocator.free=RelinquishLZMAMemory; + lzma_info=initialize_lzma; + lzma_info.allocator=&allocator; + code=lzma_easy_encoder(&lzma_info,image->quality/10,LZMA_CHECK_SHA256); + if (code != LZMA_OK) + status=MagickTrue; + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + int + code; + + (void) ResetMagickMemory(&zip_info,0,sizeof(zip_info)); + zip_info.zalloc=AcquireZIPMemory; + zip_info.zfree=RelinquishZIPMemory; + code=deflateInit(&zip_info,(int) (image->quality == + UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10,9))); + if (code != Z_OK) + status=MagickFalse; + break; + } +#endif + default: + break; + } + quantum_type=GetQuantumType(image,exception); + pixels=GetQuantumPixels(quantum_info); for (y=0; y < (ssize_t) image->rows; y++) { - register const IndexPacket - *restrict indexes; - - register const PixelPacket + register const Quantum *restrict p; register ssize_t x; - p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception); - if (p == (const PixelPacket *) NULL) + if (status == MagickFalse) + break; + p=GetVirtualPixels(image,0,y,image->columns,1,exception); + if (p == (const Quantum *) NULL) break; - indexes=GetVirtualIndexQueue(image); q=pixels; switch (compression) { -#if defined(MAGICKCORE_ZLIB_DELEGATE) - case LZWCompression: - case ZipCompression: +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: { - if (y == 0) - { - zip_info.zalloc=AcquireZIPMemory; - zip_info.zfree=RelinquishZIPMemory; - zip_info.opaque=(voidpf) NULL; - code=deflateInit(&zip_info,(int) (image->quality == - UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10, - 9))); - if (code >= 0) - status=MagickTrue; - } - zip_info.next_in=pixels; - zip_info.avail_in=(uInt) (packet_size*image->columns); - (void) ExportQuantumPixels(image,(const CacheView *) NULL, - quantum_info,quantum_type,pixels,&image->exception); + bzip_info.next_in=(char *) pixels; + bzip_info.avail_in=(unsigned int) (packet_size*image->columns); + (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); do { - zip_info.next_out=compress_pixels; - zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns); - code=deflate(&zip_info,Z_SYNC_FLUSH); - if (code >= 0) - status=MagickTrue; - length=(size_t) (zip_info.next_out-compress_pixels); + int + code; + + bzip_info.next_out=(char *) compress_pixels; + bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size* + image->columns); + code=BZ2_bzCompress(&bzip_info,BZ_FLUSH); + if (code != BZ_OK) + status=MagickFalse; + length=(size_t) (bzip_info.next_out-(char *) compress_pixels); if (length != 0) { (void) WriteBlobMSBLong(image,(unsigned int) length); (void) WriteBlob(image,length,compress_pixels); } - } while (zip_info.avail_in != 0); - if (y == (ssize_t) (image->rows-1)) - { - for ( ; ; ) - { - zip_info.next_out=compress_pixels; - zip_info.avail_out=(uInt) ZipMaxExtent(packet_size* - image->columns); - code=deflate(&zip_info,Z_FINISH); - length=(size_t) (zip_info.next_out-compress_pixels); - if (length > 6) - { - (void) WriteBlobMSBLong(image,(unsigned int) length); - (void) WriteBlob(image,length,compress_pixels); - } - if (code == Z_STREAM_END) - break; - } - status=deflateEnd(&zip_info) == 0 ? MagickTrue : MagickFalse; - } + } while (bzip_info.avail_in != 0); break; } #endif -#if defined(MAGICKCORE_BZLIB_DELEGATE) - case BZipCompression: +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: { - if (y == 0) - { - bzip_info.bzalloc=AcquireBZIPMemory; - bzip_info.bzfree=RelinquishBZIPMemory; - bzip_info.opaque=(void *) NULL; - code=BZ2_bzCompressInit(&bzip_info,(int) (image->quality == - UndefinedCompressionQuality ? 7 : MagickMin(image->quality/10, - 9)), - (int) image_info->verbose,0); - if (code >= 0) - status=MagickTrue; - } - bzip_info.next_in=(char *) pixels; - bzip_info.avail_in=(unsigned int) (packet_size*image->columns); - (void) ExportQuantumPixels(image,(const CacheView *) NULL, - quantum_info,quantum_type,pixels,&image->exception); + lzma_info.next_in=pixels; + lzma_info.avail_in=packet_size*image->columns; + (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); do { - bzip_info.next_out=(char *) compress_pixels; - bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size* - image->columns); - code=BZ2_bzCompress(&bzip_info,BZ_FLUSH); - if (code >= 0) - status=MagickTrue; - length=(size_t) (bzip_info.next_out-(char *) compress_pixels); + int + code; + + lzma_info.next_out=compress_pixels; + lzma_info.avail_out=packet_size*image->columns; + code=lzma_code(&lzma_info,LZMA_RUN); + if (code != LZMA_OK) + status=MagickFalse; + length=(size_t) (lzma_info.next_out-compress_pixels); if (length != 0) { (void) WriteBlobMSBLong(image,(unsigned int) length); (void) WriteBlob(image,length,compress_pixels); } - } while (bzip_info.avail_in != 0); - if (y == (ssize_t) (image->rows-1)) - { - for ( ; ; ) + } while (lzma_info.avail_in != 0); + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + zip_info.next_in=pixels; + zip_info.avail_in=(uInt) (packet_size*image->columns); + (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); + do + { + int + code; + + zip_info.next_out=compress_pixels; + zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns); + code=deflate(&zip_info,Z_SYNC_FLUSH); + if (code != Z_OK) + status=MagickFalse; + length=(size_t) (zip_info.next_out-compress_pixels); + if (length != 0) { - bzip_info.next_out=(char *) compress_pixels; - bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size* - image->columns); - code=BZ2_bzCompress(&bzip_info,BZ_FINISH); - length=(size_t) (bzip_info.next_out-(char *) compress_pixels); - if (length != 0) - { - (void) WriteBlobMSBLong(image,(unsigned int) length); - (void) WriteBlob(image,length,compress_pixels); - } - if (code == BZ_STREAM_END) - break; + (void) WriteBlobMSBLong(image,(unsigned int) length); + (void) WriteBlob(image,length,compress_pixels); } - status=BZ2_bzCompressEnd(&bzip_info) == 0 ? MagickTrue : - MagickFalse; - } + } while (zip_info.avail_in != 0); break; } #endif case RLECompression: { - pixel=(*p); - index=(IndexPacket) 0; - if (indexes != (IndexPacket *) NULL) - index=(*indexes); - length=255; - for (x=0; x < (ssize_t) image->columns; x++) + length=0; + GetPixelInfoPixel(image,p,&pixel); + p+=GetPixelChannels(image); + for (x=1; x < (ssize_t) image->columns; x++) { - if ((length < 255) && (x < (ssize_t) (image->columns-1)) && - (IsColorEqual(p,&pixel) != MagickFalse) && - ((image->matte == MagickFalse) || - (p->opacity == pixel.opacity)) && - ((indexes == (IndexPacket *) NULL) || (index == indexes[x]))) + GetPixelInfoPixel(image,p,&target); + if ((length < 255) && + (IsPixelInfoEquivalent(&pixel,&target) != MagickFalse)) length++; else { - if (x > 0) - q=PopRunlengthPacket(image,q,length,pixel,index); + q=PopRunlengthPacket(image,q,length,&pixel,exception); length=0; } - pixel=(*p); - if (indexes != (IndexPacket *) NULL) - index=indexes[x]; - p++; + GetPixelInfoPixel(image,p,&pixel); + p+=GetPixelChannels(image); } - q=PopRunlengthPacket(image,q,length,pixel,index); + q=PopRunlengthPacket(image,q,length,&pixel,exception); (void) WriteBlob(image,(size_t) (q-pixels),pixels); break; } default: { - (void) ExportQuantumPixels(image,(const CacheView *) NULL, - quantum_info,quantum_type,pixels,&image->exception); + (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, + quantum_type,pixels,exception); (void) WriteBlob(image,packet_size*image->columns,pixels); break; } @@ -2308,6 +2534,95 @@ static MagickBooleanType WriteMIFFImage(const ImageInfo *image_info, break; } } + switch (compression) + { +#if defined(MAGICKCORE_BZLIB_DELEGATE) + case BZipCompression: + { + int + code; + + for ( ; ; ) + { + if (status == MagickFalse) + break; + bzip_info.next_out=(char *) compress_pixels; + bzip_info.avail_out=(unsigned int) BZipMaxExtent(packet_size* + image->columns); + code=BZ2_bzCompress(&bzip_info,BZ_FINISH); + length=(size_t) (bzip_info.next_out-(char *) compress_pixels); + if (length != 0) + { + (void) WriteBlobMSBLong(image,(unsigned int) length); + (void) WriteBlob(image,length,compress_pixels); + } + if (code == BZ_STREAM_END) + break; + } + code=BZ2_bzCompressEnd(&bzip_info); + if (code != BZ_OK) + status=MagickFalse; + break; + } +#endif +#if defined(MAGICKCORE_LZMA_DELEGATE) + case LZMACompression: + { + int + code; + + for ( ; ; ) + { + if (status == MagickFalse) + break; + lzma_info.next_out=compress_pixels; + lzma_info.avail_out=packet_size*image->columns; + code=lzma_code(&lzma_info,LZMA_FINISH); + length=(size_t) (lzma_info.next_out-compress_pixels); + if (length > 6) + { + (void) WriteBlobMSBLong(image,(unsigned int) length); + (void) WriteBlob(image,length,compress_pixels); + } + if (code == LZMA_STREAM_END) + break; + } + lzma_end(&lzma_info); + break; + } +#endif +#if defined(MAGICKCORE_ZLIB_DELEGATE) + case LZWCompression: + case ZipCompression: + { + int + code; + + for ( ; ; ) + { + if (status == MagickFalse) + break; + zip_info.next_out=compress_pixels; + zip_info.avail_out=(uInt) ZipMaxExtent(packet_size*image->columns); + code=deflate(&zip_info,Z_FINISH); + length=(size_t) (zip_info.next_out-compress_pixels); + if (length > 6) + { + (void) WriteBlobMSBLong(image,(unsigned int) length); + (void) WriteBlob(image,length,compress_pixels); + } + if (code == Z_STREAM_END) + break; + } + code=deflateEnd(&zip_info); + if (code != Z_OK) + status=MagickFalse; + break; + } +#endif + default: + break; + } quantum_info=DestroyQuantumInfo(quantum_info); compress_pixels=(unsigned char *) RelinquishMagickMemory(compress_pixels); if (GetNextImageInList(image) == (Image *) NULL)