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

📄 abmloader.cpp

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