提交 702f5e81 编写于 作者: B bernard.xiong@gmail.com

add blit functions.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@842 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 bb22b8ec
#include <rtgui/rtgui.h>
#include <rtgui/blit.h>
/* 2 bpp to 1 bpp */
static void rtgui_blit_line_2_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
/* 3 bpp to 1 bpp */
static void rtgui_blit_line_3_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 3;
while (line)
{
*dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
((*(src_ptr + 1) & 0x0000E000)>>11) |
((*(src_ptr + 2) & 0x000000C0)>>6));
src_ptr += 3;
dst_ptr ++;
line --;
}
return;
}
/* 4 bpp to 1 bpp */
static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 4;
while (line)
{
*dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
((*(src_ptr + 1) & 0x0000E000)>>11) |
((*(src_ptr + 2) & 0x000000C0)>>6));
src_ptr += 4;
dst_ptr ++;
line --;
}
return;
}
/* 1 bpp to 2 bpp */
static void rtgui_blit_line_1_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
/* 3 bpp to 2 bpp */
static void rtgui_blit_line_3_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t* dst;
rt_uint32_t* src;
dst = (rt_uint16_t*)dst_ptr;
line = line / 3;
while (line)
{
*dst = (((*(src_ptr + 2) << 8) & 0x0000F800) |
((*(src_ptr + 1) << 3) & 0x000007E0) |
((*src_ptr >> 3) & 0x0000001F));
src_ptr += 3;
dst ++;
line --;
}
return;
}
/* 4 bpp to 2 bpp */
static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t* dst;
dst = (rt_uint16_t*)dst_ptr;
line = line / 4;
while (line)
{
*dst = (((*(src_ptr + 1) << 8) & 0x0000F800) |
((*(src_ptr + 1) << 3) & 0x000007E0) |
((*src_ptr >> 3) & 0x0000001F));
src_ptr += 4; /* skip alpha */
dst ++;
line --;
}
return;
}
static void rtgui_blit_line_1_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
return;
}
#define HI 1
#define LO 0
/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
{
0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
};
static void rtgui_blit_line_2_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t *src;
rt_uint32_t *dst;
src = (rt_uint16_t*)src_ptr;
dst = (rt_uint32_t*)dst_ptr;
line = line / 2;
while (line)
{
*dst++ = RGB565_RGBA8888_LUT[src[LO]*2] + RGB565_RGBA8888_LUT[src[HI]*2+1];
line--;
src ++;
}
}
void rtgui_blit_line_direct(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_memcpy(dst_ptr, src_ptr, line);
}
static void rtgui_blit_line_4_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 4;
while (line)
{
line --;
}
}
static void rtgui_blit_line_1_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
}
static void rtgui_blit_line_2_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
}
static void rtgui_blit_line_3_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
line = line / 4;
}
static const rtgui_blit_line_func _blit_table[5][5] =
{
/* 0_0, 1_0, 2_0, 3_0, 4_0 */
{RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
/* 0_1, 1_1, 2_1, 3_1, 4_1 */
{RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
/* 0_2, 1_2, 2_2, 3_2, 4_2 */
{RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 },
/* 0_3, 1_3, 2_3, 3_3, 4_3 */
{RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
/* 0_4, 1_4, 2_4, 3_4, 4_4 */
{RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
};
const rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
{
RT_ASSERT(dst_bpp>1 && dst_bpp < 5);
RT_ASSERT(src_bpp>1 && src_bpp < 5);
return _blit_table[dst_bpp][src_bpp];
}
......@@ -98,6 +98,7 @@ struct rtgui_image* rtgui_image_create_from_file(const char* type, const char* f
return RT_NULL;
}
image->palette = RT_NULL;
if (engine->image_load(image, filerw, load) != RT_TRUE)
{
/* close filerw context */
......@@ -146,6 +147,7 @@ struct rtgui_image* rtgui_image_create_from_mem(const char* type, const rt_uint8
return RT_NULL;
}
image->palette = RT_NULL;
if (engine->image_load(image, filerw, load) != RT_TRUE)
{
/* close filerw context */
......@@ -169,6 +171,8 @@ void rtgui_image_destroy(struct rtgui_image* image)
RT_ASSERT(image != RT_NULL);
image->engine->image_unload(image);
if (image->palette != RT_NULL)
rtgui_free(image->palette);
rtgui_free(image);
}
......@@ -194,3 +198,16 @@ void rtgui_image_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtg
}
}
struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors)
{
struct rtgui_image_palette* palette = RT_NULL;
if (ncolors > 0)
{
palette = (struct rtgui_image_palette*) rtgui_malloc(sizeof(struct rtgui_image_palette) +
sizeof(rtgui_color_t) * ncolors);
if (palette != RT_NULL) palette->colors = (rtgui_color_t*)(palette + 1);
}
return palette;
}
......@@ -3,6 +3,7 @@
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/image_bmp.h>
#include <rtgui/blit.h>
/* Compression encodings for BMP files */
#ifndef BI_RGB
......@@ -12,12 +13,24 @@
#define BI_BITFIELDS 3
#endif
#define hw_driver (rtgui_graphic_driver_get_default())
struct rtgui_image_bmp
{
rt_bool_t is_loaded;
rt_uint32_t Rmask;
rt_uint32_t Gmask;
rt_uint32_t Bmask;
rt_size_t pixel_offset;
rt_uint8_t byte_per_pixel;
rt_uint8_t pad;
rt_uint8_t ExpandBMP;
rt_uint8_t *pixels;
rt_uint32_t pitch;
struct rtgui_filerw* filerw;
};
......@@ -60,10 +73,26 @@ struct rtgui_image_engine rtgui_image_bmp_engine =
rtgui_image_bmp_blit
};
rt_inline rt_uint32_t rtgui_filerw_read32(struct rtgui_filerw* src)
{
rt_uint32_t value;
rtgui_filerw_read(src, &value, (sizeof value), 1);
return value;
}
rt_inline rt_uint16_t rtgui_filerw_read16(struct rtgui_filerw* src)
{
rt_uint16_t value;
rtgui_filerw_read(src, &value, (sizeof value), 1);
return value;
}
static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
{
char magic[2];
rt_bool_t is_bmp;
rt_off_t start;
if ( !file ) return 0;
......@@ -76,7 +105,7 @@ static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
if ( rtgui_filerw_read(file, magic, 1, sizeof(magic)) == sizeof(magic) )
{
if (magic[0] == 'B' &&
magic[1] == 'M')
magic[1] == 'M')
{
is_bmp = RT_TRUE;
}
......@@ -87,39 +116,256 @@ static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
return(is_bmp);
}
static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load)
static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load)
{
struct rtgui_image_bmp* bmp;
struct rtgui_image_bmp* bmp;
struct rtgui_image_bmp_header* header;
int ExpandBMP, bmpPitch;
rt_uint32_t Rmask;
rt_uint32_t Gmask;
rt_uint32_t Bmask;
bmp = RT_NULL;
header = RT_NULL;
header = (struct rtgui_image_bmp_header*) rtgui_malloc(sizeof(struct rtgui_image_bmp_header));
if (header == RT_NULL) return RT_FALSE;
if ( rtgui_filerw_read(src, header->magic, 1, sizeof(header->magic)) ==
sizeof(sizeof(header->magic)) )
{
if (header->magic[0] != 'B' ||
header->magic[1] != 'M')
{
goto __exit;
}
}
header->bfSize = rtgui_filerw_read32(src);
header->bfReserved1 = rtgui_filerw_read16(src);
header->bfReserved2 = rtgui_filerw_read16(src);
header->bfOffBits = rtgui_filerw_read32(src);
bmp = (struct rtgui_image_bmp*) rtgui_malloc(sizeof(struct rtgui_image_bmp));
if (bmp == RT_NULL) return RT_FALSE;
/* Read the Win32 BITMAPINFOHEADER */
header->biSize = rtgui_filerw_read32(src);
if ( header->biSize == 12 )
{
header->biWidth = (rt_uint32_t)rtgui_filerw_read16(src);
header->biHeight = (rt_uint32_t)rtgui_filerw_read16(src);
header->biPlanes = rtgui_filerw_read16(src);
header->biBitCount = rtgui_filerw_read16(src);
header->biCompression = BI_RGB;
header->biSizeImage = 0;
header->biXPelsPerMeter = 0;
header->biYPelsPerMeter = 0;
header->biClrUsed = 0;
header->biClrImportant = 0;
bmp->hw_driver = rtgui_graphic_driver_get_default();
if (bmp->hw_driver == RT_NULL) { rtgui_free(bmp); return RT_FALSE; }
}
else
{
header->biWidth = rtgui_filerw_read32(src);
header->biHeight = rtgui_filerw_read32(src);
header->biPlanes = rtgui_filerw_read16(src);
header->biBitCount = rtgui_filerw_read16(src);
header->biCompression = rtgui_filerw_read32(src);
header->biSizeImage = rtgui_filerw_read32(src);
header->biXPelsPerMeter = rtgui_filerw_read32(src);
header->biYPelsPerMeter = rtgui_filerw_read32(src);
header->biClrUsed = rtgui_filerw_read32(src);
header->biClrImportant = rtgui_filerw_read32(src);
rtgui_filerw_read(file, (char*)&header, 1, sizeof(header));
}
/* Expand 1 and 4 bit bitmaps to 8 bits per pixel */
switch (header->biBitCount)
{
case 1:
case 4:
ExpandBMP = header->biBitCount;
header->biBitCount = 8;
break;
default:
ExpandBMP = 0;
break;
}
/* We don't support any BMP compression right now */
Rmask = Gmask = Bmask = 0;
switch (header->biCompression)
{
case BI_RGB:
/* If there are no masks, use the defaults */
if ( header->bfOffBits == (14 + header->biSize) )
{
/* Default values for the BMP format */
switch (header->biBitCount)
{
case 15:
case 16:
Rmask = 0x7C00;
Gmask = 0x03E0;
Bmask = 0x001F;
break;
case 24:
case 32:
Rmask = 0x00FF0000;
Gmask = 0x0000FF00;
Bmask = 0x000000FF;
break;
default:
break;
}
break;
}
/* Fall through -- read the RGB masks */
case BI_BITFIELDS:
switch (header->biBitCount)
{
case 15:
case 16:
case 32:
Rmask = rtgui_filerw_read32(src);
Gmask = rtgui_filerw_read32(src);
Bmask = rtgui_filerw_read32(src);
break;
default:
break;
}
break;
default:
rt_kprintf("Compressed BMP files not supported\n");
goto __exit;
}
bmp = (struct rtgui_image_bmp*) rtgui_malloc(sizeof(struct rtgui_image_bmp));
if (bmp == RT_NULL)
goto __exit;
/* set image information */
image->w = (rt_uint16_t)header[1]; image->h = (rt_uint16_t)header[2];
image->w = header->biWidth;
image->h = header->biHeight;
image->engine = &rtgui_image_bmp_engine;
image->data = bmp;
bmp->filerw = file;
bmp->byte_per_pixel = bmp->hw_driver->byte_per_pixel;
bmp->filerw = src;
bmp->byte_per_pixel = header->biBitCount/8;
bmp->pitch = image->w * bmp->byte_per_pixel;
bmp->pixel_offset = rtgui_filerw_tell(file);
bmp->pixel_offset = header->bfOffBits;
bmp->Rmask = Rmask; bmp->Gmask = Gmask; bmp->Bmask = Bmask;
bmp->ExpandBMP = ExpandBMP;
/* Load the palette, if any */
#if 0
if ( palette )
{
rt_size_t i;
if (header->biClrUsed == 0)
header->biClrUsed = 1 << header->biBitCount;
image->palette = rtgui_image_palette_create(header->biClrUsed);
if ( header->biSize == 12 )
{
for ( i = 0; i < (int)header->biClrUsed; ++i )
{
rtgui_filerw_read(src, &RTGUI_RGB_R(image->palette->colors[i]), 1, 1);
rtgui_filerw_read(src, &RTGUI_RGB_G(image->palette->colors[i]), 1, 1);
rtgui_filerw_read(src, &RTGUI_RGB_B(image->palette->colors[i]), 1, 1);
RTGUI_RGB_A(image->palette->colors[i]) = 0;
}
}
else
{
for ( i = 0; i < (int)header->biClrUsed; ++i )
{
rtgui_filerw_read(src, &RTGUI_RGB_R(image->palette->colors[i]), 1, 1);
rtgui_filerw_read(src, &RTGUI_RGB_G(image->palette->colors[i]), 1, 1);
rtgui_filerw_read(src, &RTGUI_RGB_B(image->palette->colors[i]), 1, 1);
rtgui_filerw_read(src, &RTGUI_RGB_A(image->palette->colors[i]), 1, 1);
}
}
}
#endif
/* get padding */
switch (ExpandBMP)
{
case 1:
bmpPitch = (header->biWidth + 7) >> 3;
bmp->pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
break;
case 4:
bmpPitch = (header->biWidth + 1) >> 1;
bmp->pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
break;
default:
bmp->pad = ((bmp->pitch%4) ? (4-(bmp->pitch%4)) : 0);
break;
}
if (load == RT_TRUE)
{
rt_uint8_t *bits;
rt_uint32_t i;
/* load all pixels */
bmp->pixels = rtgui_malloc(image->h * bmp->pitch);
if (bmp->pixels == RT_NULL)
goto __exit;
/* Read the pixels. Note that the bmp image is upside down */
if ( rtgui_filerw_seek(src, bmp->pixel_offset, RTGUI_FILE_SEEK_SET) < 0)
goto __exit;
bits = bmp->pixels + image->h * bmp->pitch;
while ( bits > bmp->pixels )
{
/* release data */
rtgui_free(bmp);
return RT_FALSE;
bits -= bmp->pitch;
switch (ExpandBMP)
{
case 1:
case 4:
{
rt_uint8_t pixel = 0;
int shift = (8 - ExpandBMP);
for ( i=0; i < image->w; ++i )
{
if ( i % (8/ExpandBMP) == 0 )
{
if ( !rtgui_filerw_read(src, &pixel, 1, 1) )
goto __exit;
}
*(bits+i) = (pixel>>shift);
pixel <<= ExpandBMP;
}
}
break;
default:
if ( rtgui_filerw_read(src, bits, 1, bmp->pitch) != bmp->pitch ) goto __exit;
break;
}
/* Skip padding bytes */
if ( bmp->pad )
{
rt_uint8_t padbyte;
for ( i=0; i < bmp->pad; ++i )
{
rtgui_filerw_read(src, &padbyte, 1, 1);
}
}
}
rtgui_filerw_read(bmp->filerw, bmp->pixels, 1, image->h * bmp->pitch);
rtgui_filerw_close(bmp->filerw);
bmp->filerw = RT_NULL;
bmp->pixel_offset = 0;
......@@ -130,6 +376,13 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_fi
}
return RT_TRUE;
__exit:
rtgui_free(header);
if (bmp != RT_NULL)
rtgui_free(bmp->pixels);
rtgui_free(bmp);
return RT_FALSE;
}
static void rtgui_image_bmp_unload(struct rtgui_image* image)
......@@ -165,29 +418,59 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
bmp = (struct rtgui_image_bmp*) image->data;
RT_ASSERT(bmp != RT_NULL);
if ((dc->type != RTGUI_DC_HW) || (dc->type != RTGUI_DC_CLIENT)) return;
if ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT)) return;
/* the minimum rect */
if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
else w = rtgui_rect_width(*dst_rect);
if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
else h = rtgui_rect_height(*dst_rect);
if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
else w = rtgui_rect_width(*dst_rect);
if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
else h = rtgui_rect_height(*dst_rect);
if (bmp->pixels != RT_NULL)
{
if (bmp->pixels != RT_NULL)
{
rt_uint8_t* ptr;
/* get pixel pointer */
ptr = bmp->pixels;
for (y = 0; y < h; y ++)
if ((dc->type == RTGUI_DC_HW) || (dc->type == RTGUI_DC_CLIENT))
{
rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + y);
ptr += bmp->pitch;
if (bmp->byte_per_pixel == hw_driver->byte_per_pixel)
{
for (y = 0; y < h; y ++)
{
rtgui_dc_hw_draw_raw_hline(dc, ptr,
dst_rect->x1, dst_rect->x1 + w,
dst_rect->y1 + y);
ptr += bmp->pitch;
}
}
else
{
rt_uint8_t *line_ptr;
rtgui_blit_line_func blit_line;
rt_size_t pitch;
line_ptr = (rt_uint8_t*) rtgui_malloc(hw_driver->byte_per_pixel * w);
blit_line = rtgui_blit_line_get(hw_driver->byte_per_pixel , bmp->byte_per_pixel);
pitch = w * bmp->byte_per_pixel;
if (line_ptr != RT_NULL)
{
for (y = 0; y < h; y ++)
{
blit_line(line_ptr, ptr, pitch);
rtgui_dc_hw_draw_raw_hline(dc, line_ptr,
dst_rect->x1, dst_rect->x1 + w,
dst_rect->y1 + y);
ptr += bmp->pitch;
}
}
rtgui_free(line_ptr);
}
}
}
else
{
}
else
{
rt_uint8_t* ptr;
ptr = rtgui_malloc(bmp->pitch);
if (ptr == RT_NULL) return; /* no memory */
......@@ -205,7 +488,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
}
rtgui_free(ptr);
}
}
}
void rtgui_image_bmp_init()
......
......@@ -155,7 +155,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc,
hdc = (struct rtgui_image_hdc*) image->data;
RT_ASSERT(hdc != RT_NULL);
if ((dc->type != RTGUI_DC_HW) || (dc->type != RTGUI_DC_CLIENT)) return;
if ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT)) return;
/* the minimum rect */
if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
......@@ -207,7 +207,7 @@ static void rtgui_image_hdcmm_blit(struct rtgui_image* image, struct rtgui_dc* d
RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);
/* this dc is not visible */
if (rtgui_dc_get_visible(dc) != RT_TRUE || (dc->type != RTGUI_DC_HW) || (dc->type != RTGUI_DC_CLIENT)) return;
if (rtgui_dc_get_visible(dc) != RT_TRUE || ((dc->type != RTGUI_DC_HW) && (dc->type != RTGUI_DC_CLIENT))) return;
hdc = (struct rtgui_image_hdcmm*) image;
RT_ASSERT(hdc != RT_NULL);
......
#ifndef __RTGUI_BLIT_H__
#define __RTGUI_BLIT_H__
#include <rtgui/rtgui.h>
typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line);
const rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
#endif
......@@ -33,6 +33,13 @@ struct rtgui_image_engine
void (*image_blit)(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
};
struct rtgui_image_palette
{
rtgui_color_t* colors;
rt_uint32_t ncolors;
};
typedef struct rtgui_image_palette rtgui_image_palette_t;
struct rtgui_image
{
/* image metrics */
......@@ -41,6 +48,9 @@ struct rtgui_image
/* image engine */
const struct rtgui_image_engine* engine;
/* image palette */
rtgui_image_palette_t* palette;
/* image private data */
void* data;
};
......@@ -60,6 +70,7 @@ void rtgui_image_register_engine(struct rtgui_image_engine* engine);
/* blit an image on DC */
void rtgui_image_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors);
#endif
......@@ -33,6 +33,7 @@
#define RTGUI_DEFAULT_FONT_SIZE 12
#define RTGUI_USING_STDIO_FILERW
#define RTGUI_IMAGE_BMP
#define RTGUI_IMAGE_PNG
#define RTGUI_IMAGE_JPEG
#define RTGUI_USING_FONT12
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册