}
}
+static void conv_cairo32_rgba8_le (const Babl *conversion,unsigned char *src, unsigned char *dst, long samples)
+{
+ long n = samples;
+ while (n--)
+ {
+ unsigned char blue = *src++;
+ unsigned char green = *src++;
+ unsigned char red = *src++;
+ unsigned char alpha = *src++;
+
+ if (alpha == 0)
+ {
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst++ = 0;
+ *dst++ = 0;
+ }
+ else if (alpha == 255)
+ {
+ *dst++ = red;
+ *dst++ = green;
+ *dst++ = blue;
+ *dst++ = alpha;
+ }
+ else
+ {
+ float falpha = alpha / 255.0;
+ float recip_alpha = 1.0 / falpha;
+ // unsigned int aa = ((255 << 16) + alpha) / falpha + 0.5;
+
+
+ *dst++ = ((red/255.0) * recip_alpha) * 255 + 0.5f;
+ *dst++ = ((green/255.0) * recip_alpha) * 255 + 0.5f;
+ *dst++ = ((blue/255.0) * recip_alpha) * 255 + 0.5f;
+
+// *dst++ = (red * aa + 0x8000) >> 16;
+// *dst++ = (green * aa + 0x8000) >> 16;
+// *dst++ = (blue * aa + 0x8000) >> 16;
+ *dst++ = alpha;
+ }
+ }
+}
+
static void conv_cairo32_rgbAF_premul_le (const Babl *conversion,unsigned char *src, unsigned char *dst_char, long samples)
{
}
static void
-conv_rgbafloat_cairo32_le (const Babl *conversion,unsigned char *src,
+conv_rgbafloat_cairo32_le (const Babl *conversion,
+ unsigned char *src,
unsigned char *dst,
long samples)
{
babl_conversion_new (f32, babl_format ("R'aG'aB'aA u8"), "linear",
conv_cairo32_rgbA8_premul_le, NULL);
+ babl_conversion_new (f32, babl_format ("R'G'B'A u8"), "linear",
+ conv_cairo32_rgba8_le, NULL);
+
babl_conversion_new (babl_format ("R'aG'aB'aA u8"), f32, "linear",
conv_rgbA8_premul_cairo32_le, NULL);
while (n--)
{
double alpha = fsrc[3];
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
- *fdst++ = *fsrc++;
+ *fdst++ = alpha;
+ fsrc++;
}
}
while (n--)
{
double alpha = fsrc[3];
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha == 0.0)
{
*fdst++ = 0.0;
*fdst++ = 0.0;
*fdst++ = 0.0;
fsrc+=4;
}
- else if (alpha >= 1.0)
- {
- *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
- *fdst++ = *fsrc++;
- }
else
{
double alpha_recip = 1.0 / alpha;
*fdst++ = linear_to_gamma_2_2_lut (blue);
*fdst++ = alpha;
}
- else if (alpha == 0.0)
- {
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- }
else
{
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
*fdst++ = linear_to_gamma_2_2_lut (red) * alpha;
*fdst++ = linear_to_gamma_2_2_lut (green) * alpha;
*fdst++ = linear_to_gamma_2_2_lut (blue) * alpha;
*cdst++ = val >= 0xff ? 0xff : val <= 0 ? 0 : val;
*cdst++ = 0xff;
}
- else if (alpha <= 0.0)
- {
- *((uint32_t*)(cdst))=0;
- cdst+=4;
- }
else
{
float balpha = alpha * 0xff;
float green = *fsrc++;
float blue = *fsrc++;
float alpha = *fsrc++;
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
if (alpha >= 1.0)
{
int val = linear_to_gamma_2_2_lut (blue) * 0xff + 0.5f;
*cdst++ = val >= 0xff ? 0xff : val <= 0 ? 0 : val;
*cdst++ = 0xff;
}
- else if (alpha <= 0.0)
- {
- *((uint32_t*)(cdst))=0;
- cdst+=4;
- }
else
{
float balpha = alpha * 0xff;
float green = *fsrc++;
float blue = *fsrc++;
float alpha = *fsrc++;
- if (alpha < BABL_ALPHA_THRESHOLD)
- {
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- }
- else if (alpha >= 1.0)
- {
- *fdst++ = linear_to_gamma_2_2_lut (red);
- *fdst++ = linear_to_gamma_2_2_lut (green);
- *fdst++ = linear_to_gamma_2_2_lut (blue);
- *fdst++ = *fsrc++;
- }
- else
- {
- float alpha_recip = 1.0 / alpha;
- *fdst++ = linear_to_gamma_2_2_lut (red * alpha_recip) * alpha;
- *fdst++ = linear_to_gamma_2_2_lut (green * alpha_recip) * alpha;
- *fdst++ = linear_to_gamma_2_2_lut (blue * alpha_recip) * alpha;
- *fdst++ = alpha;
- }
+
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
+ if (alpha >= 1.0)
+ {
+ *fdst++ = linear_to_gamma_2_2_lut (red);
+ *fdst++ = linear_to_gamma_2_2_lut (green);
+ *fdst++ = linear_to_gamma_2_2_lut (blue);
+ *fdst++ = *fsrc++;
+ }
+ else
+ {
+ float alpha_recip = 1.0 / alpha;
+ *fdst++ = linear_to_gamma_2_2_lut (red * alpha_recip) * alpha;
+ *fdst++ = linear_to_gamma_2_2_lut (green * alpha_recip) * alpha;
+ *fdst++ = linear_to_gamma_2_2_lut (blue * alpha_recip) * alpha;
+ *fdst++ = alpha;
+ }
}
}
while (n--)
{
float alpha = fsrc[3];
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
*fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
- *fdst++ = *fsrc++;
+ *fdst++ = alpha;
+ fsrc++;
}
}
while (n--)
{
float alpha = fsrc[3];
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
- *fdst++ = *fsrc++;
+ *fdst++ = alpha;
+ fsrc++;
}
}
while (n--)
{
float alpha = fsrc[3];
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha == 0)
{
*fdst++ = 0.0;
*fdst++ = 0.0;
*fdst++ = 0.0;
fsrc+=4;
}
- else if (alpha >= 1.0)
- {
- *fdst++ = babl_trc_from_linear (trc[0], *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc[1], *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc[2], *fsrc++) * alpha;
- *fdst++ = *fsrc++;
- }
else
{
float alpha_recip = 1.0 / alpha;
while (n--)
{
float alpha = fsrc[3];
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha == 0.0f)
{
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
- *fdst++ = 0.0;
+ *fdst++ = 0.0f;
+ *fdst++ = 0.0f;
+ *fdst++ = 0.0f;
+ *fdst++ = 0.0f;
fsrc+=4;
}
- else if (alpha >= 1.0)
- {
- *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
- *fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++) * alpha;
- *fdst++ = *fsrc++;
- }
else
{
- float alpha_recip = 1.0 / alpha;
+ float alpha_recip = 1.0f / alpha;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
*fdst++ = babl_trc_from_linear (trc_srgb, *fsrc++ * alpha_recip) * alpha;
while (n--)
{
float alpha = src[3];
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha == 0.0f)
{
dst[0] = 0;
dst[1] = 0;
}
else
{
- float alpha_recip = 1.0 / alpha;
+ float alpha_recip = 1.0f / alpha;
dst[0] = table_F_8g[gggl_float_to_index16 (src[0] * alpha_recip)];
dst[1] = table_F_8g[gggl_float_to_index16 (src[1] * alpha_recip)];
dst[2] = table_F_8g[gggl_float_to_index16 (src[2] * alpha_recip)];
while (n--)
{
float alpha = src[3];
+ if (alpha < BABL_ALPHA_FLOOR)
+ alpha = BABL_ALPHA_FLOOR;
dst[0] = src[0] * alpha;
dst[1] = src[1] * alpha;
dst[2] = src[2] * alpha;
{
float alpha = src[3];
float recip;
- if (alpha < BABL_ALPHA_THRESHOLD)
- recip = 0.0;
+ if (alpha == 0.0f)
+ recip = 0.0f;
else
- recip = 1.0/alpha;
+ recip = 1.0f/alpha;
+
dst[0] = src[0] * recip;
dst[1] = src[1] * recip;
dst[2] = src[2] * recip;
- dst[3] = alpha;
+ if (alpha == BABL_ALPHA_FLOOR)
+ dst[3] = 0.0f;
+ else
+ dst[3] = alpha;
src += 4;
dst += 4;
}
while (n--)
{
float alpha = src[3];
- float recip = (1.0/alpha);
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha == 0.0f)
{
dst[0] = dst[1] = dst[2] = dst[3] = 0;
}
else
{
+ float recip = (1.0/alpha);
+ if (alpha == BABL_ALPHA_FLOOR)
+ alpha = 0.0f;
dst[0] = table_F_8[gggl_float_to_index16 (src[0] * recip)];
dst[1] = table_F_8[gggl_float_to_index16 (src[1] * recip)];
dst[2] = table_F_8[gggl_float_to_index16 (src[2] * recip)];
src += 8;
}
}
+
static void
conv_16_8 (const Babl *conversion,unsigned char *src, unsigned char *dst, long samples)
{
long n = samples;
- while (n--)
+ while (n>4)
{
#define div_257(a) ((((a)+128)-(((a)+128)>>8))>>8)
+ ((unsigned char *) dst)[0] = div_257 (((unsigned short *) src)[0]);
+ ((unsigned char *) dst)[1] = div_257 (((unsigned short *) src)[1]);
+ ((unsigned char *) dst)[2] = div_257 (((unsigned short *) src)[2]);
+ ((unsigned char *) dst)[3] = div_257 (((unsigned short *) src)[3]);
+ dst += 4;
+ src += 8;
+ n-=4;
+ }
+
+ while (n--)
+ {
(*(unsigned char *) dst) = div_257 (*(unsigned short *) src);
dst += 1;
src += 2;
* Copyright 2003, 2004, 2005 Øyvind Kolås <pippin@gimp.org>
*/
-#define _POSIX_C_SOURCE 200112L
+//#define _POSIX_C_SOURCE 200112L
#include "config.h"
#include <math.h>
#include <string.h>
#include "babl.h"
+#include "base/util.h"
#include "extensions/util.h"
+
/*
* Implemented according to information read from:
*
}
else
{
- c = lrint (u.f * 255.0);
- s = lrint (u.f * 65535.0);
+ c = u.f * 255 + 0.5f;
+ s = u.f * 65535 + 0.5f;
}
/*fprintf (stderr, "%2.3f=%03i %05i ", f, c, (*hi));
while (n--)
{
float alpha = src[3] * 255;
-#define BABL_ALPHA_THRESHOLD 0.000000152590219
- if (alpha < BABL_ALPHA_THRESHOLD)
+ if (alpha < BABL_ALPHA_FLOOR)
{
*(int *)dst = 0;
}
*
* http://www.cinenet.net/~spitzak/conversion/sketches_0265.pdf
*
- * initially ignoring any diffusion, to keep the implementation
- * smaller, and interchangeable with the non optimized version.
- *
* due to ability to be able to relicence gggl under a different
* licence than GPL, I avoided the temptation to look at the
* source files in the same location, in case I was going to
* need this piece of code for projects where GPL compatibility
* was a must.
*
- * TODO: error diffusion,
- * gamma correction (not really,. gamma correction belongs in seperate ops,.
*/
/* lookup tables used in conversion */
{
if (table_inited)
return;
-
+
table_8_F_int = (void*)(table_8_F);
table_inited = 1;
}
else
{
- c = lrint (u.f * 255.0);
- s = lrint (u.f * 65535.0);
+ c = u.f * 255 + 0.5f;
+ s = u.f * 65535 + 0.5f;
}
/*fprintf (stderr, "%2.3f=%03i %05i ", f, c, (*hi));
table_F_16[u.s[1]] = s;
}
}
- /* fix tables to ensure 1:1 conversions back and forth */
+ /* patch tables to ensure 1:1 conversions back and forth */
if (0)
{ /*FIXME: probably not the right way to do it,.. must sit down and scribble on paper */
int i;
{
long n = samples;
- while (n--)
+ while (n>4)
{
#define div_257(a) ((((a)+128)-(((a)+128)>>8))>>8)
+ ((unsigned char *) dst)[0] = div_257 (((unsigned short *) src)[0]);
+ ((unsigned char *) dst)[1] = div_257 (((unsigned short *) src)[1]);
+ ((unsigned char *) dst)[2] = div_257 (((unsigned short *) src)[2]);
+ ((unsigned char *) dst)[3] = div_257 (((unsigned short *) src)[3]);
+ dst += 4;
+ src += 8;
+ n-=4;
+ }
+
+ while (n--)
+ {
(*(unsigned char *) dst) = div_257 (*(unsigned short *) src);
- dst += 1;
- src += 2;
+ dst += 1;
+ src += 2;
}
}
-static void
+static inline void
conv_8_16 (const Babl *conversion,unsigned char *src, unsigned char *dst, long samples)
{
long n = samples;
-
while (n--)
{
- (*(unsigned short *) dst) = ((*(unsigned char *) src) << 8) | *src;
- dst += 2;
- src += 1;
+ (*(unsigned short *) dst) = *src << 8 | *src;
+ dst += 2;
+ src += 1;
}
}
}
else
{
- unsigned int aa = ((255 << 16) + (src[3] >> 1)) / src[3];
- *dst++ = (src[0] * aa + 0x8000) >> 16;
- *dst++ = (src[1] * aa + 0x8000) >> 16;
- *dst++ = (src[2] * aa + 0x8000) >> 16;
+ float alpha = src[3]/255.0;
+ float ralpha = 1.0/alpha;
+ //unsigned aa = ((255 << 16)) / src[3];
+ unsigned aa = ((1 << 10)) * ralpha;
+ *dst++ = (src[0] * aa + .5) / 1024.0 + 0.5;
+ *dst++ = (src[1] * aa +.5) / 1024.0 + 0.5;
+ *dst++ = (src[2] * aa +.5) / 1024.0 + 0.5;
*dst++ = src[3];
}
src += 4;
for ( ; i < n; i += 2)
{
+ float alpha0 = ((float *)s)[3];
+ float alpha1 = ((float *)s)[7];
+
+ if (alpha0 < BABL_ALPHA_FLOOR)
+ ((float *)s)[3] = BABL_ALPHA_FLOOR;
+ if (alpha1 < BABL_ALPHA_FLOOR)
+ ((float *)s)[7] = BABL_ALPHA_FLOOR;
+ {
__v4sf rbaa0, rbaa1;
__v4sf rgba0 = *s++;
__v4sf rgba1 = *s++;
+
/* Expand alpha */
__v4sf aaaa0 = (__v4sf)_mm_shuffle_epi32((__m128i)rgba0, _MM_SHUFFLE(3, 3, 3, 3));
__v4sf aaaa1 = (__v4sf)_mm_shuffle_epi32((__m128i)rgba1, _MM_SHUFFLE(3, 3, 3, 3));
*d++ = rgba0;
*d++ = rgba1;
+ }
}
_mm_empty ();
}
remainder = samples - i;
while (remainder--)
{
- const float a = src[3];
+ float a = src[3];
+ if (a < BABL_ALPHA_FLOOR)
+ a = BABL_ALPHA_FLOOR;
dst[0] = src[0] * a;
dst[1] = src[1] * a;
dst[2] = src[2] * a;
float alpha0 = ((float *)s)[3];
pre_rgba0 = *s;
- if (alpha0 <= BABL_ALPHA_THRESHOLD_FLOAT)
+ if (alpha0 == 0.0f)
{
/* Zero RGB */
rgba0 = _mm_setzero_ps();
/* Shuffle the original alpha value back in */
rbaa0 = _mm_shuffle_ps(rgba0, pre_rgba0, _MM_SHUFFLE(3, 3, 2, 0));
rgba0 = _mm_shuffle_ps(rgba0, rbaa0, _MM_SHUFFLE(2, 1, 1, 0));
-
+
+ if (alpha0 == BABL_ALPHA_FLOOR)
+ ((float *)d)[3] = 0.0f;
+
s++;
*d++ = rgba0;
}
{
long i = 0;
long remainder;
-
+ // XXX : not ported to color preserving premul
if (((uintptr_t)src % 16) + ((uintptr_t)dst % 16) == 0)
{
const long n = samples;
while (n--)
{
- if (src[3] < BABL_ALPHA_THRESHOLD)
- {
- *(int *)dst = 0;
- }
- else
- {
- dst[0] = conv_float_u8_two_table_map (src[2]);
- dst[1] = conv_float_u8_two_table_map (src[1]);
- dst[2] = conv_float_u8_two_table_map (src[0]);
- }
+ dst[0] = conv_float_u8_two_table_map (src[2]);
+ dst[1] = conv_float_u8_two_table_map (src[1]);
+ dst[2] = conv_float_u8_two_table_map (src[0]);
src += 4;
dst += 4;
}
while (n--)
{
- if (src[3] < BABL_ALPHA_THRESHOLD)
+ if (src[3] < BABL_ALPHA_FLOOR)
{
dst[0] = 0;
dst[1] = 0;
while (n--)
{
- if (src[3] <=0)
- {
- dst[0] = 0;
- dst[1] = 0;
- dst[2] = 0;
- dst[3] = 0;
- }
- else
- {
- dst[0] = conv_float_u8_two_table_map (src[0]);
- dst[1] = conv_float_u8_two_table_map (src[1]);
- dst[2] = conv_float_u8_two_table_map (src[2]);
- dst[3] = src[3] * 0xff + 0.5;
- }
+ dst[0] = conv_float_u8_two_table_map (src[0]);
+ dst[1] = conv_float_u8_two_table_map (src[1]);
+ dst[2] = conv_float_u8_two_table_map (src[2]);
+ dst[3] = src[3] * 0xff + 0.5;
src += 4;
dst += 4;
}
echo ""
echo "[$format]"
$base_path/tools/babl-verify "$format" "cairo-ARGB32" "x"
+$base_path/tools/babl-verify "cairo-ARGB32" "$format" "x"
$base_path/tools/babl-verify "$format" "RaGaBaA float" "x"
$base_path/tools/babl-verify "RaGaBaA float" "$format" "x"
$base_path/tools/babl-verify "$format" "RGBA float" "x"
$base_path/tools/babl-verify "RGBA float" "$format" "x"
$base_path/tools/babl-verify "$format" "R'G'B'A float" "x"
$base_path/tools/babl-verify "R'G'B'A float" "$format" "x"
+$base_path/tools/babl-verify "$format" "R~G~B~A float" "x"
+$base_path/tools/babl-verify "R~G~B~A float" "$format" "x"
$base_path/tools/babl-verify "$format" "cairo-ARGB32"
+$base_path/tools/babl-verify "cairo-ARGB32" "$format"
$base_path/tools/babl-verify "$format" "RaGaBaA float"
$base_path/tools/babl-verify "RaGaBaA float" "$format"
$base_path/tools/babl-verify "$format" "RGBA float"
$base_path/tools/babl-verify "RGBA float" "$format"
$base_path/tools/babl-verify "$format" "R'G'B'A float"
$base_path/tools/babl-verify "R'G'B'A float" "$format"
+$base_path/tools/babl-verify "$format" "R~G~B~A float"
+$base_path/tools/babl-verify "R~G~B~A float" "$format"