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

📄 grblit.c

📁 Ftee type Demo for Linux open source
💻 C
📖 第 1 页 / 共 4 页
字号:
  const byte  gr_saturation_5[8] = { 0, 1, 2, 3, 4, 4, 4, 4 };


  static
  const byte  gr_saturation_17[32] =
  {
     0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
  };


  static
  grSaturation  gr_saturations[ GR_MAX_SATURATIONS ] =
  {
    {  5, gr_saturation_5  },
    { 17, gr_saturation_17 }
  };

  static
  int  gr_num_saturations = 2;

  static
  grSaturation*  gr_last_saturation = gr_saturations;


  extern
  const byte*  grGetSaturation( int  num_grays )
  {
    /* first of all, scan the current saturations table */
    grSaturation*  sat   = gr_saturations;
    grSaturation*  limit = sat + gr_num_saturations;

    if ( num_grays < 2 )
    {
      grError = gr_err_bad_argument;
      return 0;
    }

    for ( ; sat < limit; sat++ )
    {
      if ( sat->count == num_grays )
      {
        gr_last_saturation = sat;
        return sat->table;
      }
    }

    /* not found, simply create a new entry if there is room */
    if (gr_num_saturations < GR_MAX_SATURATIONS)
    {
      int          i;
      const byte*  table;

      table = (const byte*)grAlloc( (3*num_grays-1)*sizeof(byte) );
      if (!table) return 0;

      sat->count = num_grays;
      sat->table = table;

      for ( i = 0; i < num_grays; i++, table++ )
        *(unsigned char*)table = (unsigned char)i;

      for ( i = 2*num_grays-1; i > 0; i--, table++ )
        *(unsigned char*)table = (unsigned char)(num_grays-1);

      gr_num_saturations++;
      gr_last_saturation = sat;
      return sat->table;
    }
    grError = gr_err_saturation_overflow;
    return 0;
  }



  /*******************************************************************/
  /*                                                                 */
  /*                    conversion tables                            */
  /*                                                                 */
  /*******************************************************************/

  typedef struct grConversion_
  {
    int          target_grays;
    int          source_grays;
    const byte*  table;

  } grConversion;



  static
  const byte  gr_gray5_to_gray17[5] = { 0, 4, 8, 12, 16 };


  static
  const byte  gr_gray5_to_gray128[5] = { 0, 32, 64, 96, 127 };


  static
  const unsigned char  gr_gray17_to_gray128[17] =
  {
    0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 127
  };

  static
  grConversion  gr_conversions[ GR_MAX_CONVERSIONS ] =
  {
    {  17,  5, gr_gray5_to_gray17   },
    { 128,  5, gr_gray5_to_gray128  },
    { 128, 17, gr_gray17_to_gray128 }
  };

  static
  int  gr_num_conversions = 3;

  static
  grConversion*  gr_last_conversion = gr_conversions;


  extern
  const byte*  grGetConversion( int  target_grays,
                                int  source_grays )
  {
    grConversion*  conv  = gr_conversions;
    grConversion*  limit = conv + gr_num_conversions;

    if ( target_grays < 2 || source_grays < 2 )
    {
      grError = gr_err_bad_argument;
      return 0;
    }

    /* otherwise, scan table */
    for ( ; conv < limit; conv++ )
    {
      if ( conv->target_grays == target_grays &&
           conv->source_grays == source_grays )
      {
        gr_last_conversion = conv;
        return conv->table;
      }
    }

    /* not found, add a new conversion to the table */
    if (gr_num_conversions < GR_MAX_CONVERSIONS)
    {
      const byte*  table;
      int          n;

      table = (const byte*)grAlloc( source_grays*sizeof(byte) );
      if (!table)
        return 0;

      conv->target_grays = target_grays;
      conv->source_grays = source_grays;
      conv->table        = table;

      for ( n = 0; n < source_grays; n++ )
        ((unsigned char*)table)[n] = (unsigned char)(n*(target_grays-1) /
                                         (source_grays-1));

      gr_num_conversions++;
      gr_last_conversion = conv;
      return table;
    }
    grError = gr_err_conversion_overflow;
    return 0;
  }




/**************************************************************************/
/*                                                                        */
/* <Function> blit_gray_to_gray                                           */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_gray_to_gray( grBlitter*   blit,
                           const byte*  saturation,
                           const byte*  conversion )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;
    unsigned char   max1;
    unsigned char   max2;

    max1  = (unsigned char)(blit->source.grays-1);
    max2  = (unsigned char)(blit->target.grays-1);

    read  = blit->read  + blit->xread;
    write = blit->write + blit->xwrite;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
#ifdef GR_CONFIG_GRAY_SKIP_WHITE
        unsigned char val = *_read;

        if (val)
        {
          if (val == max)
            *_write = max2;
          else
            *_write = saturation[ (int)*_write + conversion[ *_read ] ];
        }
#else
        *_write = saturation[ (int)*_write + conversion[ *_read ] ];
#endif
        _write++;
        _read++;
        x--;
      }

      read  += blit->read_line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }


/**************************************************************************/
/*                                                                        */
/* <Function> blit_gray_to_gray_simple                                    */
/*                                                                        */
/**************************************************************************/

  static
  void  blit_gray_to_gray_simple( grBlitter*   blit,
                                  const byte*  saturation )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;
    unsigned char   max;

    max   = (unsigned char)(blit->source.grays-1);

    read  = blit->read  + blit->xread;
    write = blit->write + blit->xwrite;

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
#ifdef GR_CONFIG_GRAY_SKIP_WHITE
        unsigned char val = *_read;

        if (val)
        {
          if (val == max)
            *_write = val;
          else
            *_write = saturation[ (int)*_write + *_read ];
        }
#else
        *_write = saturation[ (int)*_write + *_read ];
#endif
        _write++;
        _read++;
        x--;
      }

      read  += blit->read_line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }



#define compose_pixel_full( a, b, n0, n1, n2, max )          \
  {                                                          \
    int  d, half = max >> 1;                                 \
                                                             \
                                                             \
    d = (int)b.chroma[0] - a.chroma[0];                      \
    a.chroma[0] += (unsigned char)((n0*d + half)/max);       \
                                                             \
    d = (int)b.chroma[1] - a.chroma[1];                      \
    a.chroma[1] += (unsigned char)((n1*d + half)/max);       \
                                                             \
    d = (int)b.chroma[2] - a.chroma[2];                      \
    a.chroma[2] += (unsigned char)((n2*d + half)/max);       \
  }

#define compose_pixel( a, b, n, max )  \
    compose_pixel_full( a, b, n, n, n, max )


#define extract555( pixel, color )                           \
   color.chroma[0] = (unsigned char)((pixel >> 10) & 0x1F);  \
   color.chroma[1] = (unsigned char)((pixel >>  5) & 0x1F);  \
   color.chroma[2] = (unsigned char)((pixel      ) & 0x1F);


#define extract565( pixel, color )                           \
   color.chroma[0] = (unsigned char)((pixel >> 11) & 0x1F);  \
   color.chroma[1] = (unsigned char)((pixel >>  5) & 0x3F);  \
   color.chroma[2] = (unsigned char)((pixel      ) & 0x1F);


#define inject555( color )                          \
   ( ( (unsigned short)color.chroma[0] << 10 ) |    \
     ( (unsigned short)color.chroma[1] <<  5 ) |    \
       color.chroma[2]                         )


#define inject565( color )                          \
   ( ( (unsigned short)color.chroma[0] << 11 ) |    \
     ( (unsigned short)color.chroma[1] <<  5 ) |    \
       color.chroma[2]                         )


/**************************************************************************/
/*                                                                        */
/* <Function> blit_gray_to_555                                            */
/*                                                                        */
/**************************************************************************/

#ifdef GRAY8
  static
  void  blit_gray8_to_555( grBlitter*  blit,
                           grColor     color )
  {
    int             y;
    int             sr = (color.chroma[0] << 8) & 0x7C00;
    int             sg = (color.chroma[1] << 2) & 0x03E0;
    int             sb = (color.chroma[2]     ) & 0x001F;
    unsigned char*  read;
    unsigned char*  write;
    long            color2;

    read   = blit->read  + blit->xread;
    write  = blit->write + 2*blit->xwrite;

    color2 = color.value;
    extract565( color2, color );

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        unsigned char    val;

        val = *_read;
        if (val)
        {
          unsigned short* pixel = (unsigned short*)_write;

          if (val >= 254 )
          {
            pixel[0] = (short)color2;
          }
          else if ( val >= 2 )
          {
            /* compose gray value */
            int   pix = (int)*pixel;
            int   dr  = pix & 0x7C00;
            int   dg  = pix & 0x03E0;
            int   db  = pix & 0x001F;

            dr  = pix & 0x7C00;
            dr += ((sr-dr)*val) >> 8;
            dr &= 0xF800;
            
            dg  = pix & 0x03E0;
            dg += ((sg-dg)*val) >> 8;
            dg &= 0x7E0;

            db  = pix & 0x001F;
            db += ((sb-db)*val) >> 8;
            db += 0x001F;

            *pixel = (short)( dr | dg | db );
          }
        }
        _write +=2;
        _read  ++;
        x--;
      }

      read  += blit->read_line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
   
  }                           
#endif /* GRAY8 */

  static
  void  blit_gray_to_555( grBlitter*  blit,
                          grColor     color,
                          int         max )
  {
    int             y;
    unsigned char*  read;
    unsigned char*  write;
    long            color2;

    read   = blit->read  + blit->xread;
    write  = blit->write + 2*blit->xwrite;

    /* convert color to R:G:B triplet */
    color2 = color.value;
    extract555( color2, color );

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        unsigned char   val;

        val = *_read;
        if (val)
        {
          unsigned short* pixel = (unsigned short*)_write;

          if (val == max)
          {
            pixel[0] = (short)color2;
          }
          else
          {
            /* compose gray value */
            unsigned short  pix16 = *pixel;
            grColor         pix;

            extract555( pix16, pix );

            compose_pixel( pix, color, val, max );
            *pixel = (unsigned short)(inject555(pix));
          }
        }
        _write += 2;
        _read  ++;
        x--;
      }

      read  += blit->read_line;
      write += blit->write_line;
      y--;
    }
    while (y > 0);
  }


/**************************************************************************/
/*                                                                        */
/* <Function> blit_gray_to_565                                            */
/*                                                                        */
/**************************************************************************/

#ifdef GRAY8
  static
  void  blit_gray8_to_565( grBlitter*  blit,
                           grColor     color )
  {
    int             y;
    int             sr = (color.chroma[0] << 8) & 0xF800;
    int             sg = (color.chroma[1] << 2) & 0x07E0;
    int             sb = (color.chroma[2]     ) & 0x001F;
    unsigned char*  read;
    unsigned char*  write;
    long            color2;

    read   = blit->read  + blit->xread;
    write  = blit->write + 2*blit->xwrite;

    color2 = color.value;
    extract565( color2, color );

    y = blit->height;
    do
    {
      unsigned char*  _read  = read;
      unsigned char*  _write = write;
      int             x      = blit->width;

      while (x > 0)
      {
        unsigned char    val;

        val = *_read;
        if (val)
        {
          unsigned short* pixel = (unsigned short*)_write;

          if (val >= 254 )
          {

⌨️ 快捷键说明

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