framebuffer下bmp格式图片

/* * ===================================================================================== * * Filename: digital_frame.c * * Description: framebuffer下用libjeg库显示jpeg图片 * * Version: 1.0 * Created: 2011年03月21日 14时01分21秒 * Revision: none * Compiler: gcc * * Author: sunsea1026@gmail.com * * ===================================================================================== */#include #include #include #include #include #include #include #include #include #include #define FB_DEV "/dev/fb0"#define JPEG 0x001#define PNG 0x010#define BMP 0x100#define UNKNOWN 0x111static int fb_dev;static struct fb_var_screeninfo fb_var;static int screen_w, screen_h, screen_bits;static void *fbmem, *data;static FILE *infile;//JPEG的内容typedef struct jpeg_color{unsigned char r;unsigned char g;unsigned char b;}COLOR;;typedef struct jpeg_pixel_t{unsigned char r;unsigned char g;unsigned char b;unsigned char a;}PIXEL_T;//BMP的内容typedef struct bmp_file_header{char cfType[2]; //文件类型,必须为“BM”(0x4D42)char cfSize[4]; //文件的大小(字节)char cfReserved[4]; //保留,必须为0char cfoffBits[4]; //位图阵列相对与文件头的偏移量(字节)}__attribute__((packed)) BITMAPFILEHEADER; //文件头结构typedef struct bmp_info_header{char ciSize[4]; //sizeof of BITMAPINFOHEADERchar ciWidth[4]; //位图宽度(像素)char ciHeight[4]; //位图高度(像素)char ciPlanes[2]; //目标设备的位平面数,必须置为1char ciBitCount[2]; //每个像素的位数,1,4,8或24char ciCompress[4]; //位图阵列的压缩方法,0=不压缩char ciSizeImage[4]; //图像大小(字节)char ciXPelsPerMeter[4]; //目标设备水平每米像素个数char ciYPelsPerMeter[4]; //目标设备垂直每米像素个数char ciClrUsed[4]; //位图实际使用的颜色表的颜色数char ciClrImportant[4]; //重要颜色索引的个数}__attribute__((packed)) BITMAPINFOHEADER; //位图信息头结构//初始化fb0void fb_init(){//打开fb0设备文件fb_dev = open(FB_DEV, O_RDWR);if(fb_dev < 0){printf("Error:open %s error/n", FB_DEV); printf("Usage:[sudo ./digital_frame xxx.jpg]/n"); exit(1);}//获取fb0参数ioctl(fb_dev, FBIOGET_VSCREENINFO, &fb_var);screen_w = fb_var.xres;screen_h = fb_var.yres;screen_bits = fb_var.bits_per_pixel;printf("Framebuffer:%d * %d/n", screen_w, screen_h); printf("screen_bits:%d/n", screen_bits);fbmem = mmap(0, screen_w * screen_h * screen_bits / 8, PROT_READ | PROT_WRITE, MAP_SHARED, fb_dev, 0);return;}//判断图片格式int judge_picture_mode(char **argv){char header[8];printf("picture = %s/n", argv[1]); infile = fopen(argv[1], "rb");if(infile == NULL){printf("Error:open %s error!/n", argv[1]); exit(1);} memset(header, 0, sizeof(header));fread(&header, 8, 1, infile);fseek(infile, -8, 1);if((unsigned char)header[0] == 0xff){return JPEG;}else if((unsigned char)header[0] == 0x89){return PNG;}else if(0 == strncmp(header, "BM", 2)){return BMP;}else{return UNKNOWN;}}//显示jpg/jpeg格式图片void display_jpeg(){struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;int picture_w, picture_h, picture_bits;int i, j, x, y;unsigned char *buffer, *tmpbuf;COLOR picture_color;PIXEL_T **fbp;fbp = (PIXEL_T **)malloc(sizeof(PIXEL_T *) * screen_w);//x, y 代表图片的起始坐标for(i = 0, x = 400 * screen_bits / 8, y = 200; i < screen_w; i++){fbp[i] = (PIXEL_T *)(fbmem + (y + i) * screen_w * screen_bits / 8 + x);}cinfo.err = jpeg_std_error(&jerr);jpeg_create_decompress(&cinfo);//指定要解压缩的图像文件jpeg_stdio_src(&cinfo, infile);//获取图像信息 jpeg_read_header(&cinfo, TRUE);//开始解压jpeg_start_decompress(&cinfo);picture_w = cinfo.output_width;picture_h = cinfo.output_height;picture_bits = cinfo.output_components;/* printf("picture info:/n");printf("width = %d/n", picture_w);printf("height = %d/n", picture_h); printf("bits = %d/n", picture_bits); *///获取颜色值buffer = (unsigned char *)malloc(picture_w * picture_bits);memset(buffer, 0, picture_w * picture_bits);for(i = 0; i < picture_h; i++){tmpbuf = buffer;jpeg_read_scanlines(&cinfo, &tmpbuf, 1);for(j = 0; j < picture_w; j++){memcpy(&picture_color, tmpbuf, sizeof(picture_color));fbp[i][j].b = picture_color.r;fbp[i][j].g = picture_color.g;fbp[i][j].r = picture_color.b;tmpbuf += picture_bits;}}//完成解压jpeg_finish_decompress(&cinfo);//释放解压对象jpeg_destroy_decompress(&cinfo);free(buffer);return;}//显示png图片void display_png(){/* png_structp png_ptr;png_infop info_ptr;int picture_w, picture_h, picture_color_type;png_ptr = create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);info_ptr = png_create_info_struct(png_ptr);setjmp(png_jmpbuf(png_ptr));png_init_io(png_ptr, infile);png_read_png(png_ptr, info_ptr, PNG_TRANSFROM_EXPAND, 0);picture_w = png_get_image_width(PngPtr, InfoPtr);picture_h = png_get_image_height(PngPtr, InfoPtr);picture_color_type = png_get_image_color_type(PngPtr, InfoPtr);printf("picture info:/n"); printf("width = %d/n", picture_w);printf("height = %d/n", picture_h);printf("color_type = %d/n", picture_color_type); */return;}//chartolonglong chartolong(char *string, int length){long number;if(length <= 4){memset(&number, 0, sizeof(long));memcpy(&number, string, length);}return number;}//显示bmp格式图片void display_bmp(){BITMAPFILEHEADER FileHead;BITMAPINFOHEADER InfoHead;int rc ,i ,j, x, y;int ciWidth, ciHeight, ciBitCount;long int BytesPerLine = 0;COLOR picture_color;PIXEL_T **fbp;unsigned char *buffer, *tmpbuf; //读位图文件头rc = fread(&FileHead, sizeof(BITMAPFILEHEADER), 1, infile);if(rc != 1){printf("Error:read bmp header error!/n"); fclose(infile);exit(1);} //判断位图的类型if(memcmp(FileHead.cfType, "BM", 2) != 0){printf("This is not a bmp picture!/n"); fclose(infile);exit(1);} //读取位图信息头rc = fread((char *)&InfoHead, sizeof(BITMAPINFOHEADER), 1, infile);if(rc != 1){printf("Error:read bmp infoheader error!/n"); fclose(infile);exit(1);}ciWidth = (int)chartolong(InfoHead.ciWidth, 4);ciHeight = (int)chartolong(InfoHead.ciHeight, 4);ciBitCount = (int)chartolong(InfoHead.ciBitCount, 4);fseek(infile, (int)chartolong(FileHead.cfoffBits, 4), SEEK_SET);BytesPerLine = (ciWidth * ciBitCount + 31) / 32 * 4;/* printf("bmp info/n"); printf("width = %d/n", ciWidth); printf("height = %d/n", ciHeight); printf("bit = %d/n", ciBitCount); */fbp = (PIXEL_T **)malloc(sizeof(PIXEL_T *) * screen_w);for(i = 0, x = 0 * screen_bits / 8, y = 0; i < screen_w; i++){fbp[i] = (PIXEL_T *)(fbmem + (y + i) * screen_w * screen_bits / 8 + x);} buffer = (unsigned char *)malloc(BytesPerLine);memset(buffer, 0, BytesPerLine);for(i = ciHeight - 1; i >= 0; i--){tmpbuf = buffer;rc = fread(tmpbuf, BytesPerLine, 1, infile);for(j = 0; j < ciWidth; j++){memcpy(&picture_color, tmpbuf, ciBitCount / 8);fbp[i][j].r = picture_color.r;fbp[i][j].g = picture_color.g;fbp[i][j].b = picture_color.b;tmpbuf += ciBitCount / 8;}}return;}int main(int argc, char* argv[]){int picture_mode;if(argc != 2){printf("Usage:[sudo ./digital_frame xxx.jpg]/n"); exit(1);}//fb0初始化fb_init();//判断图片格式picture_mode = judge_picture_mode(argv);switch(picture_mode){case JPEG:printf("JPEG/JPG/n"); display_jpeg();break;case PNG:printf("PNG/n"); display_png();break;case BMP:printf("bmp/n"); display_bmp();break;case UNKNOWN:printf("UNKNOWN/n"); break;default:break;}fclose(infile);return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值