📄 abmloader.cpp
字号:
U16 *mem16_p;
S32 normal_color_num, alpha_color_num, color_num;
S32 i;
U32 abm_size;
U32 bmp_bpp;
mycolor c, color16;
mycolor a, r, g, b;
U32 bytes_per_pixel;
U32 bitstream_padding_byte;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
w = abm_enc->bmp_width;
h = abm_enc->bmp_height;
bmp_bpp = abm_enc->bmp_bpp;
line_padding_bytes = abm_enc->line_padding_bytes;
/* 1st pass, build the unique color index table */
abmenc_build_color_index_table();
/* out of ABM limit, return a large size to prevent choosing ABM */
if (cit->color_num >= ABM_MAX_COLOR_NUM)
{
return 0xFFFFFFFF;
}
color_num = cit->color_num + 1; /* 1 for transparent color 0 */
normal_color_num = get_normal_color_num() + 1; /* 1 for transparent color 0 */
alpha_color_num = color_num - normal_color_num;
bpp = log2_ceiling(color_num);
/*
* fill the ABM 12-byte header
*/
mem16_p = (U16*)out_mem_p;
mem16_p[0] = (U16)w;
if (ABM_PALETTE_BPP == 16)
{
mem16_p[1] = (U16)h;
}
else
{
mem16_p[1] = (U16)(h | 0x8000); /* bit 15 is 1 to indicate it's 24-bit palette. */
}
mem16_p[2] = (U16)normal_color_num; /* number of normal colors */
mem16_p[3] =(U16) alpha_color_num; /* number of alpha colors */
/* bounding box info header (width and height offsets, not bounding box coordinates) */
mem16_p[4] = (U16)((abm_enc->y1 << 8) | abm_enc->x1);
bottom_right_off_w = w - 1 - abm_enc->x2;
bottom_right_off_h = h - 1 - abm_enc->y2;
mem16_p[5] = (U16)((bottom_right_off_h << 8) | bottom_right_off_w);
mem16_p += 6;
mem8_p = (U8*)mem16_p;
/* output color palette */
for (i = 0; i < color_num - 1; i++)
{
c = cit->color_table[i];
a = A_OF_ARGB8888(c);
/* prevent blue channel from saturation to get rid of source key checking in the decoder */
if (ABM_PALETTE_BPP == 16)
{ /* 16-bit */
color16 = ARGB8888_TO_RGB16(c);
if (B_OF_RGB16(color16) == 0x1F)
{
c -= 1 << 3; /* 5-bit B: 0x1F -> 0x1E */
}
}
else
{ /* 24-bit and 32-bit ABM both use 24-bit palette */
if (B_OF_ARGB8888(c) == 0xFF)
{
c -= 1; /* 8-bit B: 0xFF -> 0xFE */
}
}
/* pre-calculate alpha color */
if (a != 255)
{
r = R_OF_ARGB8888(c);
g = G_OF_ARGB8888(c);
b = B_OF_ARGB8888(c);
r = (r * a) / 256;
g = (g * a) / 256;
b = (b * a) / 256;
c = _RGB(r, g, b);
}
if (ABM_PALETTE_BPP == 16)
{ /* 16-bit palette */
PUT_16(mem8_p, ARGB8888_TO_RGB16(c));
mem8_p += 2;
}
else
{ /* 24-bit palette */
PUT_24(mem8_p, c);
mem8_p += 3;
}
}
/* output 1-byte alpha values of alpha colors */
for (i = normal_color_num - 1; i < color_num - 1; i++)
{
/* inverted alpha due to precalculation */
*mem8_p++ = 255 - A_OF_ARGB8888(cit->color_table[i]);
}
/* add a padding byte to meet 2-byte alignment for the bitstream */
if ((U32)mem8_p & 1)
{
/* padding with 0xFF */
*mem8_p++ = 0xFF;
bitstream_padding_byte = 1;
}
else
{
bitstream_padding_byte = 0;
}
img_p = abm_enc->bmp_pixel_start_p;
bytes_per_pixel = abm_enc->bmp_bpp / 8;
/* calculate bounding box width and height */
bound_box_w = abm_enc->x2 - abm_enc->x1 + 1;
bound_box_h = abm_enc->y2 - abm_enc->y1 + 1;
/* initialize the bitstream writer */
BW_INIT((U16*)mem8_p);
/* 2nd pass, output ABM packed pixels, and do vertical flipping (BMP nature) */
for (y = abm_enc->y1; y <= abm_enc->y2; y++)
{
/* point pixel_p to the start of the line (notice the vertical flip) */
pixel_p = img_p + (w * bytes_per_pixel + line_padding_bytes) * (h - 1 - y) + abm_enc->x1 * bytes_per_pixel;
for (x = 0; x < bound_box_w; x++)
{
/* read pixel */
if (bmp_bpp == 32)
{ /* 32-bit bitmap */
c = GET_32(pixel_p);
pixel_p += 4;
/* Windows 32-bit BMP is always 0x00RRGGBB. */
if (abm_enc->is_windows_bmp)
{
c |= 0xFF000000;
}
if (abm_enc->src_key_color_enable && (c == TRANSPARENT_COLOR_32))
{ /* transparent color, alpha = 0 */
c = 0;
}
}
else if (bmp_bpp == 24)
{ /* 24-bit bitmap */
c = GET_24(pixel_p);
pixel_p += 3;
if (abm_enc->src_key_color_enable && (c == TRANSPARENT_COLOR_24))
{ /* transparent color, alpha = 0 */
c = 0;
}
else
{ /* opaque color, alpha = 255 */
c |= 0xFF000000;
}
}
else
{ /* 8-bit bitmap */
c = abm_enc->bmp_palette[*pixel_p++];
}
/* search color from the color table */
if (A_OF_ARGB8888(c) == 0)
{ /* alpha = 0 -> transparent color, output directly without searching */
p = 0;
}
else
{ /* go search the color, the color WILL and MUST exist in the table */
/* color 0 is reserved for transparent color, so +1 */
p = search_color(COLOR_REDUCE(c)) + 1;
}
/* write the ABM pixel data into the bitstream */
BW_WRITE(p, bpp);
}
}
/* flush bitstream writer */
BW_END();
abm_size = ABM_HEADER_SIZE + /* header size */
(color_num - 1) * ABM_PALETTE_BPP / 8 + /* palette size */
alpha_color_num + /* 8-bit alpha channel */
bitstream_padding_byte + /* a padding byte or not */
(bound_box_w * bound_box_h * bpp + 15) / 16 * 16 / 8; /* pixel data size (2-byte align) */
return abm_size;
}
/*****************************************************************************
* FUNCTION
* ABM_load
* DESCRIPTION
* ABM encoder interface
* PARAMETERS
* in_bmp_filename [IN] input bitmap filename
* dev_bmp_bpp [IN] PBM color depth in bits
* image_type [IN] for decision whether to use ABM
* data [OUT] output memory
* size [OUT] size of ABM image
* width [OUT] width of ABM image
* height [OUT] height of ABM image
* RETURNS
* return code to use ABM or not
* + ABM_ENC_RETURN_KEEP_ORIGINAL 0 donot use ABM
* + ABM_ENC_RETURN_USE_ABM 1 use ABM
*****************************************************************************/
S32 ABM_load(
char *in_bmp_filename,
S32 dev_bmp_bpp,
U8 image_type,
U8 *data,
U32 *size,
S32 *width,
S32 *height)
{
/*----------------------------------------------------------------*/
/* Local Variables */
/*----------------------------------------------------------------*/
FILE *fp;
U32 input_bmp_file_size;
S32 pbm_size;
S32 w, h;
/*----------------------------------------------------------------*/
/* Code Body */
/*----------------------------------------------------------------*/
/* initialize color index table and abm encoder context */
cit->color_num = 0;
memset(abm_enc, 0, sizeof(abm_enc_struct));
/* enable source key color only for PBM and BMP */
if (image_type == IMAGE_TYPE_BMP)
{
abm_enc->src_key_color_enable = 1;
}
/* It is necessary to identify PNG to BMP or originally BMP for 32-bit BMP files. */
if (image_type != IMAGE_TYPE_PNG)
{
abm_enc->is_windows_bmp = 1;
}
/* open the input bitmap file */
fp = fopen(in_bmp_filename, "rb");
if (fp == NULL)
{
printf("[ABM enc] open file error: %s\n", in_bmp_filename);
return ABM_ENC_RETURN_KEEP_ORIGINAL;
}
/* get the file size of the input BMP file */
input_bmp_file_size = get_file_size(fp);
/* make sure the file buffer size is enough */
if (input_bmp_file_size > ABMENC_BMP_FILE_BUFFER_SIZE)
{
fclose(fp);
printf("[ABM enc] over buffer size: %s\n", in_bmp_filename);
return ABM_ENC_RETURN_KEEP_ORIGINAL;
}
/* read the whole file into the memory */
if (fread(g_file_buf, input_bmp_file_size, 1, fp) != 1)
{
fclose(fp);
printf("[ABM enc] read buffer error: %s\n", in_bmp_filename);
return ABM_ENC_RETURN_KEEP_ORIGINAL;
}
/* parse bitmap header */
if (parse_bitmap(g_file_buf, input_bmp_file_size) == ABM_ENC_INPUT_BITMAP_ERROR)
{
fclose(fp);
printf("[ABM enc] parse BMP error, %s\n", in_bmp_filename);
return ABM_ENC_RETURN_KEEP_ORIGINAL;
}
fclose(fp);
/* ABM encode */
*size = abmenc_encode(data);
/* return width and height */
w = abm_enc->bmp_width;
h = abm_enc->bmp_height;
*width = w;
*height = h;
/* calculate PBM size */
pbm_size = PBM_HEADER_SIZE + /* PBM header */
w * h * dev_bmp_bpp / 8; /* PBM pixel data */
/* choose ABM if the ABM size is smaller */
switch (image_type)
{
case IMAGE_TYPE_PNG:
return ABM_ENC_RETURN_USE_ABM;
break;
case IMAGE_TYPE_BMP:
if (*size <= input_bmp_file_size)
{
return ABM_ENC_RETURN_USE_ABM;
}
break;
default:
break;
}
return ABM_ENC_RETURN_KEEP_ORIGINAL;
}
/*-----------------------------------------------------------
* FUNCTION NAME: ABMLoader
* DESCRIPTION:
* get gif image data include mtk file header
* ARGUMENTS:
* char *in_filename:the file name include path
* U8 *out_data:outpur data
* U32 *data_len:output data length
* Return:
* 0:false 1:ok
* Note:
*
*------------------------------------------------------------*/
U8 ABMLoader(char *in_filename, U8 *out_data, U32 *data_len)
{
S32 width, height,ret;
U32 width_height,size;
mtk_file_header_t file_h;
U8 header_len;
ret = ABM_load(in_filename, MMI_DEVICE_BMP_FORMAT, IMAGE_TYPE_BMP, ABM_buffer, &size, &width, &height);
if( ABM_ENC_RETURN_USE_ABM != ret )
{
return 0;
}
if ((size >> 24) > 0)
{
printf("image is too big:%s\n", in_filename);
return 0;
}
width_height = (((U32)width & 0XFFF) << 12) | ((U32)height & 0XFFF);
file_h.file_type = IMAGE_TYPE_ABM;
file_h.frame_count = 0x01;
//image data len
file_h.file_len_low = (U8)(size & 0x000000ff);
file_h.file_len_mid = (U8)((size & 0x0000ff00) >> 8);
file_h.file_len_high = (U8)((size & 0x00ff0000) >> 16);
//image width and height
file_h.width_height_low = (U8)(width_height & 0x000000ff);
file_h.width_height_mid = (U8)((width_height & 0x0000ff00) >> 8);
file_h.width_height_high = (U8)((width_height & 0x00ff0000) >> 16);
header_len = sizeof(file_h);
memcpy(out_data, &file_h, header_len);
memcpy(&out_data[header_len], ABM_buffer, size);
*data_len = size + header_len;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -