freetype-commit
[Top][All Lists]
Advanced

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

[freetype2-demos] master 59ef309 06/22: [graph] Reduce color conversions


From: Werner Lemberg
Subject: [freetype2-demos] master 59ef309 06/22: [graph] Reduce color conversions in the blender (part 2).
Date: Fri, 5 Mar 2021 11:18:38 -0500 (EST)

branch: master
commit 59ef309e682f4ffef0bda33b7fe472f739a2a67e
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>

    [graph] Reduce color conversions in the blender (part 2).
    
    * graph/gblender.h (GBlenderBGR): Define color channel storage.
    * graph/gblblit.c (GDST_CHANNELS): Redefined.
    (GDST_READ): Merged into...
    (GDST_PIX): Redefined.
    * graph/gblany.h (*): Major revisions.
---
 ChangeLog        |  10 +++
 graph/gblany.h   | 212 +++++++++++++++----------------------------------------
 graph/gblblit.c  |  47 ++++++------
 graph/gblender.h |   7 ++
 4 files changed, 92 insertions(+), 184 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9f91d32..28899fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2021-01-21  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
+       [graph] Reduce color conversions in the blender (part 2).
+
+       * graph/gblender.h (GBlenderBGR): Define color channel storage.
+       * graph/gblblit.c (GDST_CHANNELS): Redefined.
+       (GDST_READ): Merged into...
+       (GDST_PIX): Redefined.
+       * graph/gblany.h (*): Major revisions.
+
+2021-01-21  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
        * graph/gblender.h (GBLENDER_CHANNEL_VARS): Squash reintroduced bug.
 
 2021-01-17  Alexei Podtelezhnikov  <apodtele@gmail.com>
diff --git a/graph/gblany.h b/graph/gblany.h
index fb28181..917a750 100644
--- a/graph/gblany.h
+++ b/graph/gblany.h
@@ -8,10 +8,6 @@
 #error "GDST_TYPE not defined"
 #endif
 
-#ifndef GDST_READ
-#error "GDST_READ not defined"
-#endif
-
 #ifdef GBLENDER_STORE_BYTES
 #  ifndef GDST_STOREB
 #    error "GDST_STOREB not defined"
@@ -53,9 +49,9 @@ GCONCAT( _gblender_spans_, GDST_TYPE )( int            y,
   grColor         color   = surface->color;
   GBlender        blender = surface->gblender;
 
-  GDST_PIX;
+  GDST_PIX( fore, &color );
 
-  GBLENDER_VARS(blender,pix);
+  GBLENDER_VARS( blender, fore );
 
   unsigned char*  dst_origin = surface->origin - y * surface->bitmap.pitch;
 
@@ -73,9 +69,7 @@ GCONCAT( _gblender_spans_, GDST_TYPE )( int            y,
     else if ( a )
       for ( ; w-- ; dst += GDST_INCR )
       {
-        GBlenderPixel  back;
-
-        GDST_READ(dst,back);
+        GDST_PIX( back, dst);
 
         GBLENDER_LOOKUP( blender, back );
 
@@ -97,9 +91,9 @@ GCONCAT( _gblender_blit_gray8_, GDST_TYPE )( GBlenderBlit  
blit,
 {
   GBlender  blender = blit->blender;
 
-  GDST_PIX;
+  GDST_PIX( fore, &color );
 
-  GBLENDER_VARS(blender,pix);
+  GBLENDER_VARS( blender, fore );
 
   int                   h        = blit->height;
   const unsigned char*  src_line = blit->src_line + blit->src_x;
@@ -125,9 +119,7 @@ GCONCAT( _gblender_blit_gray8_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else
       {
-        GBlenderPixel  back;
-
-        GDST_READ(dst,back);
+        GDST_PIX( back, dst );
 
         GBLENDER_LOOKUP( blender, back );
 
@@ -158,9 +150,9 @@ GCONCAT( _gblender_blit_hrgb_, GDST_TYPE )( GBlenderBlit  
blit,
 {
   GBlender      blender = blit->blender;
 
-  GDST_CHANNELS;
+  GDST_CHANNELS( fore, &color );
 
-  GBLENDER_CHANNEL_VARS(blender,r,g,b);
+  GBLENDER_CHANNEL_VARS( blender, fore.r, fore.g, fore.b );
 
   int                   h        = blit->height;
   const unsigned char*  src_line = blit->src_line + blit->src_x*3;
@@ -191,36 +183,15 @@ GCONCAT( _gblender_blit_hrgb_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else
       {
-        GBlenderPixel  back;
-        int            pix_r, pix_g, pix_b;
-
-        GDST_READ(dst,back);
-
-        {
-          unsigned int  back_r = (back >> 16) & 255;
-
-          GBLENDER_LOOKUP_R( blender, back_r );
-
-          pix_r = _grcells[ar];
-        }
-
-        {
-          unsigned int  back_g = (back >> 8) & 255;
+        GDST_CHANNELS( back, dst );
 
-          GBLENDER_LOOKUP_G( blender, back_g );
+        GBLENDER_LOOKUP_R( blender, back.r );
 
-          pix_g = _ggcells[ag];
-        }
+        GBLENDER_LOOKUP_G( blender, back.g );
 
-        {
-          unsigned int  back_b = (back) & 255;
+        GBLENDER_LOOKUP_B( blender, back.b );
 
-          GBLENDER_LOOKUP_B( blender, back_b );
-
-          pix_b = _gbcells[ab];
-        }
-
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, _grcells[ar], _ggcells[ag], _gbcells[ab] );
       }
 
       src += 3;
@@ -243,9 +214,9 @@ GCONCAT( _gblender_blit_hbgr_, GDST_TYPE )( GBlenderBlit  
blit,
 {
   GBlender      blender = blit->blender;
 
-  GDST_CHANNELS;
+  GDST_CHANNELS( fore, &color );
 
-  GBLENDER_CHANNEL_VARS(blender,r,g,b);
+  GBLENDER_CHANNEL_VARS( blender, fore.r, fore.g, fore.b );
 
   int                   h        = blit->height;
   const unsigned char*  src_line = blit->src_line + blit->src_x*3;
@@ -276,36 +247,15 @@ GCONCAT( _gblender_blit_hbgr_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else
       {
-        GBlenderPixel  back;
-        int            pix_r, pix_g, pix_b;
-
-        GDST_READ(dst,back);
-
-        {
-          unsigned int  back_r = (back >> 16) & 255;
-
-          GBLENDER_LOOKUP_R( blender, back_r );
-
-          pix_r = _grcells[ar];
-        }
-
-        {
-          unsigned int  back_g = (back >> 8) & 255;
-
-          GBLENDER_LOOKUP_G( blender, back_g );
+        GDST_CHANNELS( back, dst );
 
-          pix_g = _ggcells[ag];
-        }
+        GBLENDER_LOOKUP_R( blender, back.r );
 
-        {
-          unsigned int  back_b = (back) & 255;
+        GBLENDER_LOOKUP_G( blender, back.g );
 
-          GBLENDER_LOOKUP_B( blender, back_b );
+        GBLENDER_LOOKUP_B( blender, back.b );
 
-          pix_b = _gbcells[ab];
-        }
-
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, _grcells[ar], _ggcells[ag], _gbcells[ab] );
       }
 
       src += 3;
@@ -328,9 +278,9 @@ GCONCAT( _gblender_blit_vrgb_, GDST_TYPE )( GBlenderBlit  
blit,
 {
   GBlender      blender = blit->blender;
 
-  GDST_CHANNELS;
+  GDST_CHANNELS( fore, &color );
 
-  GBLENDER_CHANNEL_VARS(blender,r,g,b);
+  GBLENDER_CHANNEL_VARS( blender, fore.r, fore.g, fore.b );
 
   int                   h         = blit->height;
   int                   src_pitch = blit->src_pitch;
@@ -362,36 +312,15 @@ GCONCAT( _gblender_blit_vrgb_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else
       {
-        GBlenderPixel  back;
-        int            pix_r, pix_g, pix_b;
-
-        GDST_READ(dst,back);
-
-        {
-          unsigned int  back_r = (back >> 16) & 255;
-
-          GBLENDER_LOOKUP_R( blender, back_r );
-
-          pix_r = _grcells[ar];
-        }
-
-        {
-          unsigned int  back_g = (back >> 8) & 255;
-
-          GBLENDER_LOOKUP_G( blender, back_g );
-
-          pix_g = _ggcells[ag];
-        }
+        GDST_CHANNELS( back, dst );
 
-        {
-          unsigned int  back_b = (back) & 255;
+        GBLENDER_LOOKUP_R( blender, back.r );
 
-          GBLENDER_LOOKUP_B( blender, back_b );
+        GBLENDER_LOOKUP_G( blender, back.g );
 
-          pix_b = _gbcells[ab];
-        }
+        GBLENDER_LOOKUP_B( blender, back.b );
 
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, _grcells[ar], _ggcells[ag], _gbcells[ab] );
       }
 
       src += 1;
@@ -414,9 +343,9 @@ GCONCAT( _gblender_blit_vbgr_, GDST_TYPE )( GBlenderBlit  
blit,
 {
   GBlender      blender = blit->blender;
 
-  GDST_CHANNELS;
+  GDST_CHANNELS( fore, &color );
 
-  GBLENDER_CHANNEL_VARS(blender,r,g,b);
+  GBLENDER_CHANNEL_VARS( blender, fore.r, fore.g, fore.b );
 
   int                   h         = blit->height;
   int                   src_pitch = blit->src_pitch;
@@ -448,36 +377,15 @@ GCONCAT( _gblender_blit_vbgr_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else
       {
-        GBlenderPixel  back;
-        int            pix_r, pix_g, pix_b;
+        GDST_CHANNELS( back, dst );
 
-        GDST_READ(dst,back);
+        GBLENDER_LOOKUP_R( blender, back.r );
 
-        {
-          unsigned int  back_r = (back >> 16) & 255;
+        GBLENDER_LOOKUP_G( blender, back.g );
 
-          GBLENDER_LOOKUP_R( blender, back_r );
+        GBLENDER_LOOKUP_B( blender, back.b );
 
-          pix_r = _grcells[ar];
-        }
-
-        {
-          unsigned int  back_g = (back >> 8) & 255;
-
-          GBLENDER_LOOKUP_G( blender, back_g );
-
-          pix_g = _ggcells[ag];
-        }
-
-        {
-          unsigned int  back_b = (back) & 255;
-
-          GBLENDER_LOOKUP_B( blender, back_b );
-
-          pix_b = _gbcells[ab];
-        }
-
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, _grcells[ar], _ggcells[ag], _gbcells[ab] );
       }
 
       src += 1;
@@ -512,9 +420,7 @@ GCONCAT( _gblender_blit_bgra_, GDST_TYPE )( GBlenderBlit  
blit,
 
     do
     {
-      unsigned int  pix_b = src[0];
-      unsigned int  pix_g = src[1];
-      unsigned int  pix_r = src[2];
+      GBlenderBGR   pix = { src[0], src[1], src[2] };
       unsigned int  a = src[3];
 
 
@@ -524,45 +430,38 @@ GCONCAT( _gblender_blit_bgra_, GDST_TYPE )( GBlenderBlit  
blit,
       }
       else if ( a == 255 )
       {
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, pix.r, pix.g, pix.b );
       }
       else
       {
-        GBlenderPixel  back;
-
-        GDST_READ(dst,back);
+        unsigned int  ba = 255 - a;
 
-        {
-          unsigned int  ba = 255 - a;
-          unsigned int  back_r = (back >> 16) & 255;
-          unsigned int  back_g = (back >> 8) & 255;
-          unsigned int  back_b = (back) & 255;
+        GDST_CHANNELS( back, dst );
 
-#if 1     /* premultiplied blending without gamma correction */
-          pix_r = (back_r * ba / 255 + pix_r);
-          pix_g = (back_g * ba / 255 + pix_g);
-          pix_b = (back_b * ba / 255 + pix_b);
+#if 1   /* premultiplied blending without gamma correction */
+        pix.r = ( back.r * ba / 255 + pix.r );
+        pix.g = ( back.g * ba / 255 + pix.g );
+        pix.b = ( back.b * ba / 255 + pix.b );
 
 #else     /* gamma-corrected blending */
-          const unsigned char*   gamma_ramp_inv = 
blit->blender->gamma_ramp_inv;
-          const unsigned short*  gamma_ramp     = blit->blender->gamma_ramp;
+        const unsigned char*   gamma_ramp_inv = blit->blender->gamma_ramp_inv;
+        const unsigned short*  gamma_ramp     = blit->blender->gamma_ramp;
 
-          back_r = gamma_ramp[back_r];
-          back_g = gamma_ramp[back_g];
-          back_b = gamma_ramp[back_b];
+        back.r = gamma_ramp[back.r];
+        back.g = gamma_ramp[back.g];
+        back.b = gamma_ramp[back.b];
 
-          /* premultiplication undone */
-          pix_r = gamma_ramp[pix_r * 255 / a];
-          pix_g = gamma_ramp[pix_g * 255 / a];
-          pix_b = gamma_ramp[pix_b * 255 / a];
+        /* premultiplication undone */
+        pix.r = gamma_ramp[pix.r * 255 / a];
+        pix.g = gamma_ramp[pix.g * 255 / a];
+        pix.b = gamma_ramp[pix.b * 255 / a];
 
-          pix_r = gamma_ramp_inv[(back_r * ba + pix_r * a + 127) / 255];
-          pix_g = gamma_ramp_inv[(back_g * ba + pix_g * a + 127) / 255];
-          pix_b = gamma_ramp_inv[(back_b * ba + pix_b * a + 127) / 255];
+        pix.r = gamma_ramp_inv[( back.r * ba + pix.r * a + 127 ) / 255];
+        pix.g = gamma_ramp_inv[( back.g * ba + pix.g * a + 127 ) / 255];
+        pix.b = gamma_ramp_inv[( back.b * ba + pix.b * a + 127 ) / 255];
 #endif
-        }
 
-        GDST_STOREC(dst,pix_r,pix_g,pix_b);
+        GDST_STOREC( dst, pix.r, pix.g, pix.b );
       }
 
       src += 4;
@@ -596,7 +495,6 @@ GCONCAT( blit_funcs_, GDST_TYPE )[GBLENDER_SOURCE_MAX] =
 #undef GCONCAT
 #undef GDST_TYPE
 #undef GDST_INCR
-#undef GDST_READ
 #undef GDST_COPY
 #undef GDST_STOREB
 #undef GDST_STOREP
diff --git a/graph/gblblit.c b/graph/gblblit.c
index 781a6b4..7b66fb0 100644
--- a/graph/gblblit.c
+++ b/graph/gblblit.c
@@ -84,11 +84,10 @@
 
 #define  GDST_TYPE                rgb32
 #define  GDST_INCR                4
-#define  GDST_CHANNELS            unsigned int  b = color.value       & 255, \
-                                                g = color.value >>  8 & 255, \
-                                                r = color.value >> 16 & 255
-#define  GDST_PIX                 unsigned int  pix = color.value & 0xFFFFFF
-#define  GDST_READ(d,p)           (p) = *(GBlenderPixel*)(d) & 0xFFFFFF
+#define  GDST_CHANNELS(p,d)       GBlenderBGR  p = { *(unsigned int*)(d)       
& 255, \
+                                                     *(unsigned int*)(d) >>  8 
& 255, \
+                                                     *(unsigned int*)(d) >> 16 
& 255 }
+#define  GDST_PIX(p,d)            unsigned int  p = *(GBlenderPixel*)(d) & 
0xFFFFFF
 #define  GDST_COPY(d)             *(GBlenderPixel*)(d) = color.value
 #define  GDST_STOREP(d,cells,a)   *(GBlenderPixel*)(d) = (cells)[(a)]
 #define  GDST_STOREB(d,cells,a)              \
@@ -106,11 +105,10 @@
 
 #define  GDST_TYPE                 rgb24
 #define  GDST_INCR                 3
-#define  GDST_CHANNELS             unsigned int  b = color.chroma[2], \
-                                                 g = color.chroma[1], \
-                                                 r = color.chroma[0]
-#define  GDST_PIX                  unsigned int  pix = 
GRGB_PACK(color.chroma[0],color.chroma[1],color.chroma[2])
-#define  GDST_READ(d,p)            (p) = GRGB_PACK((d)[0],(d)[1],(d)[2])
+#define  GDST_CHANNELS(p,d)        GBlenderBGR  p = { ((unsigned 
char*)(d))[2], \
+                                                      ((unsigned 
char*)(d))[1], \
+                                                      ((unsigned char*)(d))[0] 
}
+#define  GDST_PIX(p,d)             unsigned int  p = GRGB_PACK(((unsigned 
char*)(d))[0],((unsigned char*)(d))[1],((unsigned char*)(d))[2])
 #define  GDST_COPY(d)              
GDST_STORE3(d,color.chroma[0],color.chroma[1],color.chroma[2])
 #define  GDST_STOREC(d,r,g,b)      GDST_STORE3(d,r,g,b)
 
@@ -137,12 +135,10 @@
 
 #define  GDST_TYPE               rgb565
 #define  GDST_INCR               2
-#define  GDST_CHANNELS           unsigned int  b = 
GRGB565_TO_BLUE(color.value),  \
-                                               g = 
GRGB565_TO_GREEN(color.value), \
-                                               r = GRGB565_TO_RED(color.value)
-#define  GDST_PIX                unsigned int  pix = 
GRGB565_TO_RGB24(color.value)
-#define  GDST_READ(d,p)          p = (GBlenderPixel)*(unsigned short*)(d);  \
-                                 p = GRGB565_TO_RGB24(p)
+#define  GDST_CHANNELS(p,d)      GBlenderBGR  p  = { GRGB565_TO_BLUE 
(*(unsigned short*)(d)), \
+                                                     
GRGB565_TO_GREEN(*(unsigned short*)(d)), \
+                                                     GRGB565_TO_RED  
(*(unsigned short*)(d)) }
+#define  GDST_PIX(p,d)           unsigned int  p = GRGB565_TO_RGB24(*(unsigned 
short*)(d))
 #define  GDST_COPY(d)            *(unsigned short*)(d) = (unsigned 
short)color.value
 
 #define  GDST_STOREB(d,cells,a)                                   \
@@ -167,12 +163,10 @@
  */
 #define  GDST_TYPE               rgb555
 #define  GDST_INCR               2
-#define  GDST_CHANNELS           unsigned int  b = 
GRGB555_TO_BLUE(color.value),  \
-                                               g = 
GRGB555_TO_GREEN(color.value), \
-                                               r = GRGB555_TO_RED(color.value)
-#define  GDST_PIX                unsigned int  pix = 
GRGB555_TO_RGB24(color.value)
-#define  GDST_READ(d,p)          p = (GBlenderPixel)*(unsigned short*)(d);  \
-                                 p = GRGB555_TO_RGB24(p)
+#define  GDST_CHANNELS(p,d)      GBlenderBGR  p  = { GRGB555_TO_BLUE 
(*(unsigned short*)(d)), \
+                                                     
GRGB555_TO_GREEN(*(unsigned short*)(d)), \
+                                                     GRGB555_TO_RED  
(*(unsigned short*)(d)) }
+#define  GDST_PIX(p,d)           unsigned int  p = GRGB555_TO_RGB24(*(unsigned 
short*)(d))
 #define  GDST_COPY(d)            *(unsigned short*)(d) = (unsigned 
short)color.value
 
 #define  GDST_STOREB(d,cells,a)                                   \
@@ -197,11 +191,10 @@
  */
 #define  GDST_TYPE               gray8
 #define  GDST_INCR               1
-#define  GDST_CHANNELS           unsigned int  b = color.value, \
-                                               g = color.value, \
-                                               r = color.value
-#define  GDST_PIX                unsigned int  pix = 
GGRAY8_TO_RGB24(color.value)
-#define  GDST_READ(d,p)          (p) = GGRAY8_TO_RGB24((d)[0])
+#define  GDST_CHANNELS(p,d)      GBlenderBGR  p = { *(unsigned char*)(d), \
+                                                    *(unsigned char*)(d), \
+                                                    *(unsigned char*)(d) }
+#define  GDST_PIX(p,d)           unsigned int  p = GGRAY8_TO_RGB24(*(unsigned 
char*)(d))
 #define  GDST_COPY(d)            *(d) = (unsigned char)color.value
 
 #define  GDST_STOREB(d,cells,a)                 \
diff --git a/graph/gblender.h b/graph/gblender.h
index 366ca69..67ea230 100644
--- a/graph/gblender.h
+++ b/graph/gblender.h
@@ -48,6 +48,13 @@
 
   typedef struct
   {
+    unsigned int  b, g, r;
+
+  } GBlenderBGR;
+
+
+  typedef struct
+  {
     GBlenderPixel  background;
     GBlenderPixel  foreground;
     GBlenderCell*  cells;



reply via email to

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