extensions: adapt to keep color in premultiplied alpha
authorØyvind Kolås <pippin@gimp.org>
Fri, 24 Aug 2018 23:09:49 +0000 (01:09 +0200)
committerØyvind Kolås <pippin@gimp.org>
Sun, 26 Aug 2018 14:16:03 +0000 (16:16 +0200)
12 files changed:
extensions/cairo.c
extensions/double.c
extensions/fast-float.c
extensions/float.c
extensions/gegl-fixups.c
extensions/gggl-lies.c
extensions/gggl-table-lies.c
extensions/gggl-table.c
extensions/gggl.c
extensions/sse2-float.c
extensions/two-table.c
tools/babl-verify.sh

index 77607c5c540dec0065161500f867f90b2363b2db..059b07d9459817feaa3135e5114d4dd3b9c90b78 100644 (file)
@@ -118,6 +118,49 @@ static void conv_cairo32_rgbA8_premul_le (const Babl *conversion,unsigned char *
     }
 }
 
+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)
 {
@@ -266,7 +309,8 @@ conv_rgbA_gamma_float_cairo32_le (const Babl *conversion,unsigned char *src,
 }
 
 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)
 {
@@ -392,6 +436,9 @@ init (void)
       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);
 
index 87b7e3bd3e5962522eaf75c70a36568c59cc506d..ec45be4aa77f5f186f76b3b01ffded57ff57c87f 100644 (file)
@@ -42,10 +42,13 @@ conv_rgbaD_linear_rgbAD_gamma (const Babl *conversion,unsigned char *src,
    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++;
      }
 }
 
@@ -65,7 +68,7 @@ conv_rgbAD_linear_rgbAD_gamma (const Babl    *conversion,
    while (n--)
      {
        double alpha = fsrc[3];
-       if (alpha < BABL_ALPHA_THRESHOLD)
+       if (alpha == 0.0)
          {
            *fdst++ = 0.0;
            *fdst++ = 0.0;
@@ -73,13 +76,6 @@ conv_rgbAD_linear_rgbAD_gamma (const Babl    *conversion,
            *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;
index 41622046222856ef06256c0e356e79532d561d96..822bc97b23cf0e63b421a6be6408ddf69bfe8a07 100644 (file)
@@ -307,15 +307,10 @@ conv_rgbaF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src,
          *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;
@@ -387,11 +382,6 @@ conv_rgbaF_linear_rgbA8_gamma (const Babl *conversion,unsigned char *src,
          *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;
@@ -461,6 +451,8 @@ conv_rgbaF_linear_rgbA8_gamma_cairo (const Babl *conversion,unsigned char *src,
       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;
@@ -471,11 +463,6 @@ conv_rgbaF_linear_rgbA8_gamma_cairo (const Babl *conversion,unsigned char *src,
         *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;
@@ -505,28 +492,24 @@ conv_rgbAF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src,
       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;
+        }
      }
 }
 
index bce0de7730959fada966ec6777c926ae97bebe60..0d425860cda38090f90f4c4d86ad68d824cfc069 100644 (file)
@@ -43,10 +43,13 @@ conv_rgbaF_linear_rgbAF_nonlinear (const Babl *conversion,unsigned char *src,
    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++;
      }
 }
 
@@ -62,10 +65,13 @@ conv_rgbaF_linear_rgbAF_perceptual (const Babl *conversion,unsigned char *src,
    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++;
      }
 }
 
@@ -86,7 +92,7 @@ conv_rgbAF_linear_rgbAF_nonlinear (const Babl    *conversion,
    while (n--)
      {
        float alpha = fsrc[3];
-       if (alpha < BABL_ALPHA_THRESHOLD)
+       if (alpha == 0)
          {
            *fdst++ = 0.0;
            *fdst++ = 0.0;
@@ -94,13 +100,6 @@ conv_rgbAF_linear_rgbAF_nonlinear (const Babl    *conversion,
            *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;
@@ -126,24 +125,17 @@ conv_rgbAF_linear_rgbAF_perceptual (const Babl    *conversion,
    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;
index d866154429aabfaa86b61166fc45a437e4a018c0..e05126cc90088d9edab28cf848406f66c47c2deb 100644 (file)
@@ -329,7 +329,7 @@ conv_rgbAF_rgb8 (const Babl *conversion,unsigned char *srcc,
   while (n--)
     {
       float alpha = src[3];
-      if (alpha < BABL_ALPHA_THRESHOLD)
+      if (alpha == 0.0f)
         {
           dst[0] = 0;
           dst[1] = 0;
@@ -337,7 +337,7 @@ conv_rgbAF_rgb8 (const Babl *conversion,unsigned char *srcc,
         }
       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)];
@@ -380,6 +380,8 @@ conv_rgbaF_rgbAF (const Babl *conversion,unsigned char *srcc,
   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;
@@ -402,14 +404,18 @@ conv_rgbAF_rgbaF (const Babl *conversion,unsigned char *srcc,
     {
       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;
     }
@@ -428,13 +434,15 @@ conv_rgbAF_lrgba8 (const Babl *conversion,unsigned char *srcc,
   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)];
index 02b3139e25a29fb56a4929401caf16f55aa2ee94..3f33305bf7c6c3d8fd01886f8b064dadde29f5c7 100644 (file)
@@ -151,14 +151,26 @@ conv_D_F (const Babl *conversion,unsigned char *src, unsigned char *dst, long sa
       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;
index 5cca68d06340d1157f8c5b3d59d7f80c587f3c84..02904a60de2b5ecc21e12f75a3554b3228f7c16a 100644 (file)
  *  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:
  *
@@ -108,8 +110,8 @@ table_init (void)
           }
         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));
@@ -313,9 +315,8 @@ conv_rgbafloat_linear_cairo32_le (const Babl *conversion,unsigned char *src_char
   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;
         }
index 039ef2e5e6b507c04a3733fd0bc6e1456006e5c0..a06a649fe07a4501b29d6d4fe61e89bc9b8fbf8e 100644 (file)
  *
  * 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 */
@@ -65,7 +60,7 @@ table_init (void)
 {
   if (table_inited)
     return;
-  
+
   table_8_F_int = (void*)(table_8_F);
 
   table_inited = 1;
@@ -108,8 +103,8 @@ table_init (void)
           }
         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));
@@ -120,7 +115,7 @@ table_init (void)
         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;
index 1b0fed49f550bb4446436ae4fc2f2abebe7969fb..21082603456b158f4c31b40a88796d99b3262aa5 100644 (file)
@@ -175,25 +175,35 @@ conv_16_8 (const Babl *conversion,unsigned char *src, unsigned char *dst, long s
 {
   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;
     }
 }
 
@@ -757,10 +767,13 @@ conv_rgbA8_rgba8 (const Babl *conversion,unsigned char *src, unsigned char *dst,
         }
       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;
index 6e7aaf16033e60282a83ea1edbd49215f1f4a078..b00ecc0701bb5e375ecdb6ad4f57c17256c9fffd 100644 (file)
@@ -51,11 +51,20 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float *
 
       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));
@@ -73,6 +82,7 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float *
           
           *d++ = rgba0;
           *d++ = rgba1;
+         }
         }
       _mm_empty ();
     }
@@ -82,7 +92,9 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float *
   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;
@@ -112,7 +124,7 @@ conv_rgbAF_linear_rgbaF_linear_shuffle (const Babl *conversion,const float *src,
           float alpha0 = ((float *)s)[3];
           pre_rgba0 = *s;
           
-          if (alpha0 <= BABL_ALPHA_THRESHOLD_FLOAT)
+          if (alpha0 == 0.0f)
           {
             /* Zero RGB */
             rgba0 = _mm_setzero_ps();
@@ -131,7 +143,10 @@ conv_rgbAF_linear_rgbaF_linear_shuffle (const Babl *conversion,const float *src,
           /* 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;
         }
@@ -164,7 +179,7 @@ conv_rgbAF_linear_rgbaF_linear_spin (const Babl *conversion,const float *src, fl
 {
   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;
index 3202e69b398df8486d7347f0416ca5d90079fc61..d4f914fe07a76cbbbd273533b03bc5889a9ab974 100644 (file)
@@ -52,16 +52,9 @@ conv_rgbafloat_linear_cairo24_le (const Babl *conversion,unsigned char *src_char
 
   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;
     }
@@ -96,7 +89,7 @@ conv_rgbafloat_linear_rgbu8_gamma (const Babl *conversion,unsigned char *src_cha
 
   while (n--)
     {
-      if (src[3] < BABL_ALPHA_THRESHOLD)
+      if (src[3] < BABL_ALPHA_FLOOR)
         {
           dst[0] = 0;
           dst[1] = 0;
@@ -124,20 +117,10 @@ conv_rgbafloat_linear_rgbau8_gamma (const Babl *conversion,unsigned char *src_ch
 
   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;
     }
index 0342e8e42fca6991fbd62ffde6a2be29480461a8..0dcaa939285514adf76d862b2e7567e1aa8d8e41 100755 (executable)
@@ -24,18 +24,24 @@ export BABL_PATH=$base_path/extensions/.libs
 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"