⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbench.c

📁 freetype库的应用demo,里面包含freetype的很多实例
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

 /*
  *  gbench is a small program used to benchmark a new algorithm
  *  performing gamma-corrected alpha-blending.
  *
  *  EXPERIMENTAL: the numbers given here do not correspond to
  *                typical usage patterns yet, and the algorithm
  *                can still be tuned
  *
  */

#ifdef UNIX
#include <sys/time.h>
#endif
#include "gbench.h"

#define  xxCACHE

  static  int             use_gamma = 0;
  static  unsigned char   gamma_ramp[256];
  static  unsigned char   gamma_ramp_inv[256];


#define  ALGO_KEY_COUNT         256
#define  ALGO_GRADE_BITS        5
#define  ALGO_GRADE_COUNT      (1 << ALGO_GRADE_BITS)
#define  ALGO_GRADE_INDEX(x)   ((x) >> (8-ALGO_GRADE_BITS))

  typedef struct CKeyRec_
  {
    int             background;
    int             foreground;
    unsigned char*  grades;

  } CKeyRec, *CKey;

  static CKeyRec        ckeys  [ ALGO_KEY_COUNT ];
  static unsigned char  cgrades[ ALGO_KEY_COUNT * ALGO_GRADE_COUNT * 3 ];

  static  chits   = 0;
  static  cmiss1  = 0;
  static  cmiss2  = 0;


 /* clear the cache
  */
  static void
  cclear( void )
  {
    int  nn;

    for ( nn = 0; nn < ALGO_KEY_COUNT; nn++ )
      ckeys[nn].grades = NULL;
  }

 /* recompute the grade levels of a given key
  */
  static void
  ckey_reset( CKey   key )
  {
    int  back = key->background;
    int  fore = key->foreground;
    unsigned char*  gr = key->grades;
    int  nn;

    int  r1,g1,b1,r2,g2,b2;

    r1 = (unsigned char)( back >> 16 );
    g1 = (unsigned char)( back >> 8 );
    b1 = (unsigned char)( back );

    r2 = (unsigned char)( fore >> 16 );
    g2 = (unsigned char)( fore >> 8 );
    b2 = (unsigned char)( fore );

    gr[0] = r1;
    gr[1] = g1;
    gr[2] = b1;

    gr[3] = r2;
    gr[4] = g2;
    gr[5] = b2;

    gr += 6;

    if ( use_gamma )
    {
      r1 = gamma_ramp_inv[r1];
      g1 = gamma_ramp_inv[g1];
      b1 = gamma_ramp_inv[b1];

      r2 = gamma_ramp_inv[r2];
      g2 = gamma_ramp_inv[g2];
      b2 = gamma_ramp_inv[b2];
    }

    for ( nn = 1; nn < ALGO_GRADE_COUNT-1; nn++ )
    {
      int  r = r1 + ((r2-r1)*nn)/(ALGO_GRADE_COUNT-1);
      int  g = g1 + ((g2-g1)*nn)/(ALGO_GRADE_COUNT-1);
      int  b = b1 + ((b2-b1)*nn)/(ALGO_GRADE_COUNT-1);

      if ( use_gamma )
      {
        r = gamma_ramp[r];
        g = gamma_ramp[g];
        b = gamma_ramp[b];
      }

      gr[0] = (unsigned char)r;
      gr[1] = (unsigned char)g;
      gr[2] = (unsigned char)b;

      gr += 3;
    }
    cmiss2 ++;
  }

 /* lookup the grades of a given (background,foreground) couple
  */
  static const unsigned char*
  clookup( int  background,
           int  foreground )
  {
    int   index, index0;
    CKey  key;

    cmiss1++;

    index0 = ( background + foreground*7 ) % ALGO_KEY_COUNT;
    index  = index0;
    do
    {
      key = ckeys + index;

      if ( key->grades == NULL )
        goto NewNode;

      if ( key->background == background &&
           key->foreground == foreground )
        goto Exit;

      index = (index+1) % ALGO_KEY_COUNT;
    }
    while ( index != index0 );

   /* the cache is full, clear it completely
    */
    cclear();

  NewNode:
    key->background = background;
    key->foreground = foreground;
    key->grades     = cgrades + index0*(3*ALGO_GRADE_COUNT);

    ckey_reset( key );

  Exit:
    return  (const unsigned char*)key->grades;
  }



  void
  ggamma_set( double  gamma )
  {
    int    ii;
    double gamma_inv = 1.0f / gamma;

    cclear();

    for ( ii = 0; ii < 256; ii++ )
      gamma_ramp[ii] = (unsigned char)( pow( (double)ii/255.0f, gamma )*255 );

    for ( ii = 0; ii < 256; ii++ )
      gamma_ramp_inv[ii] = (unsigned char)( pow( (double)ii/255.0f, gamma_inv ) * 255.0f );

    use_gamma = (gamma != 1.0f);
  }



  static void
  gblitter_blitrgb24_gray_direct( GBlitter  blitter,
                                  int       color )
  {
    unsigned char   r = (unsigned char)(color >> 16);
    unsigned char   g = (unsigned char)(color >> 8);
    unsigned char   b = (unsigned char)(color);

    int             h = blitter->height;
    unsigned char*  src_line = blitter->src_line;
    unsigned char*  dst_line = blitter->dst_line;

    if ( use_gamma )
    {
      int  r1 = gamma_ramp_inv[r];
      int  g1 = gamma_ramp_inv[g];
      int  b1 = gamma_ramp_inv[b];

      do
      {
        unsigned char*  src = src_line + (blitter->src_x);
        unsigned char*  dst = dst_line + (blitter->dst_x*3);
        int             w   = blitter->width;

        do
        {
          int  a = src[0];

          if ( a < 2 )
          {
            /* nothing */
          }
          else if ( a >= 254 )
          {
            dst[0] = r;
            dst[1] = g;
            dst[2] = b;
          }
          else
          {
            int  r0 = dst[0];
            int  g0 = dst[1];
            int  b0 = dst[2];

            r0 = gamma_ramp_inv[r0];
            g0 = gamma_ramp_inv[g0];
            b0 = gamma_ramp_inv[b0];

            a = a + (a >> 7);

            r0 += (r1 - r0)*a/256;
            g0 += (g1 - g0)*a/256;
            b0 += (b1 - b0)*a/256;

            r0 = gamma_ramp[r0];
            g0 = gamma_ramp[g0];
            b0 = gamma_ramp[b0];

            dst[0] = (unsigned char)r0;
            dst[1] = (unsigned char)g0;
            dst[2] = (unsigned char)b0;
          }

          src += 1;
          dst += 3;
        }
        while (--w > 0);

        src_line += blitter->src_incr;
        dst_line += blitter->dst_incr;
      }
      while (--h > 0);

      return;
    }

    do
    {
      unsigned char*  src = src_line + (blitter->src_x);
      unsigned char*  dst = dst_line + (blitter->dst_x*3);
      int             w   = blitter->width;

      do
      {
        int  a = src[0];

        if ( a < 2 )
        {
          /* nothing */
        }
        else if ( a >= 254 )
        {
          dst[0] = r;
          dst[1] = g;
          dst[2] = b;
        }
        else
        {
          int  r0 = dst[0];
          int  g0 = dst[1];
          int  b0 = dst[2];

          a = a + (a >> 7);

          r0 += (r - r0)*a/256;
          g0 += (g - g0)*a/256;
          b0 += (b - b0)*a/256;

          dst[0] = (unsigned char)r0;
          dst[1] = (unsigned char)g0;
          dst[2] = (unsigned char)b0;
        }

        src += 1;
        dst += 3;
      }
      while (--w > 0);

      src_line += blitter->src_incr;
      dst_line += blitter->dst_incr;
    }
    while (--h > 0);
  }


  static void
  gblitter_blitrgb24_gray_cache( GBlitter  blitter,
                                 int       color )
  {
    unsigned char   r = (unsigned char)(color >> 16);
    unsigned char   g = (unsigned char)(color >> 8);
    unsigned char   b = (unsigned char)(color);

    int                   back   = -1;
    const unsigned char*  grades = NULL;

    int             h = blitter->height;
    unsigned char*  src_line = blitter->src_line;
    unsigned char*  dst_line = blitter->dst_line;

    do
    {
      unsigned char*  src = src_line + (blitter->src_x);
      unsigned char*  dst = dst_line + (blitter->dst_x*3);
      int             w   = blitter->width;

      do
      {
        int  a = src[0];

        if ( a < 2 )
        {
          /* nothing */
        }
        else if ( a >= 254 )
        {
          dst[0] = r;
          dst[1] = g;
          dst[2] = b;
        }
        else
        {
          int                   back0 = ((int)dst[0] << 16) | ((int)dst[1] << 8) | dst[2];
          const unsigned char*  g;

          if ( back0 != back )
          {
            grades = clookup( back0, color );
            back   = back0;
          }
          else
            chits++;

          g = grades + ALGO_GRADE_INDEX(a)*3;

          dst[0] = g[0];
          dst[1] = g[1];
          dst[2] = g[2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -