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

📄 gbench.c

📁 Ftee type Demo for Linux open source
💻 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 + -