Page MenuHomec4science

mrgbe.h
No OneTemporary

File Metadata

Created
Sat, Nov 23, 23:11
/*
=========================================================================
mRGBE (miniRGBE): reduced RGBE encoding of normalised RGB floats plus
associated integer payload data. By default, this encoding consists of:
- three signed 5-bit mantissas for each RGB colour channel,
- a common 5-bit exponent,
- and an associated 12-bit integer datum.
However, this allocation can be modified within a 32-bit envelope if more
precision is required by modifying mRGBE_MANTBITS, mRGBE_EXPBITS and
mRGBE_DATABITS.
The encoded float RGB tuples are assumed to lie in the range [-1, 1],
with values in the interval [-mRGBE_MIN, mRGBE_MIN] clamped to 0, since
these cannot be resolved. The encoded values are therefore normalised
against a given normalisation factor (e.g. absolute maximum) in order to
maximise the useful range.
Roland Schregle (roland.schregle@{hslu.ch, gmail.com})
(c) Lucerne University of Applied Sciences and Arts,
supported by the Swiss National Science Foundation
(SNSF #179067, "Light Fields for Spatio-Temporal Glare Assessment")
=========================================================================
$Id$
*/
#ifndef _mRGBE_H
#define _mRGBE_H
#include <stdint.h>
/* Mantissa / exponent / payload data bits and their encoding ranges.
NOTE: binary shifts can overflow if the number of bits is increased;
in this case shifts must either be promoted to 64 bits (possibly at
the expense of portability), or replaced by much slower pow(2, ..) */
#define mRGBE_MANTBITS 6
#define mRGBE_EXPBITS 5
#define mRGBE_DATABITS 9
/* Make sure the above configuration occupies a 32 bit envelope */
#if (3*mRGBE_MANTBITS + mRGBE_EXPBITS + mRGBE_DATABITS != 32)
#error Invalid mRGBE bit configuration
#endif
/* Rounding amplitude for encoding
NOTE: unit test indicates this actually _increases_ RMSE! */
#define mRGBE_ROUND 0
/* Jitter amplitude for decoding */
#define mRGBE_JITTER 0.5
/* Jitter encoded zeros (this may not always be desirable, depending on
* the application */
/* #define mRGBE_ZEROJITTER */
/* Signed maximum for mantissa */
#define mRGBE_MANTMAX (1L << (mRGBE_MANTBITS - 1))
/* Absolute overflow limit for mantissa (sign flips if exceeded) */
#define mRGBE_MANTOVF ((mRGBE_MANTMAX << 1) - 1)
/* HACK: Factorisation of mRGBE_MIN prevents integer overflow for
mRGBE_EXPBITS <= 6; further factorisation is required for larger
exponent sizes, else this code will trigger warnings or errors! */
#define mRGBE_MIN (1.0 / \
(1L << (1 << (mRGBE_EXPBITS - 1))) / \
(1L << (1 << (mRGBE_EXPBITS - 1))) \
)
#define mRGBE_MAX 1.0
#define mRGBE_RANGE (mRGBE_MAX - mRGBE_MIN)
#define mRGBE_DATAMAX ((1U << mRGBE_DATABITS) - 1)
typedef union {
struct {
/* (mini)RGBE representation consisting of MANTBITS-bit mantissa
(incl. sign bit) per RGB, a common (implictly negative)
EXPBITS-bit exponent, and DATABITS-bit payload data */
unsigned red: mRGBE_MANTBITS, /* Includes sign bit each */
grn: mRGBE_MANTBITS,
blu: mRGBE_MANTBITS,
exp: mRGBE_EXPBITS, /* Implicitly 2^(-exp) */
dat: mRGBE_DATABITS;
};
uint32_t all;
} mRGBE;
/* State for mRGBE encoding to offset and normalise floats in order to
* optimally utilise the encoding range */
typedef struct {
double min [3], max [3], norm [3];
} mRGBERange;
mRGBERange *mRGBEinit (mRGBERange *range,
double rgbMin [3], double rgbMax [3]
);
/* Initialise range state for mRGBEencode()/mRGBEdecode() with
* the specified float input ranges [rgbMin, rgbMax] in _absolute_ values
* per colour channel. This sets the offset and normalisation for the
* encoding. */
mRGBE mRGBEencode (double rgb [3], const mRGBERange *range, unsigned data);
/* Encode signed float RGB tuple to mRGBE along with payload data. The
* supplied range state must be previously initialised with mRGBEinit().
* A warning is issued if rgb lies outside the initialised range. */
unsigned mRGBEdecode (mRGBE mrgbe, const mRGBERange *range, double rgb [3]);
/* Decode mRGBE, returning signed float RGB tuple in array rgb. The
* associated payload data is decoded as return value. The supplied
* range state must be previously initialised with mRGBEinit(). */
#endif

Event Timeline