📄 grblit.c
字号:
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 + -