Re: speeding up GEGL operations in GIMP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On 10:06, Thu 15 May 08, Sven Neumann wrote:
> Changing this in GIMP is not feasible. What needs to be done is to
> implement shortcuts for the conversions that GIMP actually uses.
> Eventually he gimp-8bit extension should provide shortcuts for both
> gamma-corrected and linear 8bit <-> double conversions.

attached is a patch that adds RGBA float->RGB u8 conversion
using code already present in gggl-lies extension based on
lookup table. I can try to move the code to the gimp-8bit
extension, although I don't think there is a point to doing
so, since this would only introduce duplicity and whould
increase memory footprint of BABL. However, for this
conversion to be selected, BABL_ERROR must be set at
least to 0.0005.

> The lookup tables in gegl-fixups are rather large, btw. As pointed out
> in the paper, a much smaller lookup table would be sufficient to cover
> the range from 0.0 to 1.0. I guess that adding a clever range check and
> reducing the size of the lookup tables would yield a performance
> improvement due to better cache coherency.

The lookup tables for float->u8 conversions are rather quite
large and it is indeed possible to add a range check to size
them down. However this range check would have to be
present in the inner loop of a conversion, which would
rather slow things down. Further, it wouldn't IMHO improve cache
coherency much, since the pixels already are in the 0-1 range
most of the time meaning only approx. 2.5% of the lookup
table items are frequently touched.

Regards, 
  Jan
Index: extensions/gggl-lies.c
===================================================================
--- extensions/gggl-lies.c	(revision 311)
+++ extensions/gggl-lies.c	(working copy)
@@ -62,13 +62,17 @@ static float          table_16_F[1 << 16
 static unsigned char  table_F_8[1 << 16];
 static unsigned short table_F_16[1 << 16];
 
-
 static int table_inited = 0;
 
 static void
 table_init (void)
 {
   int i;
+  union
+  {
+    float          f;
+    unsigned short s[2];
+  } u;
 
   if (table_inited)
     return;
@@ -84,64 +88,48 @@ table_init (void)
       table_16_F[i] = (i * 1.0) / 65535.0;
     }
   /* fill tables for conversion from float to integer */
-  {
-    union
+   
+  u.s[0] = 0; 
+  for (i = 0; i < 1 << 16; i++)
     {
-      float          f;
-      unsigned short s[2];
-    } u;
-    u.f = 0.0;
-
-    u.s[0] = 0.0;
-
-    for (i = 0; i < 1 << 16; i++)
-      {
-        unsigned char  c;
-        unsigned short s;
+      unsigned char  c;
+      unsigned short s;
 
-        u.s[1] = i;
+      u.s[1] = i;
 
-        if (u.f <= 0.0)
-          {
-            c = 0;
-            s = 0;
-          }
-        else if (u.f >= 1.0)
-          {
-            c = 255;
-            s = 65535;
-          }
-        else
-          {
-            c = rint (u.f * 255.0);
-            s = rint (u.f * 65535.0);
-          }
+      if (u.f <= 0.0)
+        {
+          c = 0;
+          s = 0;
+        }
+      else if (u.f >= 1.0)
+        {
+          c = 255;
+          s = 65535;
+        }
+      else
+        {
+          c = rint (u.f * 255.0);
+          s = rint (u.f * 65535.0);
+        }
 
         /*fprintf (stderr, "%2.3f=%03i %05i ", f, c, (*hi));
            / if (! ((*hi)%9))
            /         fprintf (stderr, "\n"); */
 
-        table_F_8[u.s[1]]  = c;
-        table_F_16[u.s[1]] = s;
-      }
-  }
-  /* fix 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;
-      for (i = 0; i < 256; i++)
-        {
-          float           f  = table_8_F[i];
-          unsigned short *hi = ((unsigned short *) (void *) &f);
-          unsigned short *lo = ((unsigned short *) (void *) &f);
-          *lo              = 0;
-          table_F_8[(*hi)] = i;
-        }
+      table_F_8[u.s[1]]  = c;
+      table_F_16[u.s[1]] = s;
     }
+  /* fix tables to ensure 1:1 conversions back and forth */
+    for (i = 0; i < 256; i++)
+      {
+        u.f  = table_8_F[i];
+        table_F_8[u.s[1]] = i;
+      }
 }
 
 /* function to find the index in table for a float */
-static unsigned int
+static INLINE unsigned int
 gggl_float_to_index16 (float f)
 {
   union
@@ -904,6 +892,33 @@ conv_rgbaF_rgbA16 (unsigned char *src, u
   return samples;
 }
 
+#ifdef USE_TABLES
+
+static INLINE long
+conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples)
+{
+  long n = samples;
+  register float f;
+  float *fsrc = (float *) src;
+
+  while (n--)
+    {
+      f = (*(float *) fsrc++);
+      *(unsigned char *) dst++ = table_F_8[gggl_float_to_index16 (f)];
+
+      f = (*(float *) fsrc++);
+      *(unsigned char *) dst++ = table_F_8[gggl_float_to_index16 (f)];
+
+      f = (*(float *) fsrc++);
+      *(unsigned char *) dst++ = table_F_8[gggl_float_to_index16 (f)];
+
+      fsrc++;
+    }
+  return samples;
+}
+
+#else
+
 static INLINE long
 conv_rgbaF_rgb8 (unsigned char *src, unsigned char *dst, long samples)
 {
@@ -924,6 +939,8 @@ conv_rgbaF_rgb8 (unsigned char *src, uns
   return samples;
 }
 
+#endif
+
 static INLINE long
 conv_rgbaF_g8 (unsigned char *src, unsigned char *dst, long samples)
 {
@@ -1951,6 +1968,8 @@ init (void)
     babl_component ("A"),
     NULL);
 
+  table_init();
+
 #define o(src, dst) \
   babl_conversion_new (src, dst, "linear", conv_ ## src ## _ ## dst, NULL)
 
_______________________________________________
Gegl-developer mailing list
Gegl-developer@xxxxxxxxxxxxxxxxxxxxxx
https://lists.XCF.Berkeley.EDU/mailman/listinfo/gegl-developer

[Index of Archives]     [Yosemite News]     [Yosemite Photos]     [gtk]     [GIMP Users]     [KDE]     [Gimp's Home]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux