lcd螢幕顯示jpeg圖片,其中lcd每個畫素佔據4位元組

小城熊儿發表於2024-08-20
// 編譯
// arm-openwrt-linux-muslgnueabi-gcc -o 17_safe_lcd_camera_test ./jpeg_show.c    -L./lib/ -ljpeg -I./include/


#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <setjmp.h>
#include <stdint.h>
#include <string.h>

// 錯誤處理結構體
struct my_error_mgr {
    struct jpeg_error_mgr pub;  // "public" fields
    jmp_buf setjmp_buffer;      // For return to caller
};
// 錯誤處理函式
void my_error_exit(j_common_ptr cinfo) {
    struct my_error_mgr * myerr = (struct my_error_mgr *)cinfo->err;
    longjmp(myerr->setjmp_buffer, 1);
}
// 解析 JPEG 資料並轉換為 BGRA 格式 // width height 為螢幕寬度和高度
int decode_jpeg_to_bgra(uint8_t* jpeg_data, size_t jpeg_size, int width, int height, unsigned char* bgra_data) {
    struct jpeg_decompress_struct cinfo;
    struct my_error_mgr jerr;
    JSAMPARRAY buffer;
    int row_stride;

    // 設定錯誤處理
    cinfo.err = jpeg_std_error(&jerr.pub);
    jerr.pub.error_exit = my_error_exit;
    if (setjmp(jerr.setjmp_buffer)) {
        jpeg_destroy_decompress(&cinfo);
        return -1;
    }

    // 初始化解壓縮物件
    jpeg_create_decompress(&cinfo);

    // 指定輸入資料
    jpeg_mem_src(&cinfo, jpeg_data, jpeg_size);

    // 讀取 JPEG 檔案頭
    jpeg_read_header(&cinfo, TRUE);

    // 開始解壓縮
    jpeg_start_decompress(&cinfo);

    row_stride = cinfo.output_width * cinfo.output_components;



    // 處理每一行資料
    buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
    for (int row = 0; row < cinfo.output_height; row++) {
        jpeg_read_scanlines(&cinfo, buffer, 1);

        for (int col = 0; col < cinfo.output_width; col++) {
            uint8_t r = buffer[0][col * cinfo.output_components + 0];
            uint8_t g = buffer[0][col * cinfo.output_components + 1];
            uint8_t b = buffer[0][col * cinfo.output_components + 2];
            uint8_t a = 255; // Alpha channel, set to 255 (opaque)

            int offset = (row * width + col) * 4;
            bgra_data[offset + 0] = b;
            bgra_data[offset + 1] = g;
            bgra_data[offset + 2] = r;
            bgra_data[offset + 3] = a;
        }
    }

    // 完成解壓縮
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);

    return 0;
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>



unsigned char* lcd_init(int* w,int* h,int* bits_per_pixel)
{
    static unsigned char *lcd_mem_p = NULL; //儲存LCD屏對映到程序空間的首地址
    struct fb_var_screeninfo vinfo;
    struct fb_fix_screeninfo finfo;

    // "/dev/fb0";
    int lcd_fd = open("/dev/fb0", O_RDWR, 0);

    /*2. 獲取可變引數*/
    if (ioctl(lcd_fd, FBIOGET_VSCREENINFO, &vinfo)){return -2;}
    printf("螢幕X:%d   螢幕Y:%d  畫素位數:%d\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
    *w=vinfo.xres;
    *h=vinfo.yres;
    *bits_per_pixel=vinfo.bits_per_pixel;
    
    /*3. 獲取固定引數*/
    if (ioctl(lcd_fd, FBIOGET_FSCREENINFO, &finfo)){return -3;}
    printf("smem_len=%d Byte,line_length=%d Byte\n", finfo.smem_len, finfo.line_length);

    /*4. 對映LCD屏實體地址到程序空間*/
    lcd_mem_p = (unsigned char *)mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0); //從檔案的那個地方開始對映
    memset(lcd_mem_p, 0xFFFFFF, finfo.smem_len);//白屏
    printf("對映LCD屏實體地址到程序空間\n");
    return lcd_mem_p;
}

int main(int argc, char **argv) {

    printf("usage:\n\t%s xxx.jpg\n\n",argv[0]);

    FILE *jpeg_file;
    if(argc==2){
        // strcpy(dev_video,argv[1]);
        jpeg_file = fopen(argv[1], "rb");
        printf(argv[1]);
        printf("\n");
    }
    else{
        jpeg_file = fopen("/mnt/UDISK/mjpeg_4.jpg", "rb");
    }
    


    // jpeg_file = fopen("/mnt/UDISK/mjpeg_4.jpg", "rb");
    if (!jpeg_file) {
        perror("Failed to open file");
        return 1;
    }

    int screen_w=0;//螢幕寬度
    int screen_h=0;//螢幕高度
    int screen_bits=0;//螢幕每個畫素佔據多少個bit位
    unsigned char* bgra_data=lcd_init(&screen_w,&screen_h,&screen_bits);
    

    // 獲取檔案大小
    fseek(jpeg_file, 0, SEEK_END);
    long file_size = ftell(jpeg_file);
    fseek(jpeg_file, 0, SEEK_SET);

    // 讀取 JPEG 資料
    uint8_t *jpeg_data = (uint8_t*)malloc(file_size);
    if (!jpeg_data) {
        perror("Failed to allocate memory");
        fclose(jpeg_file);
        return 1;
    }
    fread(jpeg_data, 1, file_size, jpeg_file);
    fclose(jpeg_file);

    decode_jpeg_to_bgra(jpeg_data, file_size, screen_w, screen_h,bgra_data);
    free(jpeg_data);

    return 0;
}

//

相關文章