]> granicus.if.org Git - imagemagick/commitdiff
(no commit message)
authorcristy <urban-warrior@git.imagemagick.org>
Sun, 10 Jan 2010 20:15:51 +0000 (20:15 +0000)
committercristy <urban-warrior@git.imagemagick.org>
Sun, 10 Jan 2010 20:15:51 +0000 (20:15 +0000)
magick/quantum-export.c
magick/quantum-import.c
magick/quantum-private.h

index ad2b784884f47f5dad9766d9b9c8b9b615c288f4..595971b798dbdb7d77de0584bc961ac13265a11e 100644 (file)
@@ -429,7 +429,7 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                q=PopShortPixel(endian,ScaleFloatToHalf(QuantumScale*
+                q=PopShortPixel(endian,SinglePrecisionToBinary16(QuantumScale*
                   indexes[x]),q);
                 q+=quantum_info->pad;
               }
@@ -589,8 +589,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
               for (x=0; x < (long) number_pixels; x++)
               {
                 q=PopShortPixel(endian,(unsigned short) indexes[x],q);
-                pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-
-                  GetOpacityPixelComponent(p)));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetAlphaPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -828,7 +828,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*PixelIntensityToQuantum(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  PixelIntensityToQuantum(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1007,10 +1008,11 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*PixelIntensityToQuantum(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  PixelIntensityToQuantum(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-
-                  GetOpacityPixelComponent(p)));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetAlphaPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1126,7 +1128,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetRedPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetRedPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1222,7 +1225,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetGreenPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetGreenPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1318,7 +1322,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetBluePixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetBluePixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1414,8 +1419,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-
-                  GetOpacityPixelComponent(p)));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetAlphaPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1520,7 +1525,8 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetOpacityPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetOpacityPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1621,7 +1627,7 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*indexes[x]);
+                pixel=SinglePrecisionToBinary16(QuantumScale*indexes[x]);
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1873,11 +1879,14 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetRedPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetRedPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetGreenPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetGreenPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetBluePixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetBluePixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -1997,14 +2006,17 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetRedPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetRedPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetGreenPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetGreenPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetBluePixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetBluePixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-
-                  GetOpacityPixelComponent(p)));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetAlphaPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -2145,13 +2157,16 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetRedPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetRedPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetGreenPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetGreenPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetBluePixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetBluePixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*indexes[x]);
+                pixel=SinglePrecisionToBinary16(QuantumScale*indexes[x]);
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
@@ -2286,16 +2301,19 @@ MagickExport size_t ExportQuantumPixels(const Image *image,
             {
               for (x=0; x < (long) number_pixels; x++)
               {
-                pixel=ScaleFloatToHalf(QuantumScale*GetRedPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetRedPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetGreenPixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetGreenPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*GetBluePixelComponent(p));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetBluePixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*indexes[x]);
+                pixel=SinglePrecisionToBinary16(QuantumScale*indexes[x]);
                 q=PopShortPixel(endian,pixel,q);
-                pixel=ScaleFloatToHalf(QuantumScale*(QuantumRange-
-                  GetOpacityPixelComponent(p)));
+                pixel=SinglePrecisionToBinary16(QuantumScale*
+                  GetAlphaPixelComponent(p));
                 q=PopShortPixel(endian,pixel,q);
                 p++;
                 q+=quantum_info->pad;
index e768cab88f832e744c92d85c5b69142e9e4122f6..98c95e42248c27aa210f5651917e243f44b4fc11 100644 (file)
@@ -412,8 +412,8 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 indexes[x]=PushColormapIndex(image,ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)),
-                  &range_exception);
+                  (MagickRealType) QuantumRange*
+                  Binary16ToSinglePrecision(pixel)),&range_exception);
                 *q=image->colormap[(long) indexes[x]];
                 p+=quantum_info->pad;
                 q++;
@@ -600,12 +600,13 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 indexes[x]=PushColormapIndex(image,ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)),
-                  &range_exception);
+                  (MagickRealType) QuantumRange*
+                  Binary16ToSinglePrecision(pixel)),&range_exception);
                 *q=image->colormap[(long) indexes[x]];
                 p=PushShortPixel(endian,p,&pixel);
                 q->opacity=(Quantum) (QuantumRange-ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)));
+                  (MagickRealType) QuantumRange*
+                  Binary16ToSinglePrecision(pixel)));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -926,7 +927,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 q->green=q->red;
                 q->blue=q->red;
                 p+=quantum_info->pad;
@@ -1131,12 +1132,13 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 q->green=q->red;
                 q->blue=q->red;
                 p=PushShortPixel(endian,p,&pixel);
                 q->opacity=(Quantum) (QuantumRange-ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)));
+                  (MagickRealType) QuantumRange*
+                  Binary16ToSinglePrecision(pixel)));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -1261,7 +1263,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -1366,7 +1368,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->green=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -1471,7 +1473,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->blue=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -1576,7 +1578,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
                 p=PushShortPixel(endian,p,&pixel);
                 q->opacity=(Quantum) (QuantumRange-ClampToQuantum(
                   (MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel)));
+                  Binary16ToSinglePrecision(pixel)));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -1685,7 +1687,7 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 indexes[x]=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
               }
               break;
@@ -1944,13 +1946,13 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->green=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->blue=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -2152,16 +2154,17 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->green=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->blue=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->opacity=(Quantum) (QuantumRange-ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)));
+                  (MagickRealType) QuantumRange*
+                  Binary16ToSinglePrecision(pixel)));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -2306,16 +2309,16 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->green=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->blue=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 indexes[x]=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p+=quantum_info->pad;
                 q++;
               }
@@ -2463,19 +2466,19 @@ MagickExport size_t ImportQuantumPixels(Image *image,CacheView *image_view,
               {
                 p=PushShortPixel(endian,p,&pixel);
                 q->red=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->green=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->blue=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 indexes[x]=ClampToQuantum((MagickRealType) QuantumRange*
-                  ScaleHalfToFloat(pixel));
+                  Binary16ToSinglePrecision(pixel));
                 p=PushShortPixel(endian,p,&pixel);
                 q->opacity=(Quantum) (QuantumRange-ClampToQuantum(
-                  (MagickRealType) QuantumRange*ScaleHalfToFloat(pixel)));
+                  (MagickRealType) QuantumRange*Binary16ToSinglePrecision(pixel)));
                 p+=quantum_info->pad;
                 q++;
               }
index 2a1a25d27e4fd5533151b0a0c940949638fc685d..d1f0af513c6b0db1192f659b6e3358b12114b281 100644 (file)
@@ -82,14 +82,80 @@ struct _QuantumInfo
     signature;
 };
 
-typedef union _HalfFloat
+static inline float Binary16ToSinglePrecision(const unsigned short binary16)
 {
+#define ExponentBias  (127-15) 
+#define ExponentMask  0x7c00
+#define ExponentShift  23
+#define SignificandShift  13
+#define SignificandMask  0x00000400
+#define SignBitShift  31
+
+  typedef union _SinglePrecision
+  {
+    unsigned int
+      fixed_point;
+
+    float
+      single_precision;
+  } SinglePrecision;
+
+  register unsigned int
+    exponent,
+    significand,
+    sign_bit;
+
+  SinglePrecision
+    map;
+
   unsigned int
-    fixed_point;
+    value;
+
+  /*
+    The IEEE 754 standard specifies a binary16 as having:
 
-  float
-    single_precision;
-} HalfFloat;
+      Sign bit: 1 bit
+      Exponent width: 5 bits
+      Significand precision: 11 (10 explicitly stored)
+  */
+  sign_bit=(unsigned int) ((binary16 >> 15) & 0x00000001);
+  exponent=(unsigned int) ((binary16 >> 10) & 0x0000001f);
+  significand=(unsigned int) (binary16 & 0x000003ff);
+  if (exponent == 0)
+    {
+       if (significand == 0)
+        value=sign_bit << SignBitShift;
+           else
+             {
+          while ((significand & SignificandMask) == 0)
+          {
+            significand<<=1;
+            exponent--;
+          }
+               exponent++;
+          significand&=(~SignificandMask);
+          exponent+=ExponentBias;
+          value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
+            (significand << SignificandShift);
+               }
+    }
+  else
+    if (exponent == SignBitShift)
+      {
+        value=(sign_bit << SignBitShift) | 0x7f800000;
+        if (significand != 0)
+          value|=(significand << SignificandShift);
+      }
+    else
+      {
+        exponent+=ExponentBias;
+        significand<<=SignificandShift;
+        value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
+          significand;
+      }
+  map.fixed_point=value;
+  return(map.single_precision);
+}
 
 static inline MagickSizeType GetQuantumRange(const unsigned long depth)
 {
@@ -230,139 +296,6 @@ 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 SignificandShift  13
-
-  HalfFloat
-    pixel;
-
-  register int
-    exponent;
-
-  register unsigned int
-    significand,
-    sign_bit;
-
-  unsigned short
-    half;
-
-  pixel.single_precision=value;
-  sign_bit=(pixel.fixed_point >> 16) & 0x00008000;
-  exponent=(int) ((pixel.fixed_point >> ExponentShift) & 0x000000ff)-
-    ExponentBias;
-  significand=pixel.fixed_point & 0x007fffff;
-  if (exponent <= 0)
-    {
-      long
-        shift;
-
-      if (exponent < -10)
-        return((unsigned short) sign_bit);
-      significand=significand | 0x00800000;
-      shift=14-exponent;
-      significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
-        ((significand >> shift) & 0x01)) >> shift);
-      return((unsigned short) (sign_bit | significand));
-    }
-  else
-    if (exponent == (0xff-ExponentBias))
-      {
-        if (significand == 0)
-          return((unsigned short) (sign_bit | ExponentMask));
-        else
-          {
-            significand>>=SignificandShift;
-            half=(unsigned short) (sign_bit | significand | (significand == 0) |
-              ExponentMask);
-            return(half);
-          }
-      }
-  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
-  if ((significand & 0x00800000) != 0)
-    {
-      significand=0;
-      exponent++;
-    }
-  if (exponent > 30)
-    {
-      float
-        alpha;
-
-      register long
-        i;
-
-      /*
-        Float overflow.
-      */
-      alpha=1.0e10;
-      for (i=0; i < 10; i++)
-        alpha*=alpha;
-      return((unsigned short) (sign_bit | ExponentMask));
-    }
-  half=(unsigned short) (sign_bit | (exponent << 10) |
-    (significand >> SignificandShift));
-  return(half);
-}
-
-static inline float ScaleHalfToFloat(const unsigned short quantum)
-{
-#define SignificandMask  0x00000400
-#define SignBitShift  31
-
-  HalfFloat
-    pixel;
-
-  register unsigned int
-    exponent,
-    significand,
-    sign_bit;
-
-  unsigned int
-    value;
-
-  sign_bit=(unsigned int) ((quantum >> 15) & 0x00000001);
-  exponent=(unsigned int) ((quantum >> 10) & 0x0000001f);
-  significand=(unsigned int) (quantum & 0x000003ff);
-  if (exponent == 0)
-    {
-       if (significand == 0)
-        value=sign_bit << SignBitShift;
-           else
-             {
-          while ((significand & SignificandMask) == 0)
-          {
-            significand<<=1;
-            exponent--;
-          }
-               exponent++;
-          significand&=(~SignificandMask);
-          exponent+=ExponentBias;
-          value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
-            (significand << SignificandShift);
-               }
-    }
-  else
-    if (exponent == SignBitShift)
-      {
-        value=(sign_bit << SignBitShift) | 0x7f800000;
-        if (significand != 0)
-          value|=(significand << SignificandShift);
-      }
-    else
-      {
-        exponent+=ExponentBias;
-        significand<<=SignificandShift;
-        value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
-          significand;
-      }
-  pixel.fixed_point=value;
-  return(pixel.single_precision);
-}
-
 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
   const QuantumAny range)
 {
@@ -666,6 +599,94 @@ static inline Quantum ScaleShortToQuantum(const unsigned short value)
 }
 #endif
 
+static inline unsigned short SinglePrecisionToBinary16(const float value)
+{
+  typedef union _SinglePrecision
+  {
+    unsigned int
+      fixed_point;
+
+    float
+      single_precision;
+  } SinglePrecision;
+
+  register int
+    exponent;
+
+  register unsigned int
+    significand,
+    sign_bit;
+
+  SinglePrecision
+    map;
+
+  unsigned short
+    binary16;
+
+  /*
+    The IEEE 754 standard specifies a binary16 as having:
+
+      Sign bit: 1 bit
+      Exponent width: 5 bits
+      Significand precision: 11 (10 explicitly stored)
+  */
+  map.single_precision=value;
+  sign_bit=(map.fixed_point >> 16) & 0x00008000;
+  exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
+  significand=map.fixed_point & 0x007fffff;
+  if (exponent <= 0)
+    {
+      long
+        shift;
+
+      if (exponent < -10)
+        return((unsigned short) sign_bit);
+      significand=significand | 0x00800000;
+      shift=14-exponent;
+      significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
+        ((significand >> shift) & 0x01)) >> shift);
+      return((unsigned short) (sign_bit | significand));
+    }
+  else
+    if (exponent == (0xff-ExponentBias))
+      {
+        if (significand == 0)
+          return((unsigned short) (sign_bit | ExponentMask));
+        else
+          {
+            significand>>=SignificandShift;
+            binary16=(unsigned short) (sign_bit | significand |
+              (significand == 0) | ExponentMask);
+            return(binary16);
+          }
+      }
+  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
+  if ((significand & 0x00800000) != 0)
+    {
+      significand=0;
+      exponent++;
+    }
+  if (exponent > 30)
+    {
+      float
+        alpha;
+
+      register long
+        i;
+
+      /*
+        Float overflow.
+      */
+      alpha=1.0e10;
+      for (i=0; i < 10; i++)
+        alpha*=alpha;
+      return((unsigned short) (sign_bit | ExponentMask));
+    }
+  binary16=(unsigned short) (sign_bit | (exponent << 10) |
+    (significand >> SignificandShift));
+  return(binary16);
+}
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif