2011年5月24日 星期二

BMP - RGB888ToRGB565

unsigned short int RGB888ToRGB565( unsigned int aPixel )
{
    int red   = ( aPixel >> 16) & 0xFF;
    int green = ( aPixel >> 8 ) & 0xFF;
    int blue  =   aPixel        & 0xFF;
   
    unsigned short  B =  (blue  >> 3)        & 0x001F;
    unsigned short  G = ((green >> 2) <<  5) & 0x07E0;
    unsigned short  R = ((red   >> 3) << 11) & 0xF800;

    return (unsigned short int) (R | G | B);
}
or
#define RGB565(R,G,B) (((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3))

ref: Here
==========================================
電腦預覽圖看不見,直接丟入img即可(amlogic8762: bootup & poweron)

#include <stdio.h>
#include <stdlib.h>

//#define DEBUG_ENV
#ifdef DEBUG_ENV
#define DEBUGF(fmt,args...) printf(fmt ,##args)
#define DEBUGMSG __FILE__, __LINE__, __FUNCTION__
#else
#define DEBUGF(fmt,args...)
#endif

#define RGB888to565(R,G,B) (((R >> 3) << 11) | ((G >> 2) << 5) | (B >> 3))

int T888to565(const char *fname_s, const char *fname_t)
{
    FILE          *fp_s = NULL;    // source file handler
    FILE          *fp_t = NULL;    // target file handler 
    unsigned int  x,y;             // for loop counter
    unsigned int  width, height;   // image width, image height
    unsigned char *image_s = NULL; // source image array
    unsigned char *image_t = NULL; // target image array
    //unsigned char R, G, B;         // color of R, G, B
    unsigned short R, G, B;         // color of R, G, B
    unsigned int y_avg;            // average of y axle
    unsigned int y_t;              // target of y axle
    unsigned short rgb=0, rgb_h=0;  //rgb_h, only hight byte

    unsigned char header[54] = {
        0x42,        // identity : B        //00h
        0x4d,        // identity : M
        0, 0, 0, 0,  // file size           //02h
        0, 0,        // reserved1           //06h
        0, 0,        // reserved2           //08h
        54, 0, 0, 0, // RGB data offset     //0Ah
        40, 0, 0, 0, // struct BITMAPINFOHEADER size    //0Eh
        0, 0, 0, 0,  // bmp width           //12h
        0, 0, 0, 0,  // bmp height          //16h
        1, 0,        // planes              //1Ah
        16, 0,       // bit per pixel       //1Ch
        3, 0, 0, 0,  // compression         //1Eh
        0, 0, 0, 0,  // data size           //22h
        0, 0, 0, 0,  // h resolution        //26h
        0, 0, 0, 0,  // v resolution        //2Ah
        0, 0, 0, 0,  // used colors         //2Eh
        0, 0, 0, 0   // important colors    //32h
    };

    unsigned int file_size;           // file size
    unsigned int rgb_raw_data_offset; // RGB raw data offset

    fp_s = fopen(fname_s, "rb");
    if (fp_s == NULL)
    {
        printf("fopen fp_s error\n");
        return -1;
    }

    // move offset to 10 to find rgb raw data offset
    fseek(fp_s, 10, SEEK_SET);
    fread(&rgb_raw_data_offset, sizeof(unsigned int), 1, fp_s);
    // move offset to 18    to get width & height;
    fseek(fp_s, 18, SEEK_SET);
    fread(&width,  sizeof(unsigned int), 1, fp_s);
    fread(&height, sizeof(unsigned int), 1, fp_s);
    // move offset to rgb_raw_data_offset to get RGB raw data
    fseek(fp_s, rgb_raw_data_offset, SEEK_SET);

    image_s = (unsigned char *)malloc((size_t)width * height * 3);
    if (image_s == NULL)
    {
        printf("malloc images_s error\n");
        return -1;
    }

    image_t = (unsigned char *)malloc((size_t)width * height * 2);
    if (image_t == NULL)
    {
        printf("malloc image_t error\n");
        return -1;
    }

    fread(image_s, sizeof(unsigned char), (size_t)(long)width * height * 3, fp_s);

    //RGB888 -> RGB565
    for(y = 0; y != height; ++y)
    {
        for(x = 0; x != width; ++x)
        {
            #if 1   //Good performence
            R = (((*(image_s + 3 * (width * y + x) + 2)) >>3)<<11) & 0xF800;
            G = (((*(image_s + 3 * (width * y + x) + 1)) >>2)<<5 ) & 0x07E0;
            B =  ((*(image_s + 3 * (width * y + x) + 0)) >>3)      & 0x001F;
            rgb=(B|G|R);
            #else
            R = *(image_s + 3 * (width * y + x) + 2);
            G = *(image_s + 3 * (width * y + x) + 1);
            B = *(image_s + 3 * (width * y + x) + 0);
            rgb=RGB888to565(R,G,B);
            #endif
            DEBUGF("R=0x%x, G=0x%x, B=0x%x ",R,G,B);
            DEBUGF("rgb=0x%x\n",rgb);
            rgb_h=rgb>>8;
            DEBUGF("rgb_h=0x%x  rgb=0x%x\n",rgb_h, (unsigned char )rgb);
            *(image_t + 2 * (width * y + x) + 1) = (unsigned char)rgb_h;
            *(image_t + 2 * (width * y + x) + 0) = (unsigned char)rgb;
        }
    }

    // write to new bmp
    fp_t = fopen(fname_t, "wb");
    if (fp_t == NULL)
    {
        printf("fopen fname_t error\n");
        return -1;
    }

    // file size  
    file_size = width * height * 2 + rgb_raw_data_offset;
    header[2] = (unsigned char)(file_size & 0x000000ff);
    header[3] = (file_size >> 8)  & 0x000000ff;
    header[4] = (file_size >> 16) & 0x000000ff;
    header[5] = (file_size >> 24) & 0x000000ff;
    // width
    header[18] = width & 0x000000ff;
    header[19] = (width >> 8)  & 0x000000ff;
    header[20] = (width >> 16) & 0x000000ff;
    header[21] = (width >> 24) & 0x000000ff;

    // height
    header[22] = height &0x000000ff;
    header[23] = (height >> 8)  & 0x000000ff;
    header[24] = (height >> 16) & 0x000000ff;
    header[25] = (height >> 24) & 0x000000ff;

    // write header
    fwrite(header, sizeof(unsigned char), rgb_raw_data_offset, fp_t);
    // write image
    fwrite(image_t, sizeof(unsigned char), (size_t)(long)width * height * 2, fp_t);

    fclose(fp_s);
    fclose(fp_t);

    return 0;
}

int main(void)
{
    if((T888to565("logo.bmp", "transfer.bmp"))<=-1)
        printf("error\n");
    return 0;
}
ref: 真OO無雙之真亂舞

沒有留言:

張貼留言