void _al_convert_bitmap_data( void *src, int src_format, int src_pitch, void *dst, int dst_format, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { ASSERT(src); ASSERT(dst); ASSERT(_al_pixel_format_is_real(dst_format)); /* Use memcpy if no conversion is needed. */ if (src_format == dst_format) { int y; int size = al_get_pixel_size(src_format); char *src_ptr = ((char *)src) + sy * src_pitch + sx * size; char *dst_ptr = ((char *)dst) + dy * dst_pitch + dx * size; width *= size; for (y = 0; y < height; y++) { memcpy(dst_ptr, src_ptr, width); src_ptr += src_pitch; dst_ptr += dst_pitch; } return; } (_al_convert_funcs[src_format][dst_format])(src, src_pitch, dst, dst_pitch, sx, sy, dx, dy, width, height); }
static void _al_draw_bitmap_region_memory_fast(ALLEGRO_BITMAP *bitmap, int sx, int sy, int sw, int sh, int dx, int dy, int flags) { ALLEGRO_LOCKED_REGION *src_region; ALLEGRO_LOCKED_REGION *dst_region; ALLEGRO_BITMAP *dest = al_get_target_bitmap(); int dw = sw, dh = sh; ASSERT(_al_pixel_format_is_real(bitmap->format)); ASSERT(_al_pixel_format_is_real(dest->format)); ASSERT(bitmap->parent == NULL); /* Currently the only flags are for flipping, which is handled as negative * scaling. */ ASSERT(flags == 0); (void)flags; CLIPPER(bitmap, sx, sy, sw, sh, dest, dx, dy, dw, dh, 1, 1, flags) if (!(src_region = al_lock_bitmap_region(bitmap, sx, sy, sw, sh, bitmap->format, ALLEGRO_LOCK_READONLY))) { return; } if (!(dst_region = al_lock_bitmap_region(dest, dx, dy, sw, sh, dest->format, ALLEGRO_LOCK_WRITEONLY))) { al_unlock_bitmap(bitmap); return; } /* will detect if no conversion is needed */ _al_convert_bitmap_data( src_region->data, bitmap->format, src_region->pitch, dst_region->data, dest->format, dst_region->pitch, 0, 0, 0, 0, sw, sh); al_unlock_bitmap(bitmap); al_unlock_bitmap(dest); }
void _al_copy_bitmap_data( const void *src, int src_pitch, void *dst, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height, int format) { int block_width = al_get_pixel_block_width(format); int block_height = al_get_pixel_block_height(format); int block_size = al_get_pixel_block_size(format); const char *src_ptr = src; char *dst_ptr = dst; int y; ASSERT(src); ASSERT(dst); ASSERT(_al_pixel_format_is_real(format)); ASSERT(width % block_width == 0); ASSERT(height % block_height == 0); ASSERT(sx % block_width == 0); ASSERT(sy % block_height == 0); ASSERT(dx % block_width == 0); ASSERT(dy % block_height == 0); sx /= block_width; sy /= block_height; dx /= block_width; dy /= block_height; width /= block_width; height /= block_height; src_ptr += sy * src_pitch + sx * block_size; dst_ptr += dy * dst_pitch + dx * block_size; for (y = 0; y < height; y++) { memcpy(dst_ptr, src_ptr, width * block_size); src_ptr += src_pitch; dst_ptr += dst_pitch; } }
/* We use al_get_display_format() as a hint for the preferred RGB ordering when * nothing else is specified. */ static bool try_display_format(ALLEGRO_DISPLAY *display, int *format) { int best_format; int bytes; if (!display) { return false; } best_format = al_get_display_format(display); if (!_al_pixel_format_is_real(best_format)) return false; bytes = al_get_pixel_size(*format); if (bytes && bytes != al_get_pixel_size(best_format)) return false; if (_al_pixel_format_has_alpha(*format) && !_al_pixel_format_has_alpha(best_format)) { switch (best_format) { case ALLEGRO_PIXEL_FORMAT_RGBX_8888: *format = ALLEGRO_PIXEL_FORMAT_RGBA_8888; return true; case ALLEGRO_PIXEL_FORMAT_XRGB_8888: *format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; return true; case ALLEGRO_PIXEL_FORMAT_XBGR_8888: *format = ALLEGRO_PIXEL_FORMAT_ABGR_8888; return true; default: return false; } } *format = best_format; return true; }
void _al_convert_bitmap_data( const void *src, int src_format, int src_pitch, void *dst, int dst_format, int dst_pitch, int sx, int sy, int dx, int dy, int width, int height) { ASSERT(src); ASSERT(dst); ASSERT(_al_pixel_format_is_real(dst_format)); /* Use memcpy if no conversion is needed. */ if (src_format == dst_format) { _al_copy_bitmap_data(src, src_pitch, dst, dst_pitch, sx, sy, dx, dy, width, height, src_format); return; } /* Video-only formats don't have conversion functions, so they should have * been taken care of before reaching this location. */ ASSERT(!_al_pixel_format_is_video_only(src_format)); ASSERT(!_al_pixel_format_is_video_only(dst_format)); (_al_convert_funcs[src_format][dst_format])(src, src_pitch, dst, dst_pitch, sx, sy, dx, dy, width, height); }
int _al_get_real_pixel_format(ALLEGRO_DISPLAY *display, int format) { /* Pick an appropriate format if the user is vague */ switch (format) { case ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA: case ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_XRGB_8888; break; case ALLEGRO_PIXEL_FORMAT_ANY: case ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA: case ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_ARGB_8888; break; case ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGB_555; break; case ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA: if (!try_display_format(display, &format)) format = ALLEGRO_PIXEL_FORMAT_RGB_565; break; case ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGBA_4444; break; case ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA: format = ALLEGRO_PIXEL_FORMAT_RGB_888; break; default: /* Already a real format - don't change it. */ break; } ASSERT(_al_pixel_format_is_real(format)); return format; }
static void _al_draw_transformed_bitmap_memory(ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint, int sx, int sy, int sw, int sh, int dw, int dh, ALLEGRO_TRANSFORM* local_trans, int flags) { float xsf[4], ysf[4]; int tl = 0, tr = 1, bl = 3, br = 2; int tmp; ALLEGRO_VERTEX v[4]; ASSERT(_al_pixel_format_is_real(src->format)); /* Decide what order to take corners in. */ if (flags & ALLEGRO_FLIP_VERTICAL) { tl = 3; tr = 2; bl = 0; br = 1; } else { tl = 0; tr = 1; bl = 3; br = 2; } if (flags & ALLEGRO_FLIP_HORIZONTAL) { tmp = tl; tl = tr; tr = tmp; tmp = bl; bl = br; br = tmp; } xsf[0] = 0; ysf[0] = 0; xsf[1] = dw; ysf[1] = 0; xsf[2] = 0; ysf[2] = dh; al_transform_coordinates(local_trans, &xsf[0], &ysf[0]); al_transform_coordinates(local_trans, &xsf[1], &ysf[1]); al_transform_coordinates(local_trans, &xsf[2], &ysf[2]); v[tl].x = xsf[0]; v[tl].y = ysf[0]; v[tl].z = 0; v[tl].u = sx; v[tl].v = sy; v[tl].color = tint; v[tr].x = xsf[1]; v[tr].y = ysf[1]; v[tr].z = 0; v[tr].u = sx + sw; v[tr].v = sy; v[tr].color = tint; v[br].x = xsf[2] + xsf[1] - xsf[0]; v[br].y = ysf[2] + ysf[1] - ysf[0]; v[br].z = 0; v[br].u = sx + sw; v[br].v = sy + sh; v[br].color = tint; v[bl].x = xsf[2]; v[bl].y = ysf[2]; v[bl].z = 0; v[bl].u = sx; v[bl].v = sy + sh; v[bl].color = tint; al_lock_bitmap(src, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY); _al_triangle_2d(src, &v[tl], &v[tr], &v[br]); _al_triangle_2d(src, &v[tl], &v[br], &v[bl]); al_unlock_bitmap(src); }