freetype-commit
[Top][All Lists]
Advanced

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

[freetype2-demos] master 5bbbfd8: [graph] Fast "powerless" gamma ramps.


From: Alexei Podtelezhnikov
Subject: [freetype2-demos] master 5bbbfd8: [graph] Fast "powerless" gamma ramps.
Date: Sat, 19 May 2018 00:27:17 -0400 (EDT)

branch: master
commit 5bbbfd806fa63c113095b5a48f56d69f8ef59a12
Author: Alexei Podtelezhnikov <address@hidden>
Commit: Alexei Podtelezhnikov <address@hidden>

    [graph] Fast "powerless" gamma ramps.
    
    We calculate the lookup tables for the power function using finite
    differences. This is 10 times faster and accurate enough for gamma
    correction.
    
    * graph/gblender.c (gblender_set_gamma_table): Reimplement using
    finite differences.
    * src/ftstring.c (event_gamma_change): Ditto for the decoration ramp.
---
 ChangeLog        | 12 ++++++++++++
 graph/gblender.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ftstring.c   | 11 ++++++++---
 3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a850fbf..fe64aef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-05-19  Alexei Podtelezhnikov  <address@hidden>
+
+       [graph] Fast "powerless" gamma ramps.
+
+       We calculate the lookup tables for the power function using finite
+       differences. This is 10 times faster and accurate enough for gamma
+       correction.
+
+       * graph/gblender.c (gblender_set_gamma_table): Reimplement using
+       finite differences.
+       * src/ftstring.c (event_gamma_change): Ditto for the decoration ramp.
+
 2018-05-15  Alexei Podtelezhnikov  <address@hidden>
 
        * src/ftgrid.c (bitmap_scale): Mark centers of mono pixels.
diff --git a/graph/gblender.c b/graph/gblender.c
index de0d70d..0bfce5c 100644
--- a/graph/gblender.c
+++ b/graph/gblender.c
@@ -1,5 +1,8 @@
 #include "gblender.h"
 #include <stdlib.h>
+
+#if 0  /* using slow power functions */
+
 #include <math.h>
 
 static void
@@ -54,6 +57,63 @@ gblender_set_gamma_table( double           gamma_value,
   }
 }
 
+#else  /* using fast finite differences */
+
+static void
+gblender_set_gamma_table( double           gamma_value,
+                          unsigned short*  gamma_ramp,
+                          unsigned char*   gamma_ramp_inv )
+{
+  const int  gmax = (256 << GBLENDER_GAMMA_SHIFT)-1;
+  double     p;
+
+  if ( gamma_value <= 0 )  /* special case for sRGB */
+  {
+    int     ii;
+
+    /* voltage to linear; power function using finite differences */
+    for ( p = 1.0, ii = 255; ii > (int)(255.*0.039285714); ii-- )
+    {
+      gamma_ramp[ii] = (unsigned short)( gmax*p + 0.5 );
+      p -= 2.4 * p / ( ii + 255. * 0.055 );
+    }
+    for ( ; ii >= 0; ii-- )
+      gamma_ramp[ii] = (unsigned short)( gmax*ii/(255.*12.92321) + 0.5 );
+
+
+    /* linear to voltage; power function using finite differences */
+    for ( p = 1.0, ii = gmax; ii > (int)(gmax*0.0030399346); ii-- )
+    {
+      gamma_ramp_inv[ii] = (unsigned char)( 255.*p + 0.5 );
+      p -= ( p + 0.055 ) / ( 2.4 * ii );
+    }
+    for ( ; ii >= 0; ii-- )
+      gamma_ramp_inv[ii] = (unsigned char)( 255.*12.92321*ii/gmax + 0.5 );
+  }
+  else
+  {
+    int     ii;
+    double  gamma_inv = 1. / gamma_value;
+
+    /* voltage to linear; power function using finite differences */
+    for ( p = 1.0, ii = 255; ii > 0; ii-- )
+    {
+      gamma_ramp[ii] = (unsigned short)( gmax*p + 0.5 );
+      p -= gamma_value * p / ii;
+    }
+    gamma_ramp[ii] = 0;
+
+    /* linear to voltage; power function using finite differences */
+    for ( p = 1.0, ii = gmax; ii > 0; ii-- )
+    {
+      gamma_ramp_inv[ii] = (unsigned char)( 255.*p + 0.5 );
+      p -= gamma_inv * p / ii;
+    }
+    gamma_ramp[ii] = 0;
+  }
+}
+
+#endif
 
 /* clear the cache
  */
diff --git a/src/ftstring.c b/src/ftstring.c
index eab262a..c275c15 100644
--- a/src/ftstring.c
+++ b/src/ftstring.c
@@ -313,6 +313,7 @@
   event_gamma_change( double  delta )
   {
     int     i;
+    double  p;
 
 
     display->gamma += delta;
@@ -324,9 +325,13 @@
 
     grSetGlyphGamma( display->gamma );
 
-    for ( i = 0; i < 256; i++ )
-      status.gamma_ramp[i] = (FT_Byte)( pow( (double)i / 255., display->gamma )
-                                        * 255. + 0.5 );
+    /* power function calculated using finite differences */
+    for ( p = 1.0, i = 255; i > 0; i-- )
+    {
+      status.gamma_ramp[i] = (FT_Byte)( p * 255. + 0.5 );
+      p -= display->gamma * p / i;
+    }
+    status.gamma_ramp[i] = 0;
   }
 
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]