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

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: 嵌入式

2011-05-04 13:04:17

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


 对照着  使用libjpeg显示JPEG图像在framebuffer 测试(八)  这个代码,自己敲了一遍,这样理解就更快了,对其中的代码进行的注释。实现一样的功能

代码附件:
 jpeg-press-self.rar  
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <linux/fb.h>
  5. #include <sys/types.h>
  6. #include <sys/mman.h>
  7. #include <sys/stat.h>
  8. #include <jpeglib.h>
  9. #include <jerror.h>

  10. #define FB_DEV "/dev/fb0"

  11. void usage(char *msg);
  12. unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue);
  13. int     fb_open(char *fb_device);
  14. int     fb_close(int fd);
  15. int     fb_stat(int fd,int *width,int *height,int *depth);
  16. void     *fb_mmap(int fd,unsigned screensize);
  17. int fb_munmap(void *start,size_t length);
  18. int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color);


  19. int main(int argc,char *argv[])
  20. {
  21.     struct jpeg_decompress_struct cinfo; //解码结构体
  22.     struct jpeg_error_mgr jerr;
  23.     FILE     *infile;
  24.     unsigned char *buffer;

  25.     FBDEV *fr_dev;
  26.     int fbdev; //fbdev=open("/dev/fb0");
  27.     char *fb_device; //fb_device=getenv("FRAMEBUFFER");取得FRAMEBUFFER环境变量
  28.     unsigned char *fbmem;
  29.     unsigned int screensize;
  30.     unsigned int fb_width;
  31.     unsigned int fb_height;
  32.     unsigned int fb_depth;
  33.     unsigned int x;
  34.     unsigned int y;

  35.     if (argc!=2) //输入一个变量
  36.     {
  37.         usage("insuffient auguments");
  38.         exit(-1);
  39.     }

  40.     init_framebuffer(&fr_dev);

  41.     if((fb_device=getenv("FRAMEBUFFER"))==NULL) //打开 /dev/fb0 缓冲帧
  42.         fb_device=FB_DEV;//="/dev/fb0"
  43.     fbdev=fb_open(fb_device);

  44.     fb_stat(fbdev,&fb_width,&fb_height,&fb_depth); //获取 LCD 可变/固定参数

  45.     screensize=fb_width*fb_height*fb_depth/8;
  46.  
  47.     fbmem=fb_mmap(fbdev,screensize); //映射地址


  48.     if((infile=fopen(argv[1],"rb"))==NULL) //打开 解码图片
  49.     {
  50.         fprintf(stderr,"open %s failed \n",argv[1]);
  51.         exit(-1);
  52.     }
  53.     
  54.     cinfo.err=jpeg_std_error(&jerr); //设置 错误处理
  55.     jpeg_create_decompress(&cinfo); //初始化 解码 结构体
  56.     jpeg_stdio_src(&cinfo,infile); //输入 解码 图片
  57.     jpeg_read_header(&cinfo,TRUE); //读 jpeg 头
  58.     jpeg_start_decompress(&cinfo); //开始 解码
  59.         
  60.     if((cinfo.output_width>fb_width)||(cinfo.output_height>fb_height)) //判断图片大小
  61.     {
  62.         printf("too large JPEG file,cannot display\n");
  63.         return -1;
  64.     }

  65.     buffer=(unsigned char *)malloc(cinfo.output_width*cinfo.output_components);
  66.     y=0;
  67.     while(cinfo.output_scanline<cinfo.output_height)
  68.     {
  69.         jpeg_read_scanlines(&cinfo,&buffer,1);
  70.         if(fb_depth==16)
  71.         {
  72.             unsigned short color;
  73.             for(x=0;x<cinfo.output_width;x++)
  74.             {
  75.                 color=RGB888_to_RGB565(buffer[3*x],buffer[3*x+1],buffer[3*x+2]);
  76.                 fb_pixel(fbmem,fb_width,fb_height,x,y,color);
  77.             }
  78.         }
  79.         else if(fb_depth==24)
  80.         {
  81.             memcpy((unsigned char *)fbmem+y*fb_width*3,buffer,cinfo.output_width*cinfo.output_components);
  82.             
  83.         }

  84.         y++; //next scanline
  85.     }
  86.     
  87.     jpeg_finish_decompress(&cinfo);
  88.     jpeg_destroy_decompress(&cinfo);
  89.     free(buffer);
  90.     fclose(infile);

  91.     fb_munmap(fbmem,screensize);
  92.     fb_close(fbdev);
  93.     
  94.     return 0;
  95. }


  96. int fb_stat(int fb,int *width,int *height,int *depth)
  97. {
  98.     struct fb_fix_screeninfo fb_finfo;
  99.     struct fb_var_screeninfo fb_vinfo;
  100.     if(ioctl(fb,FBIOGET_FSCREENINFO,&fb_finfo))
  101.     {
  102.         perror(__func__);
  103.         return (-1);
  104.     }

  105.     if(ioctl(fb,FBIOGET_VSCREENINFO,&fb_vinfo))
  106.     {
  107.         perror(__func__);
  108.         return (-1);
  109.     }

  110.     *width=fb_vinfo.xres;
  111.     *height=fb_vinfo.yres;
  112.     *depth=fb_vinfo.bits_per_pixel;
  113.     return 0;
  114. }

  115. void *fb_mmap(int fb,unsigned int screensize)
  116. {
  117.     caddr_t fbmem; //typedef void *caddr_t;
  118.     if((fbmem=mmap(NULL,screensize,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0))==MAP_FAILED)
  119.     {
  120.         perror(__func__);
  121.         return (void *)(-1);
  122.     }
  123.     return (fbmem);
  124. }

  125. void usage(char *msg)
  126. {
  127.     fprintf(stderr,"%s\n",msg);
  128.     printf("Usage:fv some-jpeg-filee.jpg\n");
  129. }

  130. unsigned short RGB888_to_RGB565(unsigned char red,unsigned char green,unsigned char blue)
  131. {
  132.     unsigned short B= (blue>>3)&0x001F;
  133.     unsigned short G= ((green>>2)<<5)&0x07E0;
  134.     unsigned short R= ((red>>3)<<11)&0xF800;
  135.     return (unsigned short)(R|G|B);
  136. }

  137. int fb_open(char *fb_device)
  138. {
  139.     int fb;    
  140.     if((fb=open(fb_device,O_RDWR))<0)
  141.     {
  142.         perror(__func__);
  143.         return -1;
  144.     }
  145.     return fb;
  146. }

  147. int fb_munmap(void *start,size_t length)
  148. {
  149.     return (munmap(start,length));
  150. }


  151. int fb_close(int fb)
  152. {
  153.     return(close(fb));
  154. }

  155. int fb_pixel(void *fbmem,int width,int height,int x,int y,unsigned short color)
  156. {
  157.     if((x>width)||(y>height))
  158.         return -1;

  159.     unsigned short *dst=((unsigned short *)fbmem+y*width+x);
  160.     *dst=color;
  161.     return 0;
  162. }
阅读(1888) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~