static void putpixel__nocheck(ALLEGRO_BITMAP *bmp, int x, int y, int color) { unsigned long addr = (unsigned long) bmp->line[y] + x * bmp->surf->format->BytesPerPixel; switch(bmp->surf->format->BytesPerPixel) { case 1: bmp_write8(addr, color); break; case 2: bmp_write16(addr, color); break; case 3: bmp_write24(addr, color); break; case 4: bmp_write32(addr, color); break; } }
void _al_clear_bitmap_by_locking(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color) { ALLEGRO_LOCKED_REGION *lr; int x1, y1, w, h; int x, y; unsigned char *line_ptr; /* This function is not just used on memory bitmaps, but also on OpenGL * video bitmaps which are not the current target, or when locked. */ ASSERT(bitmap); ASSERT(bitmap->flags & (ALLEGRO_MEMORY_BITMAP | _ALLEGRO_INTERNAL_OPENGL)); x1 = bitmap->cl; y1 = bitmap->ct; w = bitmap->cr_excl - x1; h = bitmap->cb_excl - y1; if (w <= 0 || h <= 0) return; /* XXX what about pre-locked bitmaps? */ lr = al_lock_bitmap_region(bitmap, x1, y1, w, h, ALLEGRO_PIXEL_FORMAT_ANY, 0); if (!lr) return; /* Write a single pixel so we can get the raw value. */ _al_put_pixel(bitmap, x1, y1, *color); /* Fill in the region. */ line_ptr = lr->data; switch (lr->pixel_size) { case 2: { int pixel_value = bmp_read16(line_ptr); for (y = y1; y < y1 + h; y++) { if (pixel_value == 0) { /* fast path */ memset(line_ptr, 0, 2 * w); } else { uint16_t *data = (uint16_t *)line_ptr; for (x = 0; x < w; x++) { bmp_write16(data, pixel_value); data++; } } line_ptr += lr->pitch; } break; } case 3: { int pixel_value = READ3BYTES(line_ptr); for (y = y1; y < y1 + h; y++) { unsigned char *data = (unsigned char *)line_ptr; if (pixel_value == 0) { /* fast path */ memset(data, 0, 3 * w); } else { for (x = 0; x < w; x++) { WRITE3BYTES(data, pixel_value); data += 3; } } line_ptr += lr->pitch; } break; } case 4: { int pixel_value = bmp_read32(line_ptr); for (y = y1; y < y1 + h; y++) { uint32_t *data = (uint32_t *)line_ptr; /* Special casing pixel_value == 0 doesn't seem to make any * difference to speed, so don't bother. */ for (x = 0; x < w; x++) { bmp_write32(data, pixel_value); data++; } line_ptr += lr->pitch; } break; } case sizeof(float4): { float4 *data = (float4 *)line_ptr; float4 pixel_value = *data; for (y = y1; y < y1 + h; y++) { data = (float4 *)line_ptr; for (x = 0; x < w; x++) { *data = pixel_value; data++; } line_ptr += lr->pitch; } break; } default: ASSERT(false); break; } al_unlock_bitmap(bitmap); }
/* Coordinates are inclusive full-pixel positions. So (0, 0, 0, 0) draws a * single pixel at 0/0. */ static void _al_draw_filled_rectangle_memory_fast(int x1, int y1, int x2, int y2, ALLEGRO_COLOR *color) { ALLEGRO_BITMAP *bitmap; ALLEGRO_LOCKED_REGION *lr; int w, h; int tmp; int x, y; unsigned char *line_ptr; bitmap = al_get_target_bitmap(); /* Make sure it's top left first */ if (x1 > x2) { tmp = x1; x1 = x2; x2 = tmp; } if (y1 > y2) { tmp = y1; y1 = y2; y2 = tmp; } /* Do clipping */ if (x1 < bitmap->cl) x1 = bitmap->cl; if (y1 < bitmap->ct) y1 = bitmap->ct; if (x2 > bitmap->cr_excl - 1) x2 = bitmap->cr_excl - 1; if (y2 > bitmap->cb_excl - 1) y2 = bitmap->cb_excl - 1; w = (x2 - x1) + 1; h = (y2 - y1) + 1; if (w <= 0 || h <= 0) return; /* XXX what about pre-locked bitmaps? */ lr = al_lock_bitmap_region(bitmap, x1, y1, w, h, ALLEGRO_PIXEL_FORMAT_ANY, 0); if (!lr) return; /* Write a single pixel so we can get the raw value. */ _al_put_pixel(bitmap, x1, y1, *color); /* Fill in the region. */ line_ptr = lr->data; switch (lr->pixel_size) { case 2: { int pixel_value = bmp_read16(line_ptr); for (y = y1; y < y1 + h; y++) { if (pixel_value == 0) { /* fast path */ memset(line_ptr, 0, 2 * w); } else { uint16_t *data = (uint16_t *)line_ptr; for (x = 0; x < w; x++) { bmp_write16(data, pixel_value); data++; } } line_ptr += lr->pitch; } break; } case 3: { int pixel_value = READ3BYTES(line_ptr); for (y = y1; y < y1 + h; y++) { unsigned char *data = (unsigned char *)line_ptr; if (pixel_value == 0) { /* fast path */ memset(data, 0, 3 * w); } else { for (x = 0; x < w; x++) { WRITE3BYTES(data, pixel_value); data += 3; } } line_ptr += lr->pitch; } break; } case 4: { int pixel_value = bmp_read32(line_ptr); for (y = y1; y < y1 + h; y++) { uint32_t *data = (uint32_t *)line_ptr; /* Special casing pixel_value == 0 doesn't seem to make any * difference to speed, so don't bother. */ for (x = 0; x < w; x++) { bmp_write32(data, pixel_value); data++; } line_ptr += lr->pitch; } break; } case sizeof(float4): { float4 *data = (float4 *)line_ptr; float4 pixel_value = *data; for (y = y1; y < y1 + h; y++) { data = (float4 *)line_ptr; for (x = 0; x < w; x++) { *data = pixel_value; data++; } line_ptr += lr->pitch; } break; } default: ASSERT(false); break; } al_unlock_bitmap(bitmap); }
void convert_image_to_allegro_templ(const Image* image, BITMAP* bmp, int _x, int _y, const Palette* palette) { const LockImageBits<ImageTraits> bits(image); typename LockImageBits<ImageTraits>::const_iterator src_it = bits.begin(); #ifdef _DEBUG typename LockImageBits<ImageTraits>::const_iterator src_end = bits.end(); #endif int depth = bitmap_color_depth(bmp); int x, y, w = image->width(), h = image->height(); unsigned long bmp_address; bmp_select(bmp); switch (depth) { case 8: #if defined GFX_MODEX && !defined ALLEGRO_UNIX && !defined ALLEGRO_MACOSX if (is_planar_bitmap (bmp)) { for (y=0; y<h; ++y) { bmp_address = (unsigned long)bmp->line[_y]; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); outportw(0x3C4, (0x100<<((_x+x)&3))|2); bmp_write8(bmp_address+((_x+x)>>2), (convert_color_to_allegro<ImageTraits, 8>(*src_it, palette))); ++src_it; address++; } _y++; } } else { #endif for (y=0; y<h; ++y) { bmp_address = bmp_write_line(bmp, _y)+_x; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); bmp_write8(bmp_address, (convert_color_to_allegro<ImageTraits, 8>(*src_it, palette))); ++bmp_address; ++src_it; } _y++; } #if defined GFX_MODEX && !defined ALLEGRO_UNIX && !defined ALLEGRO_MACOSX } #endif break; case 15: _x <<= 1; for (y=0; y<h; y++) { bmp_address = bmp_write_line(bmp, _y)+_x; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); bmp_write15(bmp_address, (convert_color_to_allegro<ImageTraits, 15>(*src_it, palette))); bmp_address += 2; ++src_it; } _y++; } break; case 16: _x <<= 1; for (y=0; y<h; ++y) { bmp_address = bmp_write_line(bmp, _y)+_x; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); bmp_write16(bmp_address, (convert_color_to_allegro<ImageTraits, 16>(*src_it, palette))); bmp_address += 2; ++src_it; } _y++; } break; case 24: _x *= 3; for (y=0; y<h; ++y) { bmp_address = bmp_write_line(bmp, _y)+_x; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); bmp_write24(bmp_address, (convert_color_to_allegro<ImageTraits, 24>(*src_it, palette))); bmp_address += 3; ++src_it; } _y++; } break; case 32: _x <<= 2; for (y=0; y<h; ++y) { bmp_address = bmp_write_line(bmp, _y)+_x; for (x=0; x<w; ++x) { ASSERT(src_it != src_end); bmp_write32(bmp_address, (convert_color_to_allegro<ImageTraits, 32>(*src_it, palette))); bmp_address += 4; ++src_it; } _y++; } break; }
/* * call-seq: * bmp_write32(addr, c) -> nil * */ VALUE a4r_API_bmp_write32(VALUE self, VALUE addr, VALUE c) { bmp_write32(NUM2ULONG(addr), *((uint32_t*)StringValuePtr(c))); return Qnil; }
void SuperEagle_ex(uint8 *src, uint32 src_pitch, uint8 *unused, ALLEGRO_BITMAP *dest, uint32 width, uint32 height) { int j, v; unsigned int x, y; int sbpp = BYTES_PER_PIXEL(bitmap_color_depth(dest)); unsigned long color[12]; unsigned char **src_line = new unsigned char*[4]; unsigned char **dst_line = new unsigned char*[2]; /* Point to the first 3 lines. */ src_line[0] = src; src_line[1] = src; src_line[2] = src + src_pitch; src_line[3] = src + src_pitch * 2; /* Can we write the results directly? */ if (is_video_bitmap(dest) || is_planar_bitmap(dest)) { //dst_line[0] = malloc(sizeof(char) * sbpp * width); //dst_line[1] = malloc(sizeof(char) * sbpp * width); dst_line[0] = new unsigned char[sbpp*width]; dst_line[1] = new unsigned char[sbpp*width]; v = 1; } else { dst_line[0] = dest->line[0]; dst_line[1] = dest->line[1]; v = 0; } /* Set destination */ bmp_select(dest); x = 0, y = 0; if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = color[0]; color[2] = color[0]; color[3] = color[0]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } for (y = 0; y < height; y++) { /* Todo: x = width - 2, x = width - 1 */ for (x = 0; x < width; x++) { unsigned long product1a, product1b, product2a, product2b; //--------------------------------------- B1 B2 0 1 // 4 5 6 S2 -> 2 3 4 5 // 1 2 3 S1 6 7 8 9 // A1 A2 10 11 if (color[7] == color[4] && color[3] != color[8]) { product1b = product2a = color[7]; if ((color[6] == color[7]) || (color[4] == color[1])) product1a = INTERPOLATE(color[7], INTERPOLATE(color[7], color[3])); else product1a = INTERPOLATE(color[3], color[4]); if ((color[4] == color[5]) || (color[7] == color[10])) product2b = INTERPOLATE(color[7], INTERPOLATE(color[7], color[8])); else product2b = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] != color[4]) { product2b = product1a = color[3]; if ((color[0] == color[3]) || (color[5] == color[9])) product1b = INTERPOLATE(color[3], INTERPOLATE(color[3], color[4])); else product1b = INTERPOLATE(color[3], color[1]); if ((color[8] == color[11]) || (color[2] == color[3])) product2a = INTERPOLATE(color[3], INTERPOLATE(color[3], color[2])); else product2a = INTERPOLATE(color[7], color[8]); } else if (color[3] == color[8] && color[7] == color[4]) { register int r = 0; r += GET_RESULT(color[4], color[3], color[6], color[10]); r += GET_RESULT(color[4], color[3], color[2], color[0]); r += GET_RESULT(color[4], color[3], color[11], color[9]); r += GET_RESULT(color[4], color[3], color[1], color[5]); if (r > 0) { product1b = product2a = color[7]; product1a = product2b = INTERPOLATE(color[3], color[4]); } else if (r < 0) { product2b = product1a = color[3]; product1b = product2a = INTERPOLATE(color[3], color[4]); } else { product2b = product1a = color[3]; product1b = product2a = color[7]; } } else { product2b = product1a = INTERPOLATE(color[7], color[4]); product2b = Q_INTERPOLATE(color[8], color[8], color[8], product2b); product1a = Q_INTERPOLATE(color[3], color[3], color[3], product1a); product2a = product1b = INTERPOLATE(color[3], color[8]); product2a = Q_INTERPOLATE(color[7], color[7], color[7], product2a); product1b = Q_INTERPOLATE(color[4], color[4], color[4], product1b); } if (PixelsPerMask == 2) { *((unsigned long *) (&dst_line[0][x * 4])) = product1a | (product1b << 16); *((unsigned long *) (&dst_line[1][x * 4])) = product2a | (product2b << 16); } else { *((unsigned long *) (&dst_line[0][x * 8])) = product1a; *((unsigned long *) (&dst_line[0][x * 8 + 4])) = product1b; *((unsigned long *) (&dst_line[1][x * 8])) = product2a; *((unsigned long *) (&dst_line[1][x * 8 + 4])) = product2b; } /* Move color matrix forward */ color[0] = color[1]; color[2] = color[3]; color[3] = color[4]; color[4] = color[5]; color[6] = color[7]; color[7] = color[8]; color[8] = color[9]; color[10] = color[11]; if (x < width - 2) { x += 2; if (PixelsPerMask == 2) { color[1] = *(((unsigned short*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned short*)src_line[1]) + x + 1); color[9] = *(((unsigned short*)src_line[2]) + x + 1); } color[11] = *(((unsigned short*)src_line[3]) + x); } else { color[1] = *(((unsigned long*)src_line[0]) + x); if (x < width) { color[5] = *(((unsigned long*)src_line[1]) + x + 1); color[9] = *(((unsigned long*)src_line[2]) + x + 1); } color[11] = *(((unsigned long*)src_line[3]) + x); } x -= 2; } } /* We're done with one line, so we shift the source lines up */ src_line[0] = src_line[1]; src_line[1] = src_line[2]; src_line[2] = src_line[3]; /* Read next line */ if (y + 3 >= height) src_line[3] = src_line[2]; else src_line[3] = src_line[2] + src_pitch; /* Then shift the color matrix up */ if (PixelsPerMask == 2) { unsigned short *sbp; sbp = (unsigned short*)src_line[0]; color[0] = *sbp; color[1] = *(sbp + 1); sbp = (unsigned short*)src_line[1]; color[2] = *sbp; color[3] = color[2]; color[4] = *(sbp + 1); color[5] = *(sbp + 2); sbp = (unsigned short*)src_line[2]; color[6] = *sbp; color[7] = color[6]; color[8] = *(sbp + 1); color[9] = *(sbp + 2); sbp = (unsigned short*)src_line[3]; color[10] = *sbp; color[11] = *(sbp + 1); } else { unsigned long *lbp; lbp = (unsigned long*)src_line[0]; color[0] = *lbp; color[1] = *(lbp + 1); lbp = (unsigned long*)src_line[1]; color[2] = *lbp; color[3] = color[2]; color[4] = *(lbp + 1); color[5] = *(lbp + 2); lbp = (unsigned long*)src_line[2]; color[6] = *lbp; color[7] = color[6]; color[8] = *(lbp + 1); color[9] = *(lbp + 2); lbp = (unsigned long*)src_line[3]; color[10] = *lbp; color[11] = *(lbp + 1); } /* Write the 2 lines, if not already done so */ if (v) { unsigned long dst_addr; dst_addr = bmp_write_line(dest, y * 2); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[0] + j))); dst_addr = bmp_write_line(dest, y * 2 + 1); for (j = 0; j < dest->w * sbpp; j += sizeof(long)) bmp_write32(dst_addr + j, *((unsigned long *) (dst_line[1] + j))); } else { if (y < height - 1) { dst_line[0] = dest->line[y * 2 + 2]; dst_line[1] = dest->line[y * 2 + 3]; } } } bmp_unwrite_line(dest); if (v) { delete dst_line[0]; delete dst_line[1]; } delete[] src_line; delete[] dst_line; }