📄 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 + -