Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4471132
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: 嵌入式

2011-05-04 14:55:06

本文的copyright归yuweixian4230@163.com 所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:yuweixian4230@163.com
博客:
yuweixian4230.blog.chinaunix.net 


   程序实现了 在 通过 对 jpg图片进行 jpeg 解码,通过 framebuffer  显示在LCD 上
这是测试版本 v1.0 后续需要改进。
代码: jpeg-framebuffer-v-1-0.rar  

  1. /***************************************************
  2. * version-1.0                                      *
  3. *                                                  *
  4. * author : yuweixian                               *
  5. * date : 2011.5.4                                  *
  6. * http://blog.chinaunix.net/space.php?uid=22666248 *
  7. *                                                  *
  8. * function : 实现 jpeg解码,显示图片在LCD上           *
  9. *                                                  *
  10. * compile : arm-linux-gcc main.c -ljpeg -o main    *
  11. *                                                  *
  12. * how to use : ./main xx.jpg                       *
  13. ***************************************************/

  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <fcntl.h>
  17. #include <linux/fb.h>
  18. #include <sys/types.h>
  19. #include <sys/mman.h>
  20. #include <sys/stat.h>
  21. #include <jpeglib.h>
  22. #include <jerror.h>

  23. /*
  24.     frame_dev :framebuffer 结构体
  25. */
  26. typedef struct frame_dev{
  27.     int fdfd; //open "dev/fb0"
  28.     struct fb_var_screeninfo vinfo; //获取 可变参数
  29.     struct fb_fix_screeninfo finfo; //获取 固定参数
  30.     long int screensize; //LCD屏 整个占有空间大小 字节 单位
  31.     char *map_fb; // framebuffer 映射 首地址
  32.     
  33. }FRAME_DEV;

  34. typedef struct jpeg_dev{
  35.     struct jpeg_decompress_struct cinfo; //解码 结构体
  36.     struct jpeg_error_mgr jerr; //错误处理 结构体
  37.     FILE *infile; // 打开 文件 infile=fopen("xx.jpg","rb");
  38.     unsigned char *buffer; //buffer=malloc();
  39. }JPEG_DEV;

  40. //初始化 framebuffer
  41. void init_framebuffer(FRAME_DEV *dev);

  42. //初始化 jpeg 解码
  43. void init_jpeg(JPEG_DEV *dev);

  44. //转换 RGB888 到 RGB565
  45. unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue);

  46. // 写 像素点
  47. int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color);

  48.  //判断图片大小,如果图片太大,返回错误信息
  49. int judge_large_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev);

  50. //显示 图片在 LCD上
  51. void dispaly_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev);

  52. void close_jpeg(JPEG_DEV *jp_dev);
  53. void close_framebuffer(FRAME_DEV *fr_dev);


  54. int main(int argc,char *argv[])
  55. {
  56.     FRAME_DEV frame_dev;
  57.     JPEG_DEV jpeg_dev;
  58.     int x=0,y=0;
  59.     
  60.     init_framebuffer(&frame_dev); //初始化 framebuffer 设备
  61.     

  62.     if((jpeg_dev.infile=fopen(argv[1],"rb"))==NULL) //打开 解码图片
  63.     {
  64.         fprintf(stderr,"open %s failed \n",argv[1]);
  65.         exit(-1);
  66.     }

  67.     init_jpeg(&jpeg_dev);

  68.     judge_large_picture(&frame_dev,&jpeg_dev); //if picture is too large ,return -1;

  69.         //申请 动态空间
  70.     jpeg_dev.buffer=(unsigned char *)malloc(jpeg_dev.cinfo.output_width*jpeg_dev.cinfo.output_components);


  71.     dispaly_picture(&frame_dev,&jpeg_dev);

  72.     close_jpeg(&jpeg_dev);
  73.     close_framebuffer(&frame_dev);
  74.     return 0;
  75. }

  76. void init_framebuffer(FRAME_DEV *dev)
  77. {
  78.     FRAME_DEV *frame_dev=dev;

  79.     frame_dev->fdfd=open("/dev/fb0",O_RDWR); //打开 framebuffer
  80.     printf("the framebuffer device was opended successfully.\n");

  81.     ioctl(frame_dev->fdfd,FBIOGET_FSCREENINFO,&(frame_dev->finfo)); //获取 固定参数

  82.     ioctl(frame_dev->fdfd,FBIOGET_VSCREENINFO,&(frame_dev->vinfo)); //获取可变参数

  83.      // 320*240*16/8 LCD 占的内存大小
  84.     frame_dev->screensize=frame_dev->vinfo.xres*frame_dev->vinfo.yres*frame_dev->vinfo.bits_per_pixel/8;
  85.                     
  86.     // 映射 screensize 大小的数据 到 fdfd=/dev/fb0 映射 地址空间到 /dev/fb0    
  87.     frame_dev->map_fb=(char *)mmap(NULL,frame_dev->screensize,PROT_READ|PROT_WRITE,MAP_SHARED,frame_dev->fdfd,0);
  88.                                            
  89.     printf("init_dev successfully.\n");
  90. }

  91. void init_jpeg(JPEG_DEV *dev)
  92. {
  93.     JPEG_DEV *jpeg_dev = dev;

  94.     jpeg_dev->cinfo.err=jpeg_std_error(&(jpeg_dev->jerr)); //设置 错误处理
  95.     jpeg_create_decompress(&(jpeg_dev->cinfo)); //初始化 解码 结构体
  96.     jpeg_stdio_src(&(jpeg_dev->cinfo),jpeg_dev->infile); //输入 解码 图片
  97.     jpeg_read_header(&(jpeg_dev->cinfo),TRUE); //读 jpeg 头
  98.     jpeg_start_decompress(&(jpeg_dev->cinfo)); //开始 解码
  99. }

  100. unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue)
  101. {
  102.     unsigned short B= (blue>>3)&0x001F;
  103.     unsigned short G= ((green>>2)<<5)&0x07E0;
  104.     unsigned short R= ((red>>3)<<11)&0xF800;
  105.     return (unsigned short)(R|G|B);
  106. }

  107. int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color)
  108. {
  109.     if((x>width)||(y>height))
  110.         return -1;

  111.     unsigned short *dst=((unsigned short *)fbmem+y*width+x);
  112.     *dst=color;
  113.     return 0;
  114. }

  115. int judge_large_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev) //判断图片大小,
  116. {
  117.     FRAME_DEV *frame_dev=fr_dev;
  118.     JPEG_DEV *jpeg_dev=jp_dev;

  119.     if((jpeg_dev->cinfo.output_width>frame_dev->vinfo.xres)||(jpeg_dev->cinfo.output_height>frame_dev->vinfo.yres)) //判断图片大小
  120.     {
  121.         printf("too large JPEG file,cannot display\n");
  122.         return -1;
  123.     }
  124. }

  125. void dispaly_picture(FRAME_DEV *fr_dev,JPEG_DEV *jp_dev)
  126. {
  127.     FRAME_DEV * frame_dev=fr_dev;
  128.     JPEG_DEV * jpeg_dev=jp_dev;
  129.     int x=0,y=0;
  130.     while(jpeg_dev->cinfo.output_scanline<jpeg_dev->cinfo.output_height) //扫描行,没有到 240,
  131.     {
  132.         /*一行一行放入内存,扫描,buffer 是动态申请的,行扫描头,将一行的数据头,放到 buffer中*/
  133.         jpeg_read_scanlines(&(jpeg_dev->cinfo),&jpeg_dev->buffer,1);
  134.         if(frame_dev->vinfo.bits_per_pixel==16) //假如我们的设备是 16bpp
  135.         {
  136.             unsigned short color;
  137.             for(x=0;x<jpeg_dev->cinfo.output_width;x++)
  138.             { // x=0;x<320;x++
  139.                 /*                    R G B 三种颜色*/
  140.                 color=RGB888_to_RGB565(jpeg_dev->buffer[3*x],jpeg_dev->buffer[3*x+1],jpeg_dev->buffer[3*x+2]);
  141.                 fb_pixel(frame_dev->map_fb,frame_dev->vinfo.xres,frame_dev->vinfo.yres,x,y,color);
  142.             }
  143.         }

  144.         y++; //next scanline
  145.     }
  146. }

  147. void close_jpeg(JPEG_DEV *jp_dev)
  148. {
  149.     JPEG_DEV *jpeg_dev=jp_dev;
  150.     
  151.     jpeg_finish_decompress(&(jpeg_dev->cinfo));
  152.     jpeg_destroy_decompress(&(jpeg_dev->cinfo));
  153.     free(jpeg_dev->buffer);
  154.     fclose(jpeg_dev->infile);
  155. }

  156. void close_framebuffer(FRAME_DEV *fr_dev)
  157. {
  158.     FRAME_DEV *frame_dev = fr_dev;
  159.         
  160.     munmap(frame_dev->map_fb,frame_dev->screensize);
  161.     close(frame_dev->fdfd);
  162. }


阅读(1459) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~