d2::render::ipc: Revise bounds calculations for improved performance.
[Ale.git] / ale_real.h
blobe51388f032ecf43d3faafcaa44c285c4f9601072
1 // Copyright 2002, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef __ale_real_h__
22 #define __ale_real_h__
24 #include "ale_fixed.h"
26 #define SINGLE 1
27 #define DOUBLE 2
28 #define HALF 3
29 #define FIXED32 4
30 #define FIXED16 5
32 #define ale_real_enable_casting()
33 #define ale_real_disable_casting()
36 * Real-valued type used to represent the range of an image (colors, weights,
37 * etc.).
39 * ale_real is used in computation.
40 * ale_sreal is used for storage.
43 #if ALE_COLORS == SINGLE
45 typedef float ale_real;
46 typedef float ale_sreal;
48 #define ale_real_ip_weight_floor 1e-10
49 #define ale_real_confidence_floor 0.001
51 #define ALE_REAL_PRECISION_STRING "SINGLE"
53 #elif ALE_COLORS == DOUBLE
55 typedef double ale_real;
56 typedef double ale_sreal;
58 #define ale_real_ip_weight_floor 1e-10
59 #define ale_real_confidence_floor 0.000001
61 #define ALE_REAL_PRECISION_STRING "DOUBLE"
63 #elif ALE_COLORS == HALF
66 * What follows is one approach to packing a floating point
67 * number into 16 bits. This implementation is very slow.
70 #define MANTISSA_BITS (9)
71 #define EXP_BITS (15 - MANTISSA_BITS)
72 #define EXP_SPECIAL (1 << (EXP_BITS - 1))
73 #define EXP_MAX (EXP_SPECIAL - 1)
74 #define EXP_MIN (-EXP_MAX)
76 typedef float ale_real;
78 class ale_sreal {
80 union {
81 uint16_t bits;
82 struct {
83 uint16_t sign:1;
84 uint16_t mant:MANTISSA_BITS;
85 int16_t exp :EXP_BITS;
86 } fpr;
87 } u;
88 public:
89 ale_sreal() {
90 u.bits = 0;
92 ale_sreal operator=(float v) {
93 if (v == 0) {
94 u.bits = 0;
95 } else if (isnan(v)) {
96 u.fpr.exp = EXP_SPECIAL;
97 u.fpr.mant = 1;
98 } else {
100 if (v > 0)
101 u.fpr.sign = 0;
102 else if (v < 0) {
103 u.fpr.sign = 1;
104 v = -v;
105 } else
106 assert(0);
109 * Get the exponent.
112 int log2 = (int) floor (log(v) / log(2));
115 * Test the exponent against the largest expressible
116 * exponent for ale_sreal.
119 if (log2 > EXP_MAX) {
121 * Infinity
124 u.fpr.exp = EXP_SPECIAL;
125 u.fpr.mant = 0;
127 return *this;
131 * Test the exponent against the smallest expressible
132 * exponent for ale_sreal.
135 if (log2 < EXP_MIN) {
137 * Zero
140 u.fpr.exp = 0x0;
141 u.fpr.mant = 0;
143 return *this;
147 * The exponent is in range, so use it.
150 u.fpr.exp = log2;
152 u.fpr.mant = (uint16_t) floor(v / pow(2, log2) * (1 << (MANTISSA_BITS - 1)));
155 return *this;
158 operator float() const {
159 float result = 3.14159;
161 if (((uint16_t) u.fpr.exp == EXP_SPECIAL) && (u.fpr.mant == 1)) {
164 * NaN
167 float a = 0;
168 float b = 0;
170 result = a / b;
172 } else if (((uint16_t) u.fpr.exp == EXP_SPECIAL) && (u.fpr.mant == 0)) {
175 * Infinity
178 float a = 1;
179 float b = 0;
181 result = (a / b);
183 } else if ((uint16_t) u.fpr.exp != EXP_SPECIAL) {
186 * Value is finite.
189 result = u.fpr.mant / ((double) (1 << (MANTISSA_BITS - 1)))
190 * pow(2, u.fpr.exp);
192 } else
193 assert(0);
195 if (u.fpr.sign)
196 result = -result;
198 return result;
201 ale_sreal operator-=(float r) {
202 *this = (float) *this - (float) r;
203 return *this;
205 ale_sreal operator/=(float r) {
206 *this = (float) *this / (float) r;
207 return *this;
209 ale_sreal operator*=(float r) {
210 *this = (float) *this * (float) r;
211 return *this;
213 ale_sreal operator+=(float r) {
214 *this = (float) *this + (float) r;
215 return *this;
219 #undef MANTISSA_BITS
220 #undef EXP_BITS
221 #undef EXP_SPECIAL
222 #undef EXP_MAX
223 #undef EXP_MIN
225 #define ALE_REAL_PRECISION_STRING "HALF"
227 #elif ALE_COLORS == FIXED32
229 typedef ale_fixed<ale_fixed_32,16> ale_real;
230 typedef ale_fixed<ale_fixed_32,16> ale_sreal;
232 #undef ale_real_enable_casting
233 #undef ale_real_disable_casting
234 #define ale_real_enable_casting() ale_real::enable_casting()
235 #define ale_real_disable_casting() ale_real::disable_casting()
237 #define ale_real_ip_weight_floor (1 / (ale_real) 100)
238 #define ale_real_confidence_floor (1 / (ale_real) 10)
240 #define ALE_REAL_PRECISION_STRING "FIXED32"
242 #elif ALE_COLORS == FIXED16
244 typedef ale_fixed<ale_fixed_16_calc,14> ale_real;
245 typedef ale_fixed<ale_fixed_16,12> ale_sreal;
247 #undef ale_real_enable_casting
248 #undef ale_real_disable_casting
249 #define ale_real_enable_casting() ale_real::enable_casting()
250 #define ale_real_disable_casting() ale_real::disable_casting()
252 #define ale_real_ip_weight_floor (1 / (ale_real) 100)
253 #define ale_real_confidence_floor (1 / (ale_real) 10)
255 #define ALE_REAL_PRECISION_STRING "FIXED16"
257 #else
259 #warning Unknown precision in ale_real.h: Choosing PRECISION=SINGLE.
261 typedef float ale_real;
262 typedef float ale_sreal;
264 #define ale_real_ip_weight_floor 1e-10
265 #define ale_real_confidence_floor 0.001
267 #define ALE_REAL_PRECISION_STRING "SINGLE"
269 #endif
271 const ale_real ale_real_0 = (ale_real) 0;
273 #undef SINGLE
274 #undef DOUBLE
275 #undef HALF
276 #undef FIXED16
277 #undef FIXED32
279 #endif