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"
32 #define ale_real_enable_casting()
33 #define ale_real_disable_casting()
35 #define ale_real_unexceptional_negation(VALUE) -(VALUE)
37 #define ale_real_from_int(INT_VALUE, MAXVAL) (((float) (INT_VALUE)) / ((float) (MAXVAL)))
38 #define ale_real_to_int(REAL_VALUE, MAXVAL) round((float) (REAL_VALUE) * (MAXVAL))
39 #define ale_real_weight_floor 0.0001
42 * Real-valued type used to represent the range of an image (colors, weights,
45 * ale_real is used in computation.
46 * ale_sreal is used for storage.
49 #if ALE_COLORS == SINGLE
51 typedef float ale_real
;
52 typedef float ale_sreal
;
54 #define ale_real_ip_weight_floor 1e-10
55 #define ale_real_confidence_floor 0.001
57 #define ALE_REAL_PRECISION_STRING "SINGLE"
59 #elif ALE_COLORS == DOUBLE
61 typedef double ale_real
;
62 typedef double ale_sreal
;
64 #define ale_real_ip_weight_floor 1e-10
65 #define ale_real_confidence_floor 0.000001
67 #define ALE_REAL_PRECISION_STRING "DOUBLE"
69 #elif ALE_COLORS == HALF
72 * What follows is one approach to packing a floating point
73 * number into 16 bits. This implementation is very slow.
76 #define MANTISSA_BITS (9)
77 #define EXP_BITS (15 - MANTISSA_BITS)
78 #define EXP_SPECIAL (1 << (EXP_BITS - 1))
79 #define EXP_MAX (EXP_SPECIAL - 1)
80 #define EXP_MIN (-EXP_MAX)
82 typedef float ale_real
;
90 uint16_t mant
:MANTISSA_BITS
;
91 int16_t exp
:EXP_BITS
;
98 ale_sreal
operator=(float v
) {
101 } else if (isnan(v
)) {
102 u
.fpr
.exp
= EXP_SPECIAL
;
118 int log2
= (int) floor (log(v
) / log(2));
121 * Test the exponent against the largest expressible
122 * exponent for ale_sreal.
125 if (log2
> EXP_MAX
) {
130 u
.fpr
.exp
= EXP_SPECIAL
;
137 * Test the exponent against the smallest expressible
138 * exponent for ale_sreal.
141 if (log2
< EXP_MIN
) {
153 * The exponent is in range, so use it.
158 u
.fpr
.mant
= (uint16_t) floor(v
/ pow(2, log2
) * (1 << (MANTISSA_BITS
- 1)));
164 operator float() const {
165 float result
= 3.14159;
167 if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 1)) {
178 } else if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 0)) {
189 } else if ((uint16_t) u
.fpr
.exp
!= EXP_SPECIAL
) {
195 result
= u
.fpr
.mant
/ ((double) (1 << (MANTISSA_BITS
- 1)))
207 ale_sreal
operator-=(float r
) {
208 *this = (float) *this - (float) r
;
211 ale_sreal
operator/=(float r
) {
212 *this = (float) *this / (float) r
;
215 ale_sreal
operator*=(float r
) {
216 *this = (float) *this * (float) r
;
219 ale_sreal
operator+=(float r
) {
220 *this = (float) *this + (float) r
;
231 #define ALE_REAL_PRECISION_STRING "HALF"
233 #elif ALE_COLORS == FIXED32
235 typedef ale_fixed
<ale_fixed_32
,16> ale_real
;
236 typedef ale_fixed
<ale_fixed_32
,16> ale_sreal
;
238 #undef ale_real_enable_casting
239 #undef ale_real_disable_casting
240 #define ale_real_enable_casting() ale_real::enable_casting()
241 #define ale_real_disable_casting() ale_real::disable_casting()
243 #undef ale_real_unexceptional_negation
244 #define ale_real_unexceptional_negation(VALUE) (VALUE).unexceptional_negation();
246 #undef ale_real_to_int
247 #undef ale_real_from_int
248 #define ale_real_to_int(REAL_VALUE, MAXVAL) ( (MAXVAL == 255) \
249 ? (int) ale_fixed<ale_fixed_16_calc,8>::fixed_to_bits(REAL_VALUE) \
250 : ( (MAXVAL == 65535) \
251 ? (int) ale_fixed<ale_fixed_16_calc,16>::fixed_to_bits(REAL_VALUE) \
252 : (int) round((float) (REAL_VALUE) * (MAXVAL)) ) )
254 #define ale_real_from_int(INT_VALUE, MAXVAL) ( (MAXVAL == 255) \
255 ? (ale_real) ale_fixed<ale_fixed_16_calc,8>::bits_to_fixed(INT_VALUE) \
256 : ( (MAXVAL == 65535) \
257 ? (ale_real) ale_fixed<ale_fixed_16_calc,16>::bits_to_fixed(INT_VALUE) \
258 : (ale_real) (((float) (INT_VALUE)) / ((float) (MAXVAL))) ) )
260 #define ale_real_ip_weight_floor (1 / (ale_real) 100)
261 #define ale_real_confidence_floor (1 / (ale_real) 10)
263 #define ALE_REAL_PRECISION_STRING "FIXED32"
265 #elif ALE_COLORS == FIXED16
267 typedef ale_fixed
<ale_fixed_16_calc
,14> ale_real
;
268 typedef ale_fixed
<ale_fixed_16
,12> ale_sreal
;
270 #undef ale_real_enable_casting
271 #undef ale_real_disable_casting
272 #define ale_real_enable_casting() ale_real::enable_casting()
273 #define ale_real_disable_casting() ale_real::disable_casting()
275 #undef ale_real_unexceptional_negation
276 #define ale_real_unexceptional_negation(VALUE) (VALUE).unexceptional_negation();
278 #undef ale_real_to_int
279 #undef ale_real_from_int
280 #define ale_real_to_int(REAL_VALUE, MAXVAL) ( (MAXVAL == 255) \
281 ? (int) ale_fixed<ale_fixed_16_calc,8>::fixed_to_bits(REAL_VALUE) \
282 : ( (MAXVAL == 65535) \
283 ? (int) ale_fixed<ale_fixed_16_calc,16>::fixed_to_bits(REAL_VALUE) \
284 : (int) round((float) (REAL_VALUE) * (MAXVAL)) ) )
286 #define ale_real_from_int(INT_VALUE, MAXVAL) ( (MAXVAL == 255) \
287 ? (ale_real) ale_fixed<ale_fixed_16_calc,8>::bits_to_fixed(INT_VALUE) \
288 : ( (MAXVAL == 65535) \
289 ? (ale_real) ale_fixed<ale_fixed_16_calc,16>::bits_to_fixed(INT_VALUE) \
290 : (ale_real) (((float) (INT_VALUE)) / ((float) (MAXVAL))) ) )
292 #define ale_real_ip_weight_floor (1 / (ale_real) 100)
293 #define ale_real_confidence_floor (1 / (ale_real) 10)
295 #define ALE_REAL_PRECISION_STRING "FIXED16"
299 #warning Unknown precision in ale_real.h: Choosing PRECISION=SINGLE.
301 typedef float ale_real
;
302 typedef float ale_sreal
;
304 #define ale_real_ip_weight_floor 1e-10
305 #define ale_real_confidence_floor 0.001
307 #define ALE_REAL_PRECISION_STRING "SINGLE"
311 const ale_real ale_real_0
= (ale_real
) 0;