1///////////////////////////////////////////////////////////////////////////
2//
3// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
4// Digital Ltd. LLC
5//
6// All rights reserved.
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11// *       Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13// *       Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17// *       Neither the name of Industrial Light & Magic nor the names of
18// its contributors may be used to endorse or promote products derived
19// from this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32//
33///////////////////////////////////////////////////////////////////////////
34
35
36//-----------------------------------------------------------------------------
37//
38//	Routines for converting between pixel data types,
39//	with well-defined behavior for exceptional cases.
40//
41//-----------------------------------------------------------------------------
42
43#include <ImfConvert.h>
44#include <limits.h>
45
46namespace Imf {
47namespace {
48
49inline bool
50isNegative (float f)
51{
52    union {float f; int i;} u;
53    u.f = f;
54    return (u.i & 0x80000000) != 0;
55}
56
57
58inline bool
59isNan (float f)
60{
61    union {float f; int i;} u;
62    u.f = f;
63    return (u.i & 0x7fffffff) > 0x7f800000;
64}
65
66
67inline bool
68isInfinity (float f)
69{
70    union {float f; int i;} u;
71    u.f = f;
72    return (u.i & 0x7fffffff) == 0x7f800000;
73}
74
75
76inline bool
77isFinite (float f)
78{
79    union {float f; int i;} u;
80    u.f = f;
81    return (u.i & 0x7f800000) != 0x7f800000;
82}
83
84} // namespace
85
86
87unsigned int
88halfToUint (half h)
89{
90    if (h.isNegative() || h.isNan())
91	return 0;
92
93    if (h.isInfinity())
94	return UINT_MAX;
95
96    return (unsigned int) h;
97}
98
99
100unsigned int
101floatToUint (float f)
102{
103    if (isNegative (f) || isNan (f))
104	return 0;
105
106    if (isInfinity (f) || f > UINT_MAX)
107	return UINT_MAX;
108
109    return (unsigned int) f;
110}
111
112
113half
114uintToHalf (unsigned int ui)
115{
116    if (ui >  HALF_MAX)
117	return half::posInf();
118
119    return half (ui);
120}
121
122
123half
124floatToHalf (float f)
125{
126    if (isFinite (f))
127    {
128	if (f >  HALF_MAX)
129	    return half::posInf();
130
131	if (f < -HALF_MAX)
132	    return half::negInf();
133    }
134
135    return half (f);
136}
137
138
139} // namespace Imf
140