1 : /******************************************************************************
2 : * $Id: tif_float.c 10645 2007-01-18 02:22:39Z warmerdam $
3 : *
4 : * Project: GeoTIFF Driver
5 : * Purpose: Floating point conversion functions. Convert 16- and 24-bit
6 : * floating point numbers into the 32-bit IEEE 754 compliant ones.
7 : * Author: Andrey Kiselev, dron@remotesensing.org
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2005, Andrey Kiselev <dron@remotesensing.org>
11 : *
12 : * This code is based on the code from OpenEXR project with the following
13 : * copyright:
14 : *
15 : * Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
16 : * Digital Ltd. LLC
17 : *
18 : * All rights reserved.
19 : *
20 : * Redistribution and use in source and binary forms, with or without
21 : * modification, are permitted provided that the following conditions are
22 : * met:
23 : * * Redistributions of source code must retain the above copyright
24 : * notice, this list of conditions and the following disclaimer.
25 : * * Redistributions in binary form must reproduce the above
26 : * copyright notice, this list of conditions and the following disclaimer
27 : * in the documentation and/or other materials provided with the
28 : * distribution.
29 : * * Neither the name of Industrial Light & Magic nor the names of
30 : * its contributors may be used to endorse or promote products derived
31 : * from this software without specific prior written permission.
32 : *
33 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
36 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
39 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
40 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
41 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
43 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 : *
45 : ****************************************************************************/
46 :
47 : #include "cpl_port.h"
48 :
49 : /************************************************************************/
50 : /* HalfToFloat() */
51 : /* */
52 : /* 16-bit floating point number to 32-bit one. */
53 : /************************************************************************/
54 :
55 400 : GUInt32 HalfToFloat( GUInt16 iHalf )
56 : {
57 :
58 400 : GUInt32 iSign = (iHalf >> 15) & 0x00000001;
59 400 : GUInt32 iExponent = (iHalf >> 10) & 0x0000001f;
60 400 : GUInt32 iMantissa = iHalf & 0x000003ff;
61 :
62 400 : if (iExponent == 0)
63 : {
64 0 : if (iMantissa == 0)
65 : {
66 : /* -------------------------------------------------------------------- */
67 : /* Plus or minus zero. */
68 : /* -------------------------------------------------------------------- */
69 :
70 0 : return iSign << 31;
71 : }
72 : else
73 : {
74 : /* -------------------------------------------------------------------- */
75 : /* Denormalized number -- renormalize it. */
76 : /* -------------------------------------------------------------------- */
77 :
78 0 : while (!(iMantissa & 0x00000400))
79 : {
80 0 : iMantissa <<= 1;
81 0 : iExponent -= 1;
82 : }
83 :
84 0 : iExponent += 1;
85 0 : iMantissa &= ~0x00000400;
86 : }
87 : }
88 400 : else if (iExponent == 31)
89 : {
90 0 : if (iMantissa == 0)
91 : {
92 : /* -------------------------------------------------------------------- */
93 : /* Positive or negative infinity. */
94 : /* -------------------------------------------------------------------- */
95 :
96 0 : return (iSign << 31) | 0x7f800000;
97 : }
98 : else
99 : {
100 : /* -------------------------------------------------------------------- */
101 : /* NaN -- preserve sign and significand bits. */
102 : /* -------------------------------------------------------------------- */
103 :
104 0 : return (iSign << 31) | 0x7f800000 | (iMantissa << 13);
105 : }
106 : }
107 :
108 : /* -------------------------------------------------------------------- */
109 : /* Normalized number. */
110 : /* -------------------------------------------------------------------- */
111 :
112 400 : iExponent = iExponent + (127 - 15);
113 400 : iMantissa = iMantissa << 13;
114 :
115 : /* -------------------------------------------------------------------- */
116 : /* Assemble sign, exponent and mantissa. */
117 : /* -------------------------------------------------------------------- */
118 :
119 400 : return (iSign << 31) | (iExponent << 23) | iMantissa;
120 : }
121 :
122 : /************************************************************************/
123 : /* TripleToFloat() */
124 : /* */
125 : /* 24-bit floating point number to 32-bit one. */
126 : /************************************************************************/
127 :
128 400 : GUInt32 TripleToFloat( GUInt32 iTriple )
129 : {
130 :
131 400 : GUInt32 iSign = (iTriple >> 23) & 0x00000001;
132 400 : GUInt32 iExponent = (iTriple >> 16) & 0x0000007f;
133 400 : GUInt32 iMantissa = iTriple & 0x0000ffff;
134 :
135 400 : if (iExponent == 0)
136 : {
137 0 : if (iMantissa == 0)
138 : {
139 : /* -------------------------------------------------------------------- */
140 : /* Plus or minus zero. */
141 : /* -------------------------------------------------------------------- */
142 :
143 0 : return iSign << 31;
144 : }
145 : else
146 : {
147 : /* -------------------------------------------------------------------- */
148 : /* Denormalized number -- renormalize it. */
149 : /* -------------------------------------------------------------------- */
150 :
151 0 : while (!(iMantissa & 0x00002000))
152 : {
153 0 : iMantissa <<= 1;
154 0 : iExponent -= 1;
155 : }
156 :
157 0 : iExponent += 1;
158 0 : iMantissa &= ~0x00002000;
159 : }
160 : }
161 400 : else if (iExponent == 127)
162 : {
163 0 : if (iMantissa == 0)
164 : {
165 : /* -------------------------------------------------------------------- */
166 : /* Positive or negative infinity. */
167 : /* -------------------------------------------------------------------- */
168 :
169 0 : return (iSign << 31) | 0x7f800000;
170 : }
171 : else
172 : {
173 : /* -------------------------------------------------------------------- */
174 : /* NaN -- preserve sign and significand bits. */
175 : /* -------------------------------------------------------------------- */
176 :
177 0 : return (iSign << 31) | 0x7f800000 | (iMantissa << 7);
178 : }
179 : }
180 :
181 : /* -------------------------------------------------------------------- */
182 : /* Normalized number. */
183 : /* -------------------------------------------------------------------- */
184 :
185 400 : iExponent = iExponent + (127 - 63);
186 400 : iMantissa = iMantissa << 7;
187 :
188 : /* -------------------------------------------------------------------- */
189 : /* Assemble sign, exponent and mantissa. */
190 : /* -------------------------------------------------------------------- */
191 :
192 400 : return (iSign << 31) | (iExponent << 23) | iMantissa;
193 : }
|