]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Tue, 5 Jan 2010 20:52:48 +0000 (20:52 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Tue, 5 Jan 2010 20:52:48 +0000 (20:52 +0000)
magick/option.c
magick/quantum-private.h
magick/quantum.h

index a6a0aab783ba3f58073203eabd04c88a6de73f6c..dd1344b0be00b6e00c6a4e64f8549e8fec9f82f0 100644 (file)
@@ -1324,6 +1324,7 @@ 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[] =
index 856d277055106a530db6359cf72a444b0b599736..20a0e9bba347f03e86444335357849c2ca7e3c2d 100644 (file)
@@ -82,6 +82,15 @@ struct _QuantumInfo
     signature;
 };
 
+typedef union _CompactFloat
+{
+  unsigned int
+    cf_uint;
+
+  float
+    cf_float;
+} CompactFloat;
+
 static inline MagickSizeType GetQuantumRange(const unsigned long depth)
 {
   return((MagickSizeType) ((MagickULLConstant(1) << (depth-1))+
@@ -113,6 +122,138 @@ 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)
 {
index 8727bf0d7aa271280310c15f3128d876ebfee390..7cef8d118cc981e91b66a8e774615dcce1af37cf 100644 (file)
@@ -43,7 +43,8 @@ typedef enum
   UndefinedQuantumFormat,
   FloatingPointQuantumFormat,
   SignedQuantumFormat,
-  UnsignedQuantumFormat
+  UnsignedQuantumFormat,
+  CompactFloatingPointQuantumFormat
 } QuantumFormatType;
 
 typedef enum