本文的copyright归yuweixian4230@163.com 所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:yuweixian4230@163.com
博客:yuweixian4230.blog.chinaunix.net 程序实现了 在 通过 对 jpg图片进行 jpeg 解码,通过 framebuffer 显示在LCD 上
这是测试版本 v1.0 后续需要改进。
代码:
jpeg-framebuffer-v-1-0.rar - /***************************************************
-
* version-1.0 *
-
* *
-
* author : yuweixian *
-
* date : 2011.5.4 *
-
* http://blog.chinaunix.net/space.php?uid=22666248 *
-
* *
-
* function : 实现 jpeg解码,显示图片在LCD上 *
-
* *
-
* compile : arm-linux-gcc main.c -ljpeg -o main *
-
* *
-
* how to use : ./main xx.jpg *
-
***************************************************/
-
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <fcntl.h>
-
#include <linux/fb.h>
-
#include <sys/types.h>
-
#include <sys/mman.h>
-
#include <sys/stat.h>
-
#include <jpeglib.h>
-
#include <jerror.h>
-
-
/*
-
frame_dev :framebuffer 结构体
-
*/
-
typedef struct frame_dev{
-
int fdfd; //open "dev/fb0"
-
struct fb_var_screeninfo vinfo; //获取 可变参数
-
struct fb_fix_screeninfo finfo; //获取 固定参数
-
long int screensize; //LCD屏 整个占有空间大小 字节 单位
-
char *map_fb; // framebuffer 映射 首地址
-
-
}FRAME_DEV;
-
-
typedef struct jpeg_dev{
-
struct jpeg_decompress_struct cinfo; //解码 结构体
-
struct jpeg_error_mgr jerr; //错误处理 结构体
-
FILE *infile; // 打开 文件 infile=fopen("xx.jpg","rb");
-
unsigned char *buffer; //buffer=malloc();
-
}JPEG_DEV;
-
-
//初始化 framebuffer
-
void init_framebuffer(FRAME_DEV *dev);
-
-
//初始化 jpeg 解码
-
void init_jpeg(JPEG_DEV *dev);
-
-
//转换 RGB888 到 RGB565
-
unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue);
-
-
// 写 像素点
-
int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color);
-
-
//判断图片大小,如果图片太大,返回错误信息
-
int judge_large_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev);
-
-
//显示 图片在 LCD上
-
void dispaly_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev);
-
-
void close_jpeg(JPEG_DEV *jp_dev);
-
void close_framebuffer(FRAME_DEV *fr_dev);
-
-
-
int main(int argc,char *argv[])
-
{
-
FRAME_DEV frame_dev;
-
JPEG_DEV jpeg_dev;
-
int x=0,y=0;
-
-
init_framebuffer(&frame_dev); //初始化 framebuffer 设备
-
-
-
if((jpeg_dev.infile=fopen(argv[1],"rb"))==NULL) //打开 解码图片
-
{
-
fprintf(stderr,"open %s failed \n",argv[1]);
-
exit(-1);
-
}
-
-
init_jpeg(&jpeg_dev);
-
-
judge_large_picture(&frame_dev,&jpeg_dev); //if picture is too large ,return -1;
-
-
//申请 动态空间
-
jpeg_dev.buffer=(unsigned char *)malloc(jpeg_dev.cinfo.output_width*jpeg_dev.cinfo.output_components);
-
-
-
dispaly_picture(&frame_dev,&jpeg_dev);
-
-
close_jpeg(&jpeg_dev);
-
close_framebuffer(&frame_dev);
-
return 0;
-
}
-
-
void init_framebuffer(FRAME_DEV *dev)
-
{
-
FRAME_DEV *frame_dev=dev;
-
-
frame_dev->fdfd=open("/dev/fb0",O_RDWR); //打开 framebuffer
-
printf("the framebuffer device was opended successfully.\n");
-
-
ioctl(frame_dev->fdfd,FBIOGET_FSCREENINFO,&(frame_dev->finfo)); //获取 固定参数
-
-
ioctl(frame_dev->fdfd,FBIOGET_VSCREENINFO,&(frame_dev->vinfo)); //获取可变参数
-
-
// 320*240*16/8 LCD 占的内存大小
-
frame_dev->screensize=frame_dev->vinfo.xres*frame_dev->vinfo.yres*frame_dev->vinfo.bits_per_pixel/8;
-
-
// 映射 screensize 大小的数据 到 fdfd=/dev/fb0 映射 地址空间到 /dev/fb0
-
frame_dev->map_fb=(char *)mmap(NULL,frame_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,frame_dev->fdfd,0);
-
-
printf("init_dev successfully.\n");
-
}
-
-
void init_jpeg(JPEG_DEV *dev)
-
{
-
JPEG_DEV *jpeg_dev = dev;
-
-
jpeg_dev->cinfo.err=jpeg_std_error(&(jpeg_dev->jerr)); //设置 错误处理
-
jpeg_create_decompress(&(jpeg_dev->cinfo)); //初始化 解码 结构体
-
jpeg_stdio_src(&(jpeg_dev->cinfo),jpeg_dev->infile); //输入 解码 图片
-
jpeg_read_header(&(jpeg_dev->cinfo),TRUE); //读 jpeg 头
-
jpeg_start_decompress(&(jpeg_dev->cinfo)); //开始 解码
-
}
-
-
unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue)
-
{
-
unsigned short B= (blue>>3)&0x001F;
-
unsigned short G= ((green>>2)<<5)&0x07E0;
-
unsigned short R= ((red>>3)<<11)&0xF800;
-
return (unsigned short)(R|G|B);
-
}
-
-
int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color)
-
{
-
if((x>width)||(y>height))
-
return -1;
-
-
unsigned short *dst=((unsigned short *)fbmem+y*width+x);
-
*dst=color;
-
return 0;
-
}
-
-
int judge_large_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev) //判断图片大小,
-
{
-
FRAME_DEV *frame_dev=fr_dev;
-
JPEG_DEV *jpeg_dev=jp_dev;
-
-
if((jpeg_dev->cinfo.output_width>frame_dev->vinfo.xres)||(jpeg_dev->cinfo.output_height>frame_dev->vinfo.yres)) //判断图片大小
-
{
-
printf("too large JPEG file,cannot display\n");
-
return -1;
-
}
-
}
-
-
void dispaly_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev)
-
{
-
FRAME_DEV * frame_dev=fr_dev;
-
JPEG_DEV * jpeg_dev=jp_dev;
-
int x=0,y=0;
-
while(jpeg_dev->cinfo.output_scanline<jpeg_dev->cinfo.output_height) //扫描行,没有到 240,
-
{
-
/*一行一行放入内存,扫描,buffer 是动态申请的,行扫描头,将一行的数据头,放到 buffer中*/
-
jpeg_read_scanlines(&(jpeg_dev->cinfo),&jpeg_dev->buffer,1);
-
if(frame_dev->vinfo.bits_per_pixel==16) //假如我们的设备是 16bpp
-
{
-
unsigned short color;
-
for(x=0;x<jpeg_dev->cinfo.output_width;x++)
-
{ // x=0;x<320;x++
-
/* R G B 三种颜色*/
-
color=RGB888_to_RGB565(jpeg_dev->buffer[3*x],jpeg_dev->buffer[3*x+1],jpeg_dev->buffer[3*x+2]);
-
fb_pixel(frame_dev->map_fb,frame_dev->vinfo.xres,frame_dev->vinfo.yres,x,y,color);
-
}
-
}
-
-
y++; //next scanline
-
}
-
}
-
-
void close_jpeg(JPEG_DEV *jp_dev)
-
{
-
JPEG_DEV *jpeg_dev=jp_dev;
-
-
jpeg_finish_decompress(&(jpeg_dev->cinfo));
-
jpeg_destroy_decompress(&(jpeg_dev->cinfo));
-
free(jpeg_dev->buffer);
-
fclose(jpeg_dev->infile);
-
}
-
-
void close_framebuffer(FRAME_DEV *fr_dev)
-
{
-
FRAME_DEV *frame_dev = fr_dev;
-
-
munmap(frame_dev->map_fb,frame_dev->screensize);
-
close(frame_dev->fdfd);
-
}
阅读(1459) | 评论(0) | 转发(0) |