add blit functions.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@842 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
bb22b8ec0d
commit
702f5e81b6
|
@ -0,0 +1,298 @@
|
|||
#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;
|
||||
|
||||
|
@ -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_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);
|
||||
|
||||
/* 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;
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
/* 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) return RT_FALSE;
|
||||
|
||||
bmp->hw_driver = rtgui_graphic_driver_get_default();
|
||||
if (bmp->hw_driver == RT_NULL) { rtgui_free(bmp); return RT_FALSE; }
|
||||
|
||||
rtgui_filerw_read(file, (char*)&header, 1, sizeof(header));
|
||||
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,7 +418,7 @@ 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;
|
||||
|
@ -179,14 +432,44 @@ static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc,
|
|||
|
||||
/* get pixel pointer */
|
||||
ptr = bmp->pixels;
|
||||
|
||||
if ((dc->type == RTGUI_DC_HW) || (dc->type == RTGUI_DC_CLIENT))
|
||||
{
|
||||
if (bmp->byte_per_pixel == hw_driver->byte_per_pixel)
|
||||
{
|
||||
for (y = 0; y < h; y ++)
|
||||
{
|
||||
rtgui_dc_client_draw_raw_hline(dc, ptr, dst_rect->x1, dst_rect->x1 + w, dst_rect->y1 + 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
|
||||
{
|
||||
rt_uint8_t* ptr;
|
||||
ptr = rtgui_malloc(bmp->pitch);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#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
|
||||
|
|
Loading…
Reference in New Issue