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()
36 * Real-valued type used to represent the range of an image (colors, weights,
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
;
84 uint16_t mant
:MANTISSA_BITS
;
85 int16_t exp
:EXP_BITS
;
92 ale_sreal
operator=(float v
) {
95 } else if (isnan(v
)) {
96 u
.fpr
.exp
= EXP_SPECIAL
;
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
) {
124 u
.fpr
.exp
= EXP_SPECIAL
;
131 * Test the exponent against the smallest expressible
132 * exponent for ale_sreal.
135 if (log2
< EXP_MIN
) {
147 * The exponent is in range, so use it.
152 u
.fpr
.mant
= (uint16_t) floor(v
/ pow(2, log2
) * (1 << (MANTISSA_BITS
- 1)));
158 operator float() const {
159 float result
= 3.14159;
161 if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 1)) {
172 } else if (((uint16_t) u
.fpr
.exp
== EXP_SPECIAL
) && (u
.fpr
.mant
== 0)) {
183 } else if ((uint16_t) u
.fpr
.exp
!= EXP_SPECIAL
) {
189 result
= u
.fpr
.mant
/ ((double) (1 << (MANTISSA_BITS
- 1)))
201 ale_sreal
operator-=(float r
) {
202 *this = (float) *this - (float) r
;
205 ale_sreal
operator/=(float r
) {
206 *this = (float) *this / (float) r
;
209 ale_sreal
operator*=(float r
) {
210 *this = (float) *this * (float) r
;
213 ale_sreal
operator+=(float r
) {
214 *this = (float) *this + (float) r
;
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"
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"
271 const ale_real ale_real_0
= (ale_real
) 0;