📄 abmloader.cpp
字号:
#include "stdafx.h"
#include "mmi.h"
#define ABMENC_BMP_FILE_BUFFER_SIZE (1024 * 1024) /* 1 MB input bitmap file size limit */
#define DRV_RGB_TO_HW(R,G,B) ( (U16)(((B)&0xf8)>>3)|(((G)&0xfc)<<3)|(((R)&0xf8)<<8) )
#define RGB_16_BIT_TYPE DRV_RGB_TO_HW(0, 255, 0)
#define COLOR_FORMAT_RGB3553 0xE007 /* 6205B, 6218 */
#define COLOR_FORMAT_RGB565 0x07E0 /* other than 6205B and 6218 */
#define GET_32(bp) ((U32)((bp)[0] | ((bp)[1] << 8) | ((bp)[2] << 16) | ((bp)[3] << 24)))
#define GET_24(bp) ((U32)((bp)[0] | ((bp)[1] << 8)) | ((bp)[2] << 16))
#define GET_16(bp) ((U32)((bp)[0] | ((bp)[1] << 8)))
#define PUT_16(mem, c) *((U16*)(mem)) = (U16)(c)
#define PUT_24(mem, c) \
do \
{ \
U8 *mem_8 = (U8*)(mem); \
mem_8[0] = (U8)(c); \
mem_8[1] = (U8)((c) >> 8); \
mem_8[2] =(U8)((c) >> 16); \
} while (0)
#define ARGB(a, r, g, b) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
#define _RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
/* RGB888 */
#define R_OF_RGB888(c) (((c) << 8) >> 24)
#define G_OF_RGB888(c) (((c) << 16) >> 24)
#define B_OF_RGB888(c) (((c) << 24) >> 24)
/* ARGB8888 */
#define A_OF_ARGB8888(c) ((c) >> 24)
#define R_OF_ARGB8888(c) R_OF_RGB888(c)
#define G_OF_ARGB8888(c) G_OF_RGB888(c)
#define B_OF_ARGB8888(c) B_OF_RGB888(c)
/* RGB565 */
#define R_OF_RGB565(c) (((c) << 16) >> 27)
#define G_OF_RGB565(c) (((c) << 21) >> 26)
#define B_OF_RGB565(c) (((c) << 27) >> 27)
/* RGB3553 */
#define R_OF_RGB3553(c) (((c) << 24) >> 27)
#define G_OF_RGB3553(c) ((((c) & 0x7) << 3) | (((c) >> 13) & 0x7))
#define B_OF_RGB3553(c) (((c) << 19) >> 27)
/* RGB16 */
#define R_OF_RGB16(c) ((RGB_16_BIT_TYPE == COLOR_FORMAT_RGB565) ? R_OF_RGB565(c) : R_OF_RGB3553(c))
#define G_OF_RGB16(c) ((RGB_16_BIT_TYPE == COLOR_FORMAT_RGB565) ? G_OF_RGB565(c) : G_OF_RGB3553(c))
#define B_OF_RGB16(c) ((RGB_16_BIT_TYPE == COLOR_FORMAT_RGB565) ? B_OF_RGB565(c) : B_OF_RGB3553(c))
#define RGB565(r, g, b) (((r) << 11) | ((g) << 5) | (b))
#define RGB3553(r, g, b) (((r) << 3) | ((b) << 8) | ((g) >> 3) | (((g) & 0x7) << 13))
#define ARGB8888_TO_RGB565(c) RGB565(R_OF_ARGB8888(c) >> 3, G_OF_ARGB8888(c) >> 2, B_OF_ARGB8888(c) >> 3)
#define ARGB8888_TO_RGB3553(c) RGB3553(R_OF_ARGB8888(c) >> 3, G_OF_ARGB8888(c) >> 2, B_OF_ARGB8888(c) >> 3)
#define ARGB8888_TO_RGB16(c) ((RGB_16_BIT_TYPE == COLOR_FORMAT_RGB565) ? ARGB8888_TO_RGB565(c) : ARGB8888_TO_RGB3553(c))
/*
* color reduction algorithms
*/
#define COLOR_REDUCE_24_TO_16(c) ((c) & 0xFFF8FCF8) /* clear R[2:0], G[1:0], B[2:0] */
#define COLOR_REDUCE_24_TO_18(c) ((c) & 0xFFFCFCFC) /* clear R[1:0], G[1:0], B[1:0] */
// /TODO: SHOULD USE COLOR_REDUCE_24_TO_18 for 18-bit panels (to reduce unique colors)
#define COLOR_REDUCE(c) ((ABM_PALETTE_BPP == 16) ? COLOR_REDUCE_24_TO_16(c) : (c))
/*
* ABM bitstream writer
*/
/* initialize bitstream variables */
#define BW_INIT(mem_ptr) \
{ \
U32 bits_buf; \
U16 *bits_mem_ptr; \
U32 bits_left; \
\
bits_mem_ptr = mem_ptr; \
bits_buf = 0; \
bits_left = 0;
/* flush bitstream buffer */
#define BW_END() \
if (bits_left > 0) \
{ \
*bits_mem_ptr++ = bits_buf; \
} \
}
/* write bpp bits of data into the bitstream */
#define BW_WRITE(data, bpp) \
bits_buf |= ((data) & ((1 << (bpp)) - 1)) << bits_left; \
bits_left += bpp; \
if (bits_left >= 16) \
{ \
*bits_mem_ptr++ = bits_buf; \
bits_buf >>= 16; \
bits_left -= 16; \
}
/* PBM header size */
#define PBM_HEADER_SIZE 13
/*
* windows bitmap
*/
#define BITMAPFILEHEADER_SIZE 14
#define BITMAPINFO_HEADER_SIZE 40
/*
* ABM encoder
*/
#define ABM_MAX_COLOR_NUM 65536 /* ABM supports up to 65536 colors */
#define ABM_HEADER_SIZE 12
#define ABM_PALETTE_BPP ((MMI_DEVICE_BMP_FORMAT == 16) ? 16 : 24)
#define TRANSPARENT_COLOR_24 _RGB(10, 11, 12) /* transparent color of 24-bit bitmap */
#define TRANSPARENT_COLOR_32 ARGB(255, 10, 11, 12) /* transparent color of 32-bit bitmap */
/* abm encoder return code */
typedef enum
{
ABMENC_UNIT_TEST_FAILED = -1, /* unit test failed */
ABMENC_UNIT_TEST_SUCCESSFUL = 0, /* unit test successful */
ABM_ENC_INPUT_BITMAP_ERROR = -2, /* input bitmap error */
ABMENC_COLOR_NOT_FOUND = -1, /* color not found in the color table */
ABM_ENC_RETURN_KEEP_ORIGINAL = 0, /* do not use ABM */
ABM_ENC_RETURN_USE_ABM, /* use ABM */
ABM_ENC_OK /* ABM internal use successful code */
}abm_enc_return_value;
/*****************************************************************************
* Typedef
*****************************************************************************/
typedef U32 mycolor;
/* abm encoder structure*/
typedef struct
{
S32 bmp_width; /* bitmap width */
S32 bmp_height; /* bitmap height */
S32 bmp_bpp; /* bitmap bits per pixel */
S32 bmp_palette_num; /* number of colors in the palette */
mycolor bmp_palette[256]; /* bitmap palette (8-bit bpp max) */
U8 *bmp_pixel_start_p; /* pointer to bitmap data */
U32 line_padding_bytes; /* line padding bytes */
S32 x1, y1, x2, y2; /* image bounding box */
S32 src_key_color_enable; /* for PBM source key color */
S32 is_windows_bmp; /* windows BMP 32-bit is always XRGB8888, not expected ARGB8888. */
} abm_enc_struct;
/* color index table */
typedef struct
{
mycolor color_table[ABM_MAX_COLOR_NUM]; /* color index table */
S32 color_num; /* number of colors in the table */
S32 last_search_idx; /* last search index */
} color_index_table_struct;
/*****************************************************************************
* Static Declaration
*****************************************************************************/
/* file buffer to keep the whole bitmap file */
static U8 g_file_buf[ABMENC_BMP_FILE_BUFFER_SIZE];
U8 ABM_buffer[ABMENC_BMP_FILE_BUFFER_SIZE];
/* color index table */
static color_index_table_struct g_color_idx_tab;
static color_index_table_struct * const cit = &g_color_idx_tab; /* Color Index Table -> cit */
/* abm encoder context */
static abm_enc_struct g_abm_enc;
static abm_enc_struct * const abm_enc = &g_abm_enc;
/* table to calculate ceiling(log2(x)) */
static const U16 log2_table[15] = {2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
/*****************************************************************************
* static Function
*****************************************************************************/
static S32 search_color(mycolor search_color);
static void insert_color_at(mycolor c, S32 insert_idx);
static void add_color_if_new(mycolor c);
static U32 get_normal_color_num(void);
static U32 get_file_size(FILE *fp);
static S32 parse_bitmap(U8* bmp_data_p, U32 input_bmp_file_size);
static void update_image_bounding_box(S32 x, S32 y);
static void limit_image_bounding_box(void);
static U32 log2_ceiling(U32 x);
static void abmenc_build_color_index_table(void);
static U32 abmenc_encode(U8* out_mem_p);
/*****************************************************************************
* FUNCTION
* search_color
* DESCRIPTION
* search a color in the color table (binary search)
* PARAMETERS
* search_color [IN] color to search
* RETURNS
* color index in the color table if found, otherwise ABMENC_COLOR_NOT_FOUND (-1)
*****************************************************************************/
static S32 search_color(mycolor search_color)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S32 start_idx, end_idx, center_idx;
mycolor c;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
start_idx = 0;
end_idx = cit->color_num - 1;
while (start_idx <= end_idx)
{
center_idx = (start_idx + end_idx) / 2;
c = cit->color_table[center_idx];
if (search_color < c)
{
start_idx = center_idx + 1;
}
else if (search_color > c)
{
end_idx = center_idx - 1;
}
else
{
return center_idx;
}
}
/* keep the search index to speed up the search-and-insert operation, add_color_if_new() */
cit->last_search_idx = start_idx;
return ABMENC_COLOR_NOT_FOUND;
}
/*****************************************************************************
* FUNCTION
* insert_color_at
* DESCRIPTION
* insert a color at a specified index in the color table
* PARAMETERS
* c [IN] color to add
* insert_idx [IN] insertion index of the table
* RETURNS
* void
*****************************************************************************/
static void insert_color_at(mycolor c, S32 insert_idx)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S32 i;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
if (insert_idx >= ABM_MAX_COLOR_NUM)
{
return;
}
/* insert at insert_idx */
for (i = cit->color_num - 1; i >= insert_idx; i--)
{
cit->color_table[i + 1] = cit->color_table[i];
}
cit->color_table[insert_idx] = c;
cit->color_num++;
}
/*****************************************************************************
* FUNCTION
* add_color_if_new
* DESCRIPTION
* add a color if the color does not exist in the table
* PARAMETERS
* c [IN] color to add
* RETURNS
* void
*****************************************************************************/
static void add_color_if_new(mycolor c)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S32 insert_idx;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
insert_idx = search_color(c);
if (insert_idx == ABMENC_COLOR_NOT_FOUND)
{
insert_idx = cit->last_search_idx;
}
else
{ /* found in the table, return */
return;
}
insert_color_at(c, insert_idx);
}
/*****************************************************************************
* FUNCTION
* get_normal_color_num
* DESCRIPTION
* get the number of NORMAL colors
* PARAMETERS
* void
* RETURNS
* number of OPAQUE colors (alpha = 255) in the color index table
*****************************************************************************/
static U32 get_normal_color_num(void)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
S32 i;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
for (i = 0; i < cit->color_num; i++)
{
if (A_OF_ARGB8888(cit->color_table[i]) != 255)
{
break;
}
}
return i;
}
/*****************************************************************************
* FUNCTION
* get_file_size
* DESCRIPTION
* return the file size in bytes
* PARAMETERS
* fp [IN] file pointer
* RETURNS
* file size in bytes
*****************************************************************************/
static U32 get_file_size(FILE *fp)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
U32 fpos, file_size;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* save the current file position */
fpos = ftell(fp);
/* seek to the EOF */
fseek(fp, 0, SEEK_END);
/* get file size */
file_size = ftell(fp);
/* restore the old file position */
fseek(fp, fpos, SEEK_SET);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -