return 1;
}
+static void
+ncomponent_convert_to_float (BablFormat *source_fmt,
+ char *source_buf,
+ char *source_float_buf,
+ int n)
+{
+ BablImage *src_img;
+ BablImage *dst_img;
+
+ src_img = (BablImage *) babl_image_new (
+ babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
+ dst_img = (BablImage *) babl_image_new (
+ babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
+
+ dst_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
+ dst_img->pitch[0] = (dst_img->type[0]->bits / 8);
+ dst_img->stride[0] = 0;
+
+ src_img->data[0] = source_buf;
+ src_img->type[0] = source_fmt->type[0];
+ src_img->pitch[0] = source_fmt->type[0]->bits / 8;
+ src_img->stride[0] = 0;
+
+ dst_img->data[0] = source_float_buf;
+
+ babl_conversion_process (
+ assert_conversion_find (src_img->type[0], dst_img->type[0]),
+ (void*)src_img, (void*)dst_img,
+ n * source_fmt->components);
+ babl_free (src_img);
+ babl_free (dst_img);
+}
+
+static void
+ncomponent_convert_from_float (BablFormat *destination_fmt,
+ char *destination_float_buf,
+ char *destination_buf,
+ int n)
+{
+ BablImage *src_img;
+ BablImage *dst_img;
+
+ src_img = (BablImage *) babl_image_new (
+ babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
+ dst_img = (BablImage *) babl_image_new (
+ babl_component_from_id (BABL_GRAY_LINEAR), NULL, 1, 0, NULL);
+
+ src_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
+ src_img->pitch[0] = (src_img->type[0]->bits / 8);
+ src_img->stride[0] = 0;
+
+ dst_img->data[0] = destination_buf;
+ dst_img->type[0] = (BablType *) babl_type_from_id (BABL_FLOAT);
+ dst_img->pitch[0] = destination_fmt->type[0]->bits/8;
+ dst_img->stride[0] = 0;
+
+ dst_img->type[0] = destination_fmt->type[0];
+ src_img->data[0] = destination_float_buf;
+
+ babl_conversion_process (
+ assert_conversion_find (src_img->type[0], dst_img->type[0]),
+ (void*)src_img, (void*)dst_img,
+ n * destination_fmt->components);
+
+ dst_img->data[0] += dst_img->type[0]->bits / 8;
+ babl_free (src_img);
+ babl_free (dst_img);
+}
+
+
static void
process_same_model (const Babl *babl,
const char *source,
if (compatible_components ((void*)babl->fish.source,
(void*)babl->fish.destination))
{
- ncomponent_convert_to_double (
- (BablFormat *) BABL (babl->fish.source),
- (char *) source,
- double_buf,
- n
- );
+ const void *type_float = babl_type_from_id (BABL_FLOAT);
- ncomponent_convert_from_double (
- (BablFormat *) BABL (babl->fish.destination),
- double_buf,
- (char *) destination,
- n
- );
+ if ((babl->fish.source->format.type[0]->bits < 32 ||
+ babl->fish.source->format.type[0] == type_float) &&
+ (babl->fish.destination->format.type[0]->bits < 32 ||
+ babl->fish.destination->format.type[0] == type_float))
+ {
+ ncomponent_convert_to_float (
+ (BablFormat *) BABL (babl->fish.source),
+ (char *) source,
+ double_buf,
+ n);
+ ncomponent_convert_from_float (
+ (BablFormat *) BABL (babl->fish.destination),
+ double_buf,
+ (char *) destination,
+ n);
+ }
+ else
+ {
+ ncomponent_convert_to_double (
+ (BablFormat *) BABL (babl->fish.source),
+ (char *) source,
+ double_buf,
+ n);
+ ncomponent_convert_from_double (
+ (BablFormat *) BABL (babl->fish.destination),
+ double_buf,
+ (char *) destination,
+ n);
+ }
}
else
{
}
-#define INT16_TYPE short
-#define UINT16_TYPE unsigned short
-#define INT32_TYPE long
-#define UINT32_TYPE unsigned long
-
-// Prototypes -----------------------------------------------------------------
-
-static int singles2halfp(void *target, void *source, int numel);
-static int halfp2singles(void *target, void *source, int numel);
-
-//-----------------------------------------------------------------------------
-//
-// Routine: singles2halfp
-//
-// Input: source = Address of 32-bit floating point data to convert
-// numel = Number of values at that address to convert
-//
-// Output: target = Address of 16-bit data to hold output (numel values)
-// return value = 0 if native floating point format is IEEE
-// = 1 if native floating point format is not IEEE
-//
-// Programmer: James Tursa
-//
-//-----------------------------------------------------------------------------
-
-static int singles2halfp(void *target, void *source, int numel)
+static void
+singles2halfp(uint16_t *hp, const uint32_t *xp, int numel)
{
- UINT16_TYPE *hp = (UINT16_TYPE *) target; // Type pun output as an unsigned 16-bit int
- UINT32_TYPE *xp = (UINT32_TYPE *) source; // Type pun input as an unsigned 32-bit int
- UINT16_TYPE hs, he, hm;
- UINT32_TYPE x, xs, xe, xm;
- int hes;
- static int next; // Little Endian adjustment
- static int checkieee = 1; // Flag to check for IEEE754, Endian, and word size
- double one = 1.0; // Used for checking IEEE754 floating point format
- UINT32_TYPE *ip; // Used for checking IEEE754 floating point format
- if( checkieee ) { // 1st call, so check for IEEE754, Endian, and word size
- ip = (UINT32_TYPE *) &one;
- if( *ip ) { // If Big Endian, then no adjustment
- next = 0;
- } else { // If Little Endian, then adjustment will be necessary
- next = 1;
- ip++;
- }
- if( *ip != 0x3FF00000u ) { // Check for exact IEEE 754 bit pattern of 1.0
- return 1; // Floating point bit pattern is not IEEE 754
- if (next)
- return 1; // not used, but silences gcc
- }
- if( sizeof(INT16_TYPE) != 2 || sizeof(INT32_TYPE) != 4 ) {
- return 1; // short is not 16-bits, or long is not 32-bits.
- }
- checkieee = 0; // Everything checks out OK
- }
+ uint16_t hs, he, hm;
+ uint32_t x, xs, xe, xm;
+ int hes;
- if( source == NULL || target == NULL ) { // Nothing to convert (e.g., imag part of pure real)
- return 0;
+
+
+ if( hp== NULL || xp== NULL ) { // Nothing to convert (e.g., imag part of pure real)
+ return;
}
while( numel-- ) {
x = *xp++;
if( (x & 0x7FFFFFFFu) == 0 ) { // Signed zero
- *hp++ = (UINT16_TYPE) (x >> 16); // Return the signed zero
+ *hp++ = (uint16_t) (x >> 16); // Return the signed zero
} else { // Not zero
xs = x & 0x80000000u; // Pick off sign bit
xe = x & 0x7F800000u; // Pick off exponent bits
xm = x & 0x007FFFFFu; // Pick off mantissa bits
if( xe == 0 ) { // Denormal will underflow, return a signed zero
- *hp++ = (UINT16_TYPE) (xs >> 16);
+ *hp++ = (uint16_t) (xs >> 16);
} else if( xe == 0x7F800000u ) { // Inf or NaN (all the exponent bits are set)
if( xm == 0 ) { // If mantissa is zero ...
- *hp++ = (UINT16_TYPE) ((xs >> 16) | 0x7C00u); // Signed Inf
+ *hp++ = (uint16_t) ((xs >> 16) | 0x7C00u); // Signed Inf
} else {
- *hp++ = (UINT16_TYPE) 0xFE00u; // NaN, only 1st mantissa bit set
+ *hp++ = (uint16_t) 0xFE00u; // NaN, only 1st mantissa bit set
}
} else { // Normalized number
- hs = (UINT16_TYPE) (xs >> 16); // Sign bit
+ hs = (uint16_t) (xs >> 16); // Sign bit
hes = ((int)(xe >> 23)) - 127 + 15; // Exponent unbias the single, then bias the halfp
if( hes >= 0x1F ) { // Overflow
- *hp++ = (UINT16_TYPE) ((xs >> 16) | 0x7C00u); // Signed Inf
+ *hp++ = (uint16_t) ((xs >> 16) | 0x7C00u); // Signed Inf
} else if( hes <= 0 ) { // Underflow
if( (14 - hes) > 24 ) { // Mantissa shifted all the way off & no rounding possibility
- hm = (UINT16_TYPE) 0u; // Set mantissa to zero
+ hm = (uint16_t) 0u; // Set mantissa to zero
} else {
xm |= 0x00800000u; // Add the hidden leading bit
- hm = (UINT16_TYPE) (xm >> (14 - hes)); // Mantissa
+ hm = (uint16_t) (xm >> (14 - hes)); // Mantissa
if( (xm >> (13 - hes)) & 0x00000001u ) // Check for rounding
- hm += (UINT16_TYPE) 1u; // Round, might overflow into exp bit, but this is OK
+ hm += (uint16_t) 1u; // Round, might overflow into exp bit, but this is OK
}
*hp++ = (hs | hm); // Combine sign bit and mantissa bits, biased exponent is zero
} else {
- he = (UINT16_TYPE) (hes << 10); // Exponent
- hm = (UINT16_TYPE) (xm >> 13); // Mantissa
+ he = (uint16_t) (hes << 10); // Exponent
+ hm = (uint16_t) (xm >> 13); // Mantissa
if( xm & 0x00001000u ) // Check for rounding
- *hp++ = (hs | he | hm) + (UINT16_TYPE) 1u; // Round, might overflow to inf, this is OK
+ *hp++ = (hs | he | hm) + (uint16_t) 1u; // Round, might overflow to inf, this is OK
else
*hp++ = (hs | he | hm); // No rounding
}
}
}
}
- return 0;
+ return;
}
+
+
+
//-----------------------------------------------------------------------------
//
// Routine: halfp2singles
// numel = Number of values at that address to convert
//
// Output: target = Address of 32-bit floating point data to hold output (numel values)
-// return value = 0 if native floating point format is IEEE
-// = 1 if native floating point format is not IEEE
+//
//
// Programmer: James Tursa
//
//-----------------------------------------------------------------------------
-static int halfp2singles(void *target, void *source, int numel)
+static void
+halfp2singles(uint32_t *xp, const uint16_t *hp, int numel)
{
- UINT16_TYPE *hp = (UINT16_TYPE *) source; // Type pun input as an unsigned 16-bit int
- UINT32_TYPE *xp = (UINT32_TYPE *) target; // Type pun output as an unsigned 32-bit int
- UINT16_TYPE h, hs, he, hm;
- UINT32_TYPE xs, xe, xm;
- INT32_TYPE xes;
- int e;
- static int next; // Little Endian adjustment
- static int checkieee = 1; // Flag to check for IEEE754, Endian, and word size
- double one = 1.0; // Used for checking IEEE754 floating point format
- UINT32_TYPE *ip; // Used for checking IEEE754 floating point format
- if( checkieee ) { // 1st call, so check for IEEE754, Endian, and word size
- ip = (UINT32_TYPE *) &one;
- if( *ip ) { // If Big Endian, then no adjustment
- next = 0;
- } else { // If Little Endian, then adjustment will be necessary
- next = 1;
- ip++;
- }
- if( *ip != 0x3FF00000u ) { // Check for exact IEEE 754 bit pattern of 1.0
- return 1; // Floating point bit pattern is not IEEE 754
- if (next)
- return 1; // not used but silences gcc
- }
- if( sizeof(INT16_TYPE) != 2 || sizeof(INT32_TYPE) != 4 ) {
- return 1; // short is not 16-bits, or long is not 32-bits.
- }
- checkieee = 0; // Everything checks out OK
- }
+ uint16_t h, hs, he, hm;
+ uint32_t xs, xe, xm;
+ int32_t xes;
+ int e;
+
+
- if( source == NULL || target == NULL ) // Nothing to convert (e.g., imag part of pure real)
- return 0;
+ if( xp == NULL || hp == NULL ) // Nothing to convert (e.g., imag part of pure real)
+ return;
while( numel-- ) {
h = *hp++;
if( (h & 0x7FFFu) == 0 ) { // Signed zero
- *xp++ = ((UINT32_TYPE) h) << 16; // Return the signed zero
+ *xp++ = ((uint32_t) h) << 16; // Return the signed zero
} else { // Not zero
hs = h & 0x8000u; // Pick off sign bit
he = h & 0x7C00u; // Pick off exponent bits
e++;
hm <<= 1;
} while( (hm & 0x0400u) == 0 ); // Shift until leading bit overflows into exponent bit
- xs = ((UINT32_TYPE) hs) << 16; // Sign bit
- xes = ((INT32_TYPE) (he >> 10)) - 15 + 127 - e; // Exponent unbias the halfp, then bias the single
- xe = (UINT32_TYPE) (xes << 23); // Exponent
- xm = ((UINT32_TYPE) (hm & 0x03FFu)) << 13; // Mantissa
+ xs = ((uint32_t) hs) << 16; // Sign bit
+ xes = ((int32_t) (he >> 10)) - 15 + 127 - e; // Exponent unbias the halfp, then bias the single
+ xe = (uint32_t) (xes << 23); // Exponent
+ xm = ((uint32_t) (hm & 0x03FFu)) << 13; // Mantissa
*xp++ = (xs | xe | xm); // Combine sign bit, exponent bits, and mantissa bits
} else if( he == 0x7C00u ) { // Inf or NaN (all the exponent bits are set)
if( hm == 0 ) { // If mantissa is zero ...
- *xp++ = (((UINT32_TYPE) hs) << 16) | ((UINT32_TYPE) 0x7F800000u); // Signed Inf
+ *xp++ = (((uint32_t) hs) << 16) | ((uint32_t) 0x7F800000u); // Signed Inf
} else {
- *xp++ = (UINT32_TYPE) 0xFFC00000u; // NaN, only 1st mantissa bit set
+ *xp++ = (uint32_t) 0xFFC00000u; // NaN, only 1st mantissa bit set
}
} else { // Normalized number
- xs = ((UINT32_TYPE) hs) << 16; // Sign bit
- xes = ((INT32_TYPE) (he >> 10)) - 15 + 127; // Exponent unbias the halfp, then bias the single
- xe = (UINT32_TYPE) (xes << 23); // Exponent
- xm = ((UINT32_TYPE) hm) << 13; // Mantissa
+ xs = ((uint32_t) hs) << 16; // Sign bit
+ xes = ((int32_t) (he >> 10)) - 15 + 127; // Exponent unbias the halfp, then bias the single
+ xe = (uint32_t) (xes << 23); // Exponent
+ xm = ((uint32_t) hm) << 13; // Mantissa
*xp++ = (xs | xe | xm); // Combine sign bit, exponent bits, and mantissa bits
}
}
}
- return 0;
+ return;
}
+
+
+
static void
convert_double_half (BablConversion *conversion,
char *src,
{
while (n--)
{
- singles2halfp (dst, src, 1);
+ singles2halfp ((void*)dst, (void*)src, 1);
dst += dst_pitch;
src += src_pitch;
}
{
while (n--)
{
- halfp2singles (dst, src, 1);
+ halfp2singles ((void*)dst, (void*)src, 1);
dst += dst_pitch;
src += src_pitch;
}