/*
* =====================================================================================
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <unistd.h>
#include <jpeglib.h>
#define FB_DEV "/dev/fb0"
#define JPEG 0x001
#define PNG 0x010
#define BMP 0x100
#define UNKNOWN 0x111
static 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;
typedef struct color
{
unsigned char r;
unsigned char g;
unsigned char b;
}COLOR;;
typedef struct pixel_t
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
}PIXEL_T;
//初始化fb0
void 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 = 0 * screen_bits / 8, y = 0; 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;
}
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");
break;
case BMP:
printf("bmp/n");
break;
case UNKNOWN:
printf("UNKNOWN/n");
break;
default:
break;
}
return 0;
}
* =====================================================================================
*
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <unistd.h>
#include <jpeglib.h>
#define FB_DEV "/dev/fb0"
#define JPEG 0x001
#define PNG 0x010
#define BMP 0x100
#define UNKNOWN 0x111
static 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;
typedef struct color
{
unsigned char r;
unsigned char g;
unsigned char b;
}COLOR;;
typedef struct pixel_t
{
unsigned char r;
unsigned char g;
unsigned char b;
unsigned char a;
}PIXEL_T;
//初始化fb0
void 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 = 0 * screen_bits / 8, y = 0; 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;
}
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");
break;
case BMP:
printf("bmp/n");
break;
case UNKNOWN:
printf("UNKNOWN/n");
break;
default:
break;
}
return 0;
}