/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * C routines for software color conversion. * * By Angelo Mottola, based on x86 asm versions by Isaac Cruz, * Eric Botcazou and Robert J. Ohannessian. * * See readme.txt for copyright information. */ #include "allegro.h" #include "allegro/internal/aintern.h" extern int *_colorconv_indexed_palette; /* for conversion from 8-bit */ extern int *_colorconv_rgb_scale_5x35; /* for conversion from 15/16-bit */ extern unsigned char *_colorconv_rgb_map; /* for conversion from 8/12-bit to 8-bit */ #if (defined ALLEGRO_USE_C || defined ALLEGRO_NO_ASM) #ifdef ALLEGRO_COLOR8 void _colorconv_blit_8_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int dest_data; width = src_rect->width; src_feed = src_rect->pitch - width; dest_feed = dest_rect->pitch - width; src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { src_data = *(unsigned int *)src; dest_data = _colorconv_rgb_map[src_data & 0xff]; dest_data |= (_colorconv_rgb_map[(src_data >> 8) & 0xff] << 8); dest_data |= (_colorconv_rgb_map[(src_data >> 16) & 0xff] << 16); dest_data |= (_colorconv_rgb_map[src_data >> 24] << 24); *(unsigned int *)dest = dest_data; src += 4; dest += 4; } if (width & 0x2) { src_data = *(unsigned short *)src; dest_data = _colorconv_rgb_map[src_data & 0xff]; dest_data |= (_colorconv_rgb_map[src_data >> 8] << 8); *(unsigned short *)dest = (unsigned short)dest_data; src += 2; dest += 2; } if (width & 0x1) { src_data = *(unsigned char *)src; dest_data = _colorconv_rgb_map[src_data]; *(unsigned char *)dest = (unsigned char)dest_data; src++; dest++; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_8_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { _colorconv_blit_8_to_16(src_rect, dest_rect); } void _colorconv_blit_8_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int dest_data; width = src_rect->width; src_feed = src_rect->pitch - width; dest_feed = dest_rect->pitch - (width << 1); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { src_data = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN dest_data = _colorconv_indexed_palette[src_data & 0xff]; dest_data |= _colorconv_indexed_palette[256 + ((src_data >> 8) & 0xff)]; *(unsigned int *)dest = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 16) & 0xff]; dest_data |= _colorconv_indexed_palette[256 + (src_data >> 24)]; *(unsigned int *)(dest + 4) = dest_data; #else dest_data = _colorconv_indexed_palette[256 + (src_data >> 24)]; dest_data |= _colorconv_indexed_palette[((src_data >> 16) & 0xff)]; *(unsigned int *)dest = dest_data; dest_data = _colorconv_indexed_palette[256 + ((src_data >> 8) & 0xff)]; dest_data |= _colorconv_indexed_palette[(src_data & 0xff)]; *(unsigned int *)(dest + 4) = dest_data; #endif src += 4; dest += 8; } if (width & 0x2) { src_data = *(unsigned short *)src; #ifdef ALLEGRO_LITTLE_ENDIAN dest_data = _colorconv_indexed_palette[src_data & 0xff]; dest_data |= _colorconv_indexed_palette[256 + (src_data >> 8)]; *(unsigned int *)dest = dest_data; #else dest_data = _colorconv_indexed_palette[src_data >> 8]; dest_data |= _colorconv_indexed_palette[256 + (src_data & 0xff)]; *(unsigned int *)dest = dest_data; #endif src += 2; dest += 4; } if (width & 0x1) { src_data = *(unsigned char *)src; dest_data = _colorconv_indexed_palette[src_data]; *(unsigned short *)dest = (unsigned short)dest_data; src++; dest += 2; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_8_to_24(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int temp1, temp2, temp3, temp4; width = src_rect->width; src_feed = src_rect->pitch - width; dest_feed = dest_rect->pitch - (width * 3); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { src_data = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN temp1 = _colorconv_indexed_palette[src_data & 0xff]; temp2 = _colorconv_indexed_palette[256 + ((src_data >> 8) & 0xff)]; temp3 = _colorconv_indexed_palette[512 + ((src_data >> 16) & 0xff)]; temp4 = _colorconv_indexed_palette[768 + (src_data >> 24)]; #else temp1 = _colorconv_indexed_palette[768 + (src_data >> 24)]; temp2 = _colorconv_indexed_palette[512 + ((src_data >> 16) & 0xff)]; temp3 = _colorconv_indexed_palette[256 + ((src_data >> 8) & 0xff)]; temp4 = _colorconv_indexed_palette[src_data & 0xff]; #endif *(unsigned int *)dest = temp1 | (temp2 & 0xff000000); *(unsigned int *)(dest + 4) = (temp2 & 0xffff) | (temp3 & 0xffff0000); *(unsigned int *)(dest + 8) = temp4 | (temp3 & 0xff); src += 4; dest += 12; } if (width & 0x2) { src_data = *(unsigned short *)src; #ifdef ALLEGRO_LITTLE_ENDIAN temp1 = _colorconv_indexed_palette[src_data & 0xff]; temp2 = _colorconv_indexed_palette[src_data >> 8]; #else temp1 = _colorconv_indexed_palette[src_data >> 8]; temp2 = _colorconv_indexed_palette[src_data & 0xff]; #endif *(unsigned int *)dest = temp1; *(unsigned short *)(dest + 3) = (unsigned short)(temp2 & 0xffff); *(unsigned char *)(dest + 5) = (unsigned char)(temp2 >> 16); src += 2; dest += 6; } if (width & 0x1) { src_data = *(unsigned char *)src; temp1 = _colorconv_indexed_palette[src_data]; *(unsigned short *)dest = (unsigned short)(temp1 & 0xffff); *(unsigned char *)(dest + 2) = (unsigned char)(temp1 >> 16); src++; dest += 3; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_8_to_32(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int dest_data; width = src_rect->width; src_feed = src_rect->pitch - width; dest_feed = dest_rect->pitch - (width << 2); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { src_data = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN dest_data = _colorconv_indexed_palette[src_data & 0xff]; *(unsigned int *)(dest) = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 8) & 0xff]; *(unsigned int *)(dest + 4) = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 16) & 0xff]; *(unsigned int *)(dest + 8) = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 24) & 0xff]; *(unsigned int *)(dest + 12) = dest_data; #else dest_data = _colorconv_indexed_palette[(src_data >> 24) & 0xff]; *(unsigned int *)(dest) = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 16) & 0xff]; *(unsigned int *)(dest + 4) = dest_data; dest_data = _colorconv_indexed_palette[(src_data >> 8) & 0xff]; *(unsigned int *)(dest + 8) = dest_data; dest_data = _colorconv_indexed_palette[src_data & 0xff]; *(unsigned int *)(dest + 12) = dest_data; #endif src += 4; dest += 16; } if (width & 0x2) { src_data = *(unsigned short *)src; #ifdef ALLEGRO_LITTLE_ENDIAN dest_data = _colorconv_indexed_palette[src_data & 0xff]; *(unsigned int *)(dest) = dest_data; dest_data = _colorconv_indexed_palette[src_data >> 8]; *(unsigned int *)(dest + 4) = dest_data; #else dest_data = _colorconv_indexed_palette[src_data >> 8]; *(unsigned int *)(dest) = dest_data; dest_data = _colorconv_indexed_palette[src_data & 0xff]; *(unsigned int *)(dest + 4) = dest_data; #endif src += 2; dest += 8; } if (width & 0x1) { src_data = *(unsigned char *)src; *(unsigned int *)dest = _colorconv_indexed_palette[src_data]; src++; dest += 4; } src += src_feed; dest += dest_feed; } } #endif #ifdef ALLEGRO_COLOR16 void _colorconv_blit_15_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned short dest_data; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - width; src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { src_data = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x03c0) >> 2) | ((src_data & 0x7800) >> 3); dest_data = _colorconv_rgb_map[temp]; src_data >>= 16; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x03c0) >> 2) | ((src_data & 0x7800) >> 3); dest_data |= ((unsigned short)_colorconv_rgb_map[temp] << 8); #else temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x03c0) >> 2) | ((src_data & 0x7800) >> 3); dest_data = ((unsigned short)_colorconv_rgb_map[temp] << 8); src_data >>= 16; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x03c0) >> 2) | ((src_data & 0x7800) >> 3); dest_data |= (unsigned short)_colorconv_rgb_map[temp]; #endif *(unsigned short *)dest = dest_data; src += 4; dest += 2; } if (width & 0x1) { src_data = *(unsigned short *)src; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x03c0) >> 2) | ((src_data & 0x7800) >> 3); *(unsigned char *)dest = _colorconv_rgb_map[temp]; src += 2; dest++; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_15_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - (width << 1); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { src_data = *(unsigned int *)src; temp = ((src_data & 0x7fe07fe0) << 1) | (src_data & 0x001f001f); *(unsigned int *)dest = (temp | 0x00200020); src += 4; dest += 4; } if (width & 0x1) { src_data = *(unsigned short *)src; temp = ((src_data & 0x7fe0) << 1) | (src_data & 0x001f); *(unsigned short *)dest = (unsigned short)(temp | 0x0020); src += 2; dest += 2; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_15_to_24(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int temp1, temp2, temp3, temp4; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - (width * 3); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { #ifdef ALLEGRO_LITTLE_ENDIAN src_data = *(unsigned int *)src; temp1 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[(src_data >> 8) & 0xff]; temp2 = _colorconv_rgb_scale_5x35[768 + ((src_data >> 16) & 0xff)] + _colorconv_rgb_scale_5x35[512 + (src_data >> 24)]; src_data = *(unsigned int *)(src + 4); temp3 = _colorconv_rgb_scale_5x35[1280 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[1024 + ((src_data >> 8) & 0xff)]; temp4 = _colorconv_rgb_scale_5x35[src_data >> 24] + _colorconv_rgb_scale_5x35[256 + ((src_data >> 16) & 0xff)]; #else src_data = *(unsigned int *)src; temp4 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[(src_data >> 8) & 0xff]; temp3 = _colorconv_rgb_scale_5x35[768 + ((src_data >> 16) & 0xff)] + _colorconv_rgb_scale_5x35[512 + (src_data >> 24)]; src_data = *(unsigned int *)(src + 4); temp2 = _colorconv_rgb_scale_5x35[1280 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[1024 + ((src_data >> 8) & 0xff)]; temp1 = _colorconv_rgb_scale_5x35[src_data >> 24] + _colorconv_rgb_scale_5x35[256 + ((src_data >> 16) & 0xff)]; #endif *(unsigned int *)dest = temp1 | (temp2 & 0xff000000); *(unsigned int *)(dest + 4) = (temp2 & 0xffff) | (temp3 & 0xffff0000); *(unsigned int *)(dest + 8) = (temp3 & 0xff) | (temp4 << 8); src += 8; dest += 12; } if (width & 0x2) { src_data = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN temp1 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[(src_data >> 8) & 0xff]; temp2 = _colorconv_rgb_scale_5x35[256 + ((src_data >> 16) & 0xff)] + _colorconv_rgb_scale_5x35[src_data >> 24]; #else temp2 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[(src_data >> 8) & 0xff]; temp1 = _colorconv_rgb_scale_5x35[256 + ((src_data >> 16) & 0xff)] + _colorconv_rgb_scale_5x35[src_data >> 24]; #endif *(unsigned int *)dest = temp1; *(unsigned short *)(dest + 3) = (unsigned short)(temp2 & 0xffff); *(unsigned char *)(dest + 5) = (unsigned char)(temp2 >> 16); src += 4; dest += 6; } if (width & 0x1) { src_data = *(unsigned short *)src; temp1 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[src_data >> 8]; *(unsigned short *)dest = (unsigned short)(temp1 & 0xffff); *(unsigned char *)(dest + 2) = (unsigned char)(temp1 >> 16); src += 2; dest += 3; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_15_to_32(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int temp1, temp2; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - (width << 2); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { src_data = *(unsigned int *)src; temp1 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[(src_data >> 8) & 0xff]; temp2 = _colorconv_rgb_scale_5x35[256 + ((src_data >> 16) & 0xff)] + _colorconv_rgb_scale_5x35[src_data >> 24]; #ifdef ALLEGRO_LITTLE_ENDIAN *(unsigned int *)dest = temp1; *(unsigned int *)(dest + 4) = temp2; #else *(unsigned int *)dest = temp2; *(unsigned int *)(dest + 4) = temp1; #endif src += 4; dest += 8; } if (width & 0x1) { src_data = *(unsigned short *)src; temp1 = _colorconv_rgb_scale_5x35[256 + (src_data & 0xff)] + _colorconv_rgb_scale_5x35[src_data >> 8]; *(unsigned int *)dest = temp1; src += 2; dest += 4; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_16_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned short dest_data; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - width; src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { #ifdef ALLEGRO_LITTLE_ENDIAN src_data = *(unsigned int *)src; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x0780) >> 3) | ((src_data & 0xf000) >> 4); dest_data = _colorconv_rgb_map[temp]; src_data >>= 16; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x0780) >> 3) | ((src_data & 0xf000) >> 4); dest_data |= ((unsigned short)_colorconv_rgb_map[temp] << 8); *(unsigned short *)dest = dest_data; #else src_data = *(unsigned int *)src; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x0780) >> 3) | ((src_data & 0xf000) >> 4); dest_data = ((unsigned short)_colorconv_rgb_map[temp] << 8); src_data >>= 16; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x0780) >> 3) | ((src_data & 0xf000) >> 4); dest_data |= (unsigned short)_colorconv_rgb_map[temp]; *(unsigned short *)dest = dest_data; #endif src += 4; dest += 2; } if (width & 0x1) { src_data = *(unsigned short *)src; temp = ((src_data & 0x001e) >> 1) | ((src_data & 0x0780) >> 3) | ((src_data & 0xf000) >> 4); *(unsigned char *)dest = _colorconv_rgb_map[temp]; src += 2; dest++; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_16_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int src_data; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width << 1); dest_feed = dest_rect->pitch - (width << 1); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { src_data = *(unsigned int *)src; temp = ((src_data & 0xffc0ffc0) >> 1) | (src_data & 0x001f001f); *(unsigned int *)dest = temp; src += 4; dest += 4; } if (width & 0x1) { src_data = *(unsigned short *)src; temp = ((src_data & 0xffc0) >> 1) | (src_data & 0x001f); *(unsigned short *)dest = (unsigned short)temp; src += 2; dest += 2; } src += src_feed; dest += dest_feed; } } void _colorconv_blit_16_to_24(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { _colorconv_blit_15_to_24(src_rect, dest_rect); } void _colorconv_blit_16_to_32(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { _colorconv_blit_15_to_32(src_rect, dest_rect); } #endif #if (defined ALLEGRO_COLOR24 || defined ALLEGRO_COLOR32) static void colorconv_blit_true_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect, int bpp) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width * bpp); dest_feed = dest_rect->pitch - width; src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width; x; x--) { temp = ((*(unsigned char *)src) >> 4) | ((*(unsigned char *)(src + 1)) & 0xf0) | (((*(unsigned char *)(src + 2)) & 0xf0) << 4); *(unsigned char *)dest = _colorconv_rgb_map[temp]; src += bpp; dest++; } src += src_feed; dest += dest_feed; } } static void colorconv_blit_true_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect, int bpp) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width * bpp); dest_feed = dest_rect->pitch - (width << 1); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { #ifdef ALLEGRO_LITTLE_ENDIAN temp = ((*(unsigned char *)(src + bpp)) >> 3) | (((*(unsigned char *)(src + bpp + 1)) << 2) & 0x03e0) | (((*(unsigned char *)(src + bpp + 2)) << 7) & 0x7c00); temp <<= 16; temp |= ((*(unsigned char *)(src)) >> 3) | (((*(unsigned char *)(src + 1)) << 2) & 0x03e0) | (((*(unsigned char *)(src + 2)) << 7) & 0x7c00); #else temp = ((*(unsigned char *)(src + bpp - 1)) >> 3) | (((*(unsigned char *)(src + bpp - 2)) << 2) & 0x03e0) | (((*(unsigned char *)(src + bpp - 3)) << 7) & 0x7c00); temp <<= 16; temp |= ((*(unsigned char *)(src + bpp + bpp - 1)) >> 3) | (((*(unsigned char *)(src + bpp + bpp - 2)) << 2) & 0x03e0) | (((*(unsigned char *)(src + bpp + bpp - 3)) << 7) & 0x7c00); #endif *(unsigned int *)dest = temp; src += (bpp << 1); dest += 4; } if (width & 0x1) { #ifdef ALLEGRO_LITTLE_ENDIAN temp = ((*(unsigned char *)(src)) >> 3) | (((*(unsigned char *)(src + 1)) << 2) & 0x03e0) | (((*(unsigned char *)(src + 2)) << 7) & 0x7c00); #else temp = ((*(unsigned char *)(src + bpp - 1)) >> 3) | (((*(unsigned char *)(src + bpp - 2)) << 2) & 0x03e0) | (((*(unsigned char *)(src + bpp - 3)) << 7) & 0x7c00); #endif *(unsigned short *)dest = (unsigned short)temp; src += bpp; dest += 2; } src += src_feed; dest += dest_feed; } } static void colorconv_blit_true_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect, int bpp) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width * bpp); dest_feed = dest_rect->pitch - (width << 1); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 1; x; x--) { #ifdef ALLEGRO_LITTLE_ENDIAN temp = ((*(unsigned char *)(src + bpp)) >> 3) | (((*(unsigned char *)(src + bpp + 1)) << 3) & 0x07e0) | (((*(unsigned char *)(src + bpp + 2)) << 8) & 0xf800); temp <<= 16; temp |= ((*(unsigned char *)(src)) >> 3) | (((*(unsigned char *)(src + 1)) << 3) & 0x07e0) | (((*(unsigned char *)(src + 2)) << 8) & 0xf800); #else temp = ((*(unsigned char *)(src + 3)) >> 3) | (((*(unsigned char *)(src + 2)) << 3) & 0x07e0) | (((*(unsigned char *)(src + 1)) << 8) & 0xf800); temp <<= 16; temp |= ((*(unsigned char *)(src + bpp + 3)) >> 3) | (((*(unsigned char *)(src + bpp + 2)) << 3) & 0x07e0) | (((*(unsigned char *)(src + bpp + 1)) << 8) & 0xf800); #endif *(unsigned int *)dest = temp; src += (bpp << 1); dest += 4; } if (width & 0x1) { #ifdef ALLEGRO_LITTLE_ENDIAN temp = ((*(unsigned char *)(src)) >> 3) | (((*(unsigned char *)(src + 1)) << 3) & 0x07e0) | (((*(unsigned char *)(src + 2)) << 8) & 0xf800); #else temp = ((*(unsigned char *)(src + 3)) >> 3) | (((*(unsigned char *)(src + 2)) << 3) & 0x07e0) | (((*(unsigned char *)(src + 1)) << 8) & 0xf800); #endif *(unsigned short *)dest = (unsigned short)temp; src += bpp; dest += 2; } src += src_feed; dest += dest_feed; } } #endif #ifdef ALLEGRO_COLOR24 void _colorconv_blit_24_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_8(src_rect, dest_rect, 3); } void _colorconv_blit_24_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_15(src_rect, dest_rect, 3); } void _colorconv_blit_24_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_16(src_rect, dest_rect, 3); } void _colorconv_blit_24_to_32(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width * 3); dest_feed = dest_rect->pitch - (width << 2); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width; x; x--) { #ifdef ALLEGRO_LITTLE_ENDIAN temp = (*(unsigned char *)src) | ((*(unsigned char *)(src + 1)) << 8) | ((*(unsigned char *)(src + 2)) << 16); #else temp = (*(unsigned char *)(src + 2)) | ((*(unsigned char *)(src + 1)) << 8) | ((*(unsigned char *)(src)) << 16); #endif *(unsigned int *)dest = temp; src += 3; dest += 4; } src += src_feed; dest += dest_feed; } } #endif #ifdef ALLEGRO_COLOR32 void _colorconv_blit_32_to_8(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_8(src_rect, dest_rect, 4); } void _colorconv_blit_32_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_15(src_rect, dest_rect, 4); } void _colorconv_blit_32_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorconv_blit_true_to_16(src_rect, dest_rect, 4); } void _colorconv_blit_32_to_24(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; unsigned int temp; width = src_rect->width; src_feed = src_rect->pitch - (width << 2); dest_feed = dest_rect->pitch - (width * 3); src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width; x; x--) { temp = *(unsigned int *)src; #ifdef ALLEGRO_LITTLE_ENDIAN *(unsigned char *)dest = (unsigned char)(temp & 0xff); *(unsigned char *)(dest + 1) = (unsigned char)(temp >> 8) & 0xff; *(unsigned char *)(dest + 2) = (unsigned char)(temp >> 16) & 0xff; #else *(unsigned char *)(dest + 2) = (unsigned char)(temp & 0xff); *(unsigned char *)(dest + 1) = (unsigned char)(temp >> 8) & 0xff; *(unsigned char *)dest = (unsigned char)(temp >> 16) & 0xff; #endif src += 4; dest += 3; } src += src_feed; dest += dest_feed; } } #endif #ifndef ALLEGRO_NO_COLORCOPY static void colorcopy(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect, int bpp) { unsigned char *src; unsigned char *dest; int width; int src_feed; int dest_feed; int y, x; width = src_rect->width * bpp; src_feed = src_rect->pitch - width; dest_feed = dest_rect->pitch - width; src = src_rect->data; dest = dest_rect->data; for (y = src_rect->height; y; y--) { for (x = width >> 2; x; x--) { *(unsigned int *)dest = *(unsigned int *)src; src += 4; dest += 4; } if (width & 0x2) { *(unsigned short *)dest = *(unsigned short *)src; src += 2; dest += 2; } if (width & 0x1) { *(unsigned char *)dest = *(unsigned char *)src; src++; dest++; } src += src_feed; dest += dest_feed; } } void _colorcopy_blit_15_to_15(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorcopy(src_rect, dest_rect, 2); } void _colorcopy_blit_16_to_16(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorcopy(src_rect, dest_rect, 2); } void _colorcopy_blit_24_to_24(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorcopy(src_rect, dest_rect, 3); } void _colorcopy_blit_32_to_32(struct GRAPHICS_RECT *src_rect, struct GRAPHICS_RECT *dest_rect) { colorcopy(src_rect, dest_rect, 4); } #endif #endif