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

📄 abmloader.cpp

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

#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 + -