⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abmloader.cpp

📁 在MTK平台上开放的一个皮肤工具,可以支持jpg、bmp、png图片
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    return file_size;
}


/*****************************************************************************
 * FUNCTION
 *  parse_bitmap
 * DESCRIPTION
 *  parse and verify the bitmap header (BITMAPFILEHEADER and BITMAPINFO)
 * PARAMETERS
 *  bitmap_p       [IN]
 * RETURNS
 *  void
 *****************************************************************************/
static S32 parse_bitmap(U8* bmp_data_p, U32 input_bmp_file_size)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    U32     bmp_w, bmp_h, bmp_bpp;
    S32     i;
    U32     bi_size;

    U32     line_size;

    U8      *pal_color_p;

    mycolor pal_first_color;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* check the "BM" magic number */
    if ((bmp_data_p[0] != 'B') || (bmp_data_p[1] != 'M'))
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* verify the bitmap file size */
    if (GET_32(bmp_data_p + 2) != input_bmp_file_size)
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* verify the BITMAPINFO HEADER size field */
    bi_size = GET_32(bmp_data_p + 14);
    if (bi_size < BITMAPINFO_HEADER_SIZE)
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* get bitmap width, height, and bits per pixel */
    bmp_w = GET_32(bmp_data_p + 18);
    bmp_h = GET_32(bmp_data_p + 22);
    bmp_bpp = GET_16(bmp_data_p + 28);

    /* only support 8, 24, and 32 bpp */
    if ((bmp_bpp != 8) && (bmp_bpp != 24) && (bmp_bpp != 32))
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* only support bottom-up bitmap */
    if (((S32)bmp_h <= 0) || ((S32)bmp_w <= 0))
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* limit image dimension to 1024x1024 */
    if (((S32)bmp_h > 1024) || ((S32)bmp_w > 1024))
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* get the palette color num */
    if (bmp_bpp == 8)
    {
        abm_enc->bmp_palette_num = GET_32(bmp_data_p + 46);
        if (abm_enc->bmp_palette_num == 0)
        {
            abm_enc->bmp_palette_num = 256;
        }
    }
    else
    {
        abm_enc->bmp_palette_num = 0;
    }

    /* make sure palette color number is 256 maximally */
    if (abm_enc->bmp_palette_num > 256)
    {
        return ABM_ENC_INPUT_BITMAP_ERROR;
    }

    /* line size in bytes */
    line_size = bmp_bpp * bmp_w / 8;

    abm_enc->line_padding_bytes = (line_size + 3) / 4 * 4 - line_size;

    abm_enc->bmp_width = bmp_w;
    abm_enc->bmp_height = bmp_h;
    abm_enc->bmp_bpp = bmp_bpp;

    /* get palette */
    pal_color_p = bmp_data_p + BITMAPFILEHEADER_SIZE + bi_size;
    pal_first_color = GET_32(pal_color_p);

    for (i = 0; i < abm_enc->bmp_palette_num; i++)
    {
        abm_enc->bmp_palette[i] = GET_32(pal_color_p + i * 4);

        /* A of ARGB quad is reserved as 0, convert it to opacity 255 */
        if (abm_enc->src_key_color_enable && (abm_enc->bmp_palette[i] == pal_first_color))
        {   
            /* 
             * The transparency color is the first color in the palette.
             * Any equivalent color is also the transpareny color.
             *
             * ONLY VALID FOR PBM AND BMP FILES.
             */
            abm_enc->bmp_palette[i] = 0;    /* force alpha value 0 */
        }
        else
        {
            abm_enc->bmp_palette[i] |= 0xFF000000; /* opaque color, alpha value 255 */
        }
    }

    /* bitmap pixel start offset */
    abm_enc->bmp_pixel_start_p = bmp_data_p + GET_32(bmp_data_p + 10);

    return ABM_ENC_OK;
}


/*****************************************************************************
 * FUNCTION
 *  update_image_bounding_box
 * DESCRIPTION
 *  update image bounding box (piggy-back in the first pass)
 * PARAMETERS
 *  x       [IN] x coordinate of non-transparent color
 *  y       [IN] y coordinate of non-transparent color
 * RETURNS
 *  void
 *****************************************************************************/
static void update_image_bounding_box(S32 x, S32 y)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    S32     x1, x2, y1, y2;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    x1 = abm_enc->x1;
    y1 = abm_enc->y1;
    x2 = abm_enc->x2;
    y2 = abm_enc->y2;

    /* x1 = min(x of non-transparent color) */
    if (x < x1)
    {
        x1 = x;
    }

    /* y1 = min(y of non-transparent color) */
    if (y < y1)
    {
        y1 = y;
    }

    /* x2 = max(x of non-transparent color) */
    if (x > x2)
    {
        x2 = x;
    }

    /* y2 = max(y of non-transparent color) */
    if (y > y2)
    {
        y2 = y;
    }

    abm_enc->x1 = x1;
    abm_enc->y1 = y1;
    abm_enc->x2 = x2;
    abm_enc->y2 = y2;
}


/*****************************************************************************
 * FUNCTION
 *  limit_image_bounding_box
 * DESCRIPTION
 *  limit the x1, y1, x2, and y2 within 8-bit
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
static void limit_image_bounding_box(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    S32     w, h, bottom_right_off_w, bottom_right_off_h;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    w = abm_enc->bmp_width;
    h = abm_enc->bmp_height;

    if (abm_enc->x1 > 255)
    {
        abm_enc->x1 = 255;
    }

    if (abm_enc->y1 > 255)
    {
        abm_enc->y1 = 255;
    }

    bottom_right_off_w = w - 1 - abm_enc->x2;
    if (bottom_right_off_w > 255)
    {
        abm_enc->x2 = w - 1 - bottom_right_off_w;
    }

    bottom_right_off_h = h - 1 - abm_enc->y2;
    if (bottom_right_off_h > 255)
    {
        abm_enc->y2 = h - 1 - bottom_right_off_h;
    }
}


/*****************************************************************************
 * FUNCTION
 *  abmenc_build_color_index_table
 * DESCRIPTION
 *  build the color index table (first pass)
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
static void abmenc_build_color_index_table(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    S32     x, y, w, h;
    S32     line_padding_bytes;
    U8      *pixel_p, *img_p;

    U32     bmp_bpp;
    mycolor c;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    w = abm_enc->bmp_width;
    h = abm_enc->bmp_height;
    line_padding_bytes = abm_enc->line_padding_bytes;
    bmp_bpp = abm_enc->bmp_bpp;
    img_p = abm_enc->bmp_pixel_start_p;    

    /* initialize image bounding box */
    abm_enc->x1 = w;
    abm_enc->y1 = h;
    abm_enc->x2 = 0;
    abm_enc->y2 = 0;

    /* first pass: build color index table and find the image bounding box */
    pixel_p = img_p;

    for (y = 0; y < h; y++)
    {
        for (x = 0; x < 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++];                
            }

            /* add color if the color is not transparent color */
            if (A_OF_ARGB8888(c) != 0)
            {               
                /* only add unique color */
                add_color_if_new(COLOR_REDUCE(c));

                /* update image bounding box (notice bitmap is flipped, so we have to invert y here) */
                update_image_bounding_box(x, h - 1 - y);
            }
        }
        
        pixel_p += line_padding_bytes;
    }

    limit_image_bounding_box();
    
    /* handle special case, all transparent color */
    if (abm_enc->x2 < abm_enc->x1)
    {
        abm_enc->x1 = 0;
        abm_enc->y1 = 0;
        abm_enc->x2 = 0;
        abm_enc->y2 = 0;
    }    
}


/*****************************************************************************
 * FUNCTION
 *  log2_ceiling
 * DESCRIPTION
 *  calculate ceiling(log2(x))
 * PARAMETERS
 *  x       [IN]    x must be in the range of [0, 65535]
 * RETURNS
 *  ceiling(log2(x))
 *****************************************************************************/
static U32 log2_ceiling(U32 x)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/   
    S32     i;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    for (i = 0; i < 15; i++)
    {
        if (x <= log2_table[i])
            break;
    }

    return i + 1;
}


/*****************************************************************************
 * FUNCTION
 *  abmenc_encode
 * DESCRIPTION
 *  abm encoder main routine
 * PARAMETERS
 *  out_mem_p       [OUT] output memory pointer
 * RETURNS
 *  ABM data size
 *****************************************************************************/
static U32 abmenc_encode(U8* out_mem_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    S32     x, y, w, h, bottom_right_off_w, bottom_right_off_h;
    S32     bound_box_w, bound_box_h;
    S32     line_padding_bytes;
    U8      *pixel_p, *img_p, *mem8_p;
    U32     p;
    U32     bpp;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -