extensions: handle negative premultiplied alpha
authorØyvind Kolås <pippin@gimp.org>
Sun, 26 Aug 2018 21:18:32 +0000 (23:18 +0200)
committerØyvind Kolås <pippin@gimp.org>
Sun, 26 Aug 2018 21:18:32 +0000 (23:18 +0200)
extensions/double.c
extensions/fast-float.c
extensions/float.c
extensions/gegl-fixups.c
extensions/gggl-table-lies.c
extensions/sse2-float.c
extensions/two-table.c

index ec45be4aa77f5f186f76b3b01ffded57ff57c87f..502a46642b36fef2019df9bc2d0958df8db4716e 100644 (file)
@@ -42,8 +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;
+       if (alpha <= BABL_ALPHA_FLOOR)
+       {
+         if (alpha >= 0.0f)
+           alpha = BABL_ALPHA_FLOOR;
+         else 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;
index 822bc97b23cf0e63b421a6be6408ddf69bfe8a07..5540185ba704312cae5c3a0fa7335e68efc00c1b 100644 (file)
@@ -310,7 +310,12 @@ conv_rgbaF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src,
        else
        {
          if (alpha < BABL_ALPHA_FLOOR)
-           alpha = BABL_ALPHA_FLOOR;
+         {
+           if (alpha >= 0.0f)
+             alpha = BABL_ALPHA_FLOOR;
+           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;
@@ -451,8 +456,6 @@ 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;
@@ -493,9 +496,7 @@ conv_rgbAF_linear_rgbAF_gamma (const Babl *conversion,unsigned char *src,
       float blue  = *fsrc++;
       float alpha = *fsrc++;
 
-      if (alpha < BABL_ALPHA_FLOOR)
-       alpha = BABL_ALPHA_FLOOR;
-      if (alpha >= 1.0)
+      if (alpha == 1.0)
         {
           *fdst++ = linear_to_gamma_2_2_lut (red);
           *fdst++ = linear_to_gamma_2_2_lut (green);
index 0d425860cda38090f90f4c4d86ad68d824cfc069..eaa38f51f90d39bc33100e600b2d4128e78d03a4 100644 (file)
@@ -44,7 +44,12 @@ conv_rgbaF_linear_rgbAF_nonlinear (const Babl *conversion,unsigned char *src,
      {
        float alpha = fsrc[3];
        if (alpha < BABL_ALPHA_FLOOR)
-         alpha = BABL_ALPHA_FLOOR;
+       {
+         if (alpha >= 0.0f)
+           alpha = BABL_ALPHA_FLOOR;
+         else 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;
@@ -66,7 +71,12 @@ conv_rgbaF_linear_rgbAF_perceptual (const Babl *conversion,unsigned char *src,
      {
        float alpha = fsrc[3];
        if (alpha < BABL_ALPHA_FLOOR)
-         alpha = BABL_ALPHA_FLOOR;
+       {
+         if (alpha >= 0.0f)
+           alpha = BABL_ALPHA_FLOOR;
+         else 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;
index e05126cc90088d9edab28cf848406f66c47c2deb..70ef2d306db228ce67937b741a91369a23b6beb0 100644 (file)
@@ -331,9 +331,9 @@ conv_rgbAF_rgb8 (const Babl *conversion,unsigned char *srcc,
       float alpha = src[3];
       if (alpha == 0.0f)
         {
-          dst[0] = 0;
-          dst[1] = 0;
-          dst[2] = 0;
+          dst[0] = 0.0f;
+          dst[1] = 0.0f;
+          dst[2] = 0.0f;
         }
       else
         {
@@ -381,7 +381,12 @@ conv_rgbaF_rgbAF (const Babl *conversion,unsigned char *srcc,
     {
       float alpha = src[3];
       if (alpha < BABL_ALPHA_FLOOR)
-        alpha = BABL_ALPHA_FLOOR;
+      {
+        if (alpha >= 0.0f)
+          alpha = BABL_ALPHA_FLOOR;
+        else if (alpha >= -BABL_ALPHA_FLOOR)
+          alpha = -BABL_ALPHA_FLOOR;
+      }
       dst[0] = src[0] * alpha;
       dst[1] = src[1] * alpha;
       dst[2] = src[2] * alpha;
@@ -412,10 +417,9 @@ conv_rgbAF_rgbaF (const Babl *conversion,unsigned char *srcc,
       dst[0] = src[0] * recip;
       dst[1] = src[1] * recip;
       dst[2] = src[2] * recip;
-      if (alpha == BABL_ALPHA_FLOOR)
-        dst[3] = 0.0f;
-      else
-        dst[3] = alpha;
+      if (alpha == BABL_ALPHA_FLOOR || alpha == -BABL_ALPHA_FLOOR)
+        alpha = 0.0f;
+      dst[3] = alpha;
       src   += 4;
       dst   += 4;
     }
@@ -441,7 +445,7 @@ conv_rgbAF_lrgba8 (const Babl *conversion,unsigned char *srcc,
       else
         {
           float recip = (1.0/alpha);
-          if (alpha == BABL_ALPHA_FLOOR)
+          if (alpha == BABL_ALPHA_FLOOR || 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)];
index 02904a60de2b5ecc21e12f75a3554b3228f7c16a..e70a45aff6f589b4d76911e9a743dc161ac82a2a 100644 (file)
@@ -316,7 +316,7 @@ conv_rgbafloat_linear_cairo32_le (const Babl *conversion,unsigned char *src_char
     {
       float alpha = src[3] * 255;
 
-      if (alpha < BABL_ALPHA_FLOOR)
+      if (alpha <= BABL_ALPHA_FLOOR)
         {
           *(int *)dst = 0;
         }
index b00ecc0701bb5e375ecdb6ad4f57c17256c9fffd..02a8c2d74e4f99c25096a6aadac6dcee99c77231 100644 (file)
@@ -55,9 +55,19 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float *
           float alpha1 = ((float *)s)[7];
 
           if (alpha0 < BABL_ALPHA_FLOOR)
-            ((float *)s)[3] = BABL_ALPHA_FLOOR;
+          {
+            if (alpha0 >= 0.0f)
+              ((float *)s)[3] = BABL_ALPHA_FLOOR;
+            else
+              ((float *)s)[3] = -BABL_ALPHA_FLOOR;
+          }
           if (alpha1 < BABL_ALPHA_FLOOR)
-            ((float *)s)[7] = BABL_ALPHA_FLOOR;
+          {
+            if (alpha1 >= 0.0f)
+              ((float *)s)[7] = BABL_ALPHA_FLOOR;
+            else
+              ((float *)s)[7] = -BABL_ALPHA_FLOOR;
+          }
          {
           __v4sf rbaa0, rbaa1;
         
@@ -93,8 +103,13 @@ conv_rgbaF_linear_rgbAF_linear (const Babl *conversion,const float *src, float *
   while (remainder--)
   {
     float a = src[3];
-    if (a < BABL_ALPHA_FLOOR)
-      a = BABL_ALPHA_FLOOR;
+    if (a <= BABL_ALPHA_FLOOR)
+    {
+      if (a >= 0.0f)
+        a = BABL_ALPHA_FLOOR;
+      else if (a >= -BABL_ALPHA_FLOOR)
+        a = -BABL_ALPHA_FLOOR;
+    }
     dst[0] = src[0] * a;
     dst[1] = src[1] * a;
     dst[2] = src[2] * a;
@@ -144,7 +159,7 @@ conv_rgbAF_linear_rgbaF_linear_shuffle (const Babl *conversion,const float *src,
           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)
+          if (alpha0 == BABL_ALPHA_FLOOR || alpha0 == -BABL_ALPHA_FLOOR)
             ((float *)d)[3] = 0.0f;
 
           s++;
index d4f914fe07a76cbbbd273533b03bc5889a9ab974..dae28c80c4fd2ab84892aaa364cb703e6daf7a7e 100644 (file)
@@ -89,7 +89,7 @@ conv_rgbafloat_linear_rgbu8_gamma (const Babl *conversion,unsigned char *src_cha
 
   while (n--)
     {
-      if (src[3] < BABL_ALPHA_FLOOR)
+      if (src[3] <= BABL_ALPHA_FLOOR)
         {
           dst[0] = 0;
           dst[1] = 0;