From c9672a94adef17dee351f074e7c9915405ef29e1 Mon Sep 17 00:00:00 2001 From: cristy Date: Wed, 6 Jan 2010 00:57:45 +0000 Subject: [PATCH] --- ChangeLog | 4 + magick/option.c | 1 - magick/quantum-export.c | 180 ++++++++++++++++++++++++++ magick/quantum-import.c | 206 ++++++++++++++++++++++++++++++ magick/quantum-private.h | 268 +++++++++++++++++++-------------------- magick/quantum.c | 11 +- magick/quantum.h | 3 +- 7 files changed, 531 insertions(+), 142 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ec082ee0..7405f449d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2010-01-01 6.5.9-0 Cristy + * Add support for compact floating point (i.e. -depth 16 -define + quantum:format=floating-point). + 2010-01-05 6.5.9-0 Stephan Menzel * Add support for the BGRA raw image format. diff --git a/magick/option.c b/magick/option.c index dd1344b0b..a6a0aab78 100644 --- a/magick/option.c +++ b/magick/option.c @@ -1324,7 +1324,6 @@ static const OptionInfo { "FloatingPoint", (long) FloatingPointQuantumFormat, MagickFalse }, { "Signed", (long) SignedQuantumFormat, MagickFalse }, { "Unsigned", (long) UnsignedQuantumFormat, MagickFalse }, - { "CompactFloatingPoint", (long) CompactFloatingPointQuantumFormat, MagickFalse }, { (char *) NULL, (long) FloatingPointQuantumFormat, MagickFalse } }, ResolutionOptions[] = diff --git a/magick/quantum-export.c b/magick/quantum-export.c index fabf9c6ff..ad85321f6 100644 --- a/magick/quantum-export.c +++ b/magick/quantum-export.c @@ -425,6 +425,16 @@ MagickExport size_t ExportQuantumPixels(const Image *image, } case 16: { + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + q=PopShortPixel(endian,ScaleFloatToHalf(QuantumScale* + indexes[x]),q); + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { q=PopShortPixel(endian,(unsigned short) indexes[x],q); @@ -573,6 +583,18 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + q=PopShortPixel(endian,(unsigned short) indexes[x],q); + pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-p->opacity)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { q=PopShortPixel(endian,(unsigned short) indexes[x],q); @@ -798,6 +820,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*PixelIntensityToQuantum(p)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(PixelIntensityToQuantum(p)); @@ -965,6 +998,19 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*PixelIntensityToQuantum(p)); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-p->opacity)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(PixelIntensityToQuantum(p)); @@ -1068,6 +1114,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->red); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->red); @@ -1153,6 +1210,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->green); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->green); @@ -1238,6 +1306,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->blue); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->blue); @@ -1322,6 +1401,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-p->opacity)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort((Quantum) (QuantumRange-p->opacity)); @@ -1414,6 +1504,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->opacity); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->opacity); @@ -1504,6 +1605,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*indexes[x]); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(indexes[x]); @@ -1745,6 +1857,21 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->red); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->green); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->blue); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->red); @@ -1853,6 +1980,23 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->red); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->green); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->blue); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-p->opacity)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->red); @@ -1981,6 +2125,23 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->red); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->green); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->blue); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*indexes[x]); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->red); @@ -2104,6 +2265,25 @@ MagickExport size_t ExportQuantumPixels(const Image *image, register unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + pixel=ScaleFloatToHalf(QuantumScale*p->red); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->green); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*p->blue); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*indexes[x]); + q=PopShortPixel(endian,pixel,q); + pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-p->opacity)); + q=PopShortPixel(endian,pixel,q); + p++; + q+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { pixel=ScaleQuantumToShort(p->red); diff --git a/magick/quantum-import.c b/magick/quantum-import.c index fe8d32b6b..24663c66e 100644 --- a/magick/quantum-import.c +++ b/magick/quantum-import.c @@ -406,6 +406,20 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + indexes[x]=PushColormapIndex(image,RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)), + &range_exception); + *q=image->colormap[(long) indexes[x]]; + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -580,6 +594,23 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + indexes[x]=PushColormapIndex(image,RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)), + &range_exception); + *q=image->colormap[(long) indexes[x]]; + p=PushShortPixel(endian,p,&pixel); + q->opacity=(Quantum) (QuantumRange-RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel))); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -889,6 +920,20 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, } break; } + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + q->green=q->red; + q->blue=q->red; + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1080,6 +1125,23 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + q->green=q->red; + q->blue=q->red; + p=PushShortPixel(endian,p,&pixel); + q->opacity=(Quantum) (QuantumRange-RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel))); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1193,6 +1255,18 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1286,6 +1360,18 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->green=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1379,6 +1465,18 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->blue=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1471,6 +1569,19 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->opacity=(Quantum) (QuantumRange-RoundToQuantum( + (MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel))); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1568,6 +1679,17 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + indexes[x]=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -1816,6 +1938,24 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->green=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->blue=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -2006,6 +2146,27 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->green=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->blue=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->opacity=(Quantum) (QuantumRange-RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel))); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -2139,6 +2300,27 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->green=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->blue=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + indexes[x]=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); @@ -2275,6 +2457,30 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view, unsigned short pixel; + if (quantum_info->format == FloatingPointQuantumFormat) + { + for (x=0; x < (long) number_pixels; x++) + { + p=PushShortPixel(endian,p,&pixel); + q->red=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->green=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->blue=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + indexes[x]=RoundToQuantum((MagickRealType) QuantumRange* + ScaleHalfToFloat(pixel)); + p=PushShortPixel(endian,p,&pixel); + q->opacity=(Quantum) (QuantumRange-RoundToQuantum( + (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel))); + p+=quantum_info->pad; + q++; + } + break; + } for (x=0; x < (long) number_pixels; x++) { p=PushShortPixel(endian,p,&pixel); diff --git a/magick/quantum-private.h b/magick/quantum-private.h index 20a0e9bba..2d08b015c 100644 --- a/magick/quantum-private.h +++ b/magick/quantum-private.h @@ -82,14 +82,14 @@ struct _QuantumInfo signature; }; -typedef union _CompactFloat +typedef union _HalfFloat { unsigned int cf_uint; float cf_float; -} CompactFloat; +} HalfFloat; static inline MagickSizeType GetQuantumRange(const unsigned long depth) { @@ -122,138 +122,6 @@ static inline void InitializeQuantumState(const QuantumInfo *quantum_info, quantum_state->mask=mask; } -static inline unsigned short DecodeCompactFloatPixel(const float value) -{ -#define ExponentBias (127-15) -#define ExponentMask 0x7c00 -#define ExponentShift 23 -#define MantissaShift 13 - - CompactFloat - decode; - - register int - exponent; - - register unsigned int - mantissa, - sign; - - unsigned short - compact; - - decode.cf_float=value; - sign=(decode.cf_uint >> 16) & 0x00008000; - exponent=((decode.cf_uint >> ExponentShift) & 0x000000ff)- - ExponentBias; - mantissa=decode.cf_uint & 0x007fffff; - if (exponent <= 0) - { - long - shift; - - if (exponent < -10) - return(sign); - mantissa=mantissa | 0x00800000; - shift=14-exponent; - mantissa=(mantissa+((1 << (shift-1))-1)+((mantissa >> shift) & 0x01)) >> - shift; - return((unsigned short) (sign | mantissa)); - } - else - if (exponent == (0xff-ExponentBias)) - { - if (mantissa == 0) - return(sign | ExponentMask); - else - { - mantissa>>=MantissaShift; - compact=(unsigned short) (sign | mantissa | (mantissa == 0) | - ExponentMask); - return(compact); - } - } - mantissa=mantissa+((mantissa >> MantissaShift) & 0x01)+0x00000fff; - if ((mantissa & 0x00800000) != 0) - { - mantissa=0; - exponent++; - } - if (exponent > 30) - { - float - alpha; - - register long - i; - - /* - Float overflow. - */ - alpha=1e10; - for (i=0; i < 10; i++) - alpha*=alpha; - return((unsigned short) (sign | ExponentMask)); - } - compact=(unsigned short) (sign | (exponent << 10) | - (mantissa >> MantissaShift)); - return(compact); -} - -static inline float EncodeCompactFloatPixel(const unsigned short quantum) -{ -#define MantissaMask 0x00000400 -#define SignShift 31 - - CompactFloat - encode; - - register unsigned int - exponent, - mantissa, - sign; - - unsigned int - value; - - sign=(quantum >> 15) & 0x00000001; - exponent=(quantum >> 10) & 0x0000001f; - mantissa=quantum & 0x000003ff; - if (exponent == 0) - { - if (mantissa == 0) - value=sign << SignShift; - else - { - while ((mantissa & MantissaMask) == 0) - { - mantissa<<=1; - exponent--; - } - exponent++; - mantissa&=(~MantissaMask); - exponent+=ExponentBias; - value=(sign << SignShift) | (exponent << ExponentShift) | - (mantissa << MantissaShift); - } - } - else - if (exponent == SignShift) - { - value=(sign << SignShift) | 0x7f800000; - if (mantissa != 0) - value|=(mantissa << MantissaShift); - } - else - { - exponent+=ExponentBias; - mantissa=mantissa << MantissaShift; - value=(sign << SignShift) | (exponent << ExponentShift) | mantissa; - } - encode.cf_uint=value; - return(encode.cf_float); -} - static inline unsigned char *PopCharPixel(const unsigned char pixel, unsigned char *pixels) { @@ -362,6 +230,138 @@ static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum, #endif } +static inline unsigned short ScaleFloatToHalf(const float value) +{ +#define ExponentBias (127-15) +#define ExponentMask 0x7c00 +#define ExponentShift 23 +#define MantissaShift 13 + + HalfFloat + pixel; + + register int + exponent; + + register unsigned int + mantissa, + sign; + + unsigned short + half; + + pixel.cf_float=value; + sign=(pixel.cf_uint >> 16) & 0x00008000; + exponent=(int) ((pixel.cf_uint >> ExponentShift) & 0x000000ff)- + ExponentBias; + mantissa=pixel.cf_uint & 0x007fffff; + if (exponent <= 0) + { + long + shift; + + if (exponent < -10) + return((unsigned short) sign); + mantissa=mantissa | 0x00800000; + shift=14-exponent; + mantissa=(unsigned int) ((mantissa+((1 << (shift-1))-1)+ + ((mantissa >> shift) & 0x01)) >> shift); + return((unsigned short) (sign | mantissa)); + } + else + if (exponent == (0xff-ExponentBias)) + { + if (mantissa == 0) + return((unsigned short) (sign | ExponentMask)); + else + { + mantissa>>=MantissaShift; + half=(unsigned short) (sign | mantissa | (mantissa == 0) | + ExponentMask); + return(half); + } + } + mantissa=mantissa+((mantissa >> MantissaShift) & 0x01)+0x00000fff; + if ((mantissa & 0x00800000) != 0) + { + mantissa=0; + exponent++; + } + if (exponent > 30) + { + float + alpha; + + register long + i; + + /* + Float overflow. + */ + alpha=1e10; + for (i=0; i < 10; i++) + alpha*=alpha; + return((unsigned short) (sign | ExponentMask)); + } + half=(unsigned short) (sign | (exponent << 10) | + (mantissa >> MantissaShift)); + return(half); +} + +static inline float ScaleHalfToFloat(const unsigned short quantum) +{ +#define MantissaMask 0x00000400 +#define SignShift 31 + + HalfFloat + pixel; + + register unsigned int + exponent, + mantissa, + sign; + + unsigned int + value; + + sign=(unsigned int) ((quantum >> 15) & 0x00000001); + exponent=(unsigned int) ((quantum >> 10) & 0x0000001f); + mantissa=(unsigned int) (quantum & 0x000003ff); + if (exponent == 0) + { + if (mantissa == 0) + value=sign << SignShift; + else + { + while ((mantissa & MantissaMask) == 0) + { + mantissa<<=1; + exponent--; + } + exponent++; + mantissa&=(~MantissaMask); + exponent+=ExponentBias; + value=(sign << SignShift) | (exponent << ExponentShift) | + (mantissa << MantissaShift); + } + } + else + if (exponent == SignShift) + { + value=(sign << SignShift) | 0x7f800000; + if (mantissa != 0) + value|=(mantissa << MantissaShift); + } + else + { + exponent+=ExponentBias; + mantissa=mantissa << MantissaShift; + value=(sign << SignShift) | (exponent << ExponentShift) | mantissa; + } + pixel.cf_uint=value; + return(pixel.cf_float); +} + static inline QuantumAny ScaleQuantumToAny(const Quantum quantum, const QuantumAny range) { diff --git a/magick/quantum.c b/magick/quantum.c index a6d7e21c6..746e6a63b 100644 --- a/magick/quantum.c +++ b/magick/quantum.c @@ -313,8 +313,8 @@ MagickExport size_t GetQuantumExtent(const Image *image, default: break; } if (quantum_info->pack == MagickFalse) - return((size_t) (packet_size*image->columns*((image->depth+7)/8))); - return((size_t) ((packet_size*image->columns*image->depth+7)/8)); + return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8))); + return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8)); } /* @@ -558,10 +558,11 @@ MagickExport MagickBooleanType SetQuantumDepth(const Image *image, if (quantum_info->depth > 32) quantum_info->depth=64; else - quantum_info->depth=32; + if (quantum_info->depth > 16) + quantum_info->depth=32; + else + quantum_info->depth=16; } - if (quantum_info->format == CompactFloatingPointQuantumFormat) - quantum_info->depth=16; if (quantum_info->pixels != (unsigned char **) NULL) DestroyQuantumPixels(quantum_info); status=AcquireQuantumPixels(quantum_info,(quantum_info->pad+5)*image->columns* diff --git a/magick/quantum.h b/magick/quantum.h index 7cef8d118..8727bf0d7 100644 --- a/magick/quantum.h +++ b/magick/quantum.h @@ -43,8 +43,7 @@ typedef enum UndefinedQuantumFormat, FloatingPointQuantumFormat, SignedQuantumFormat, - UnsignedQuantumFormat, - CompactFloatingPointQuantumFormat + UnsignedQuantumFormat } QuantumFormatType; typedef enum -- 2.40.0