免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3282 | 回复: 1
打印 上一主题 下一主题

在Linux控制台下显示JPEG图像 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-29 11:59 |只看该作者 |倒序浏览

  1. /*
  2. * $Id: fv.c
  3. * $Desp: draw jpeg to framebuffer
  4. * $Author: rockins
  5. * $Date: Wed Jan  3 20:15:49 CST 2007
  6. */

  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <fcntl.h>
  10. #include <linux/fb.h>
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <sys/mman.h>
  14. #include <jpeglib.h>
  15. #include <jerror.h>

  16. #define        FB_DEV        "/dev/fb0"

  17. /***************** function declaration ******************/
  18. void            usage(char *msg);
  19. unsigned short  RGB888toRGB565(unsigned char red,
  20.                                                            unsigned char green, unsigned char blue);
  21. int             fb_open(char *fb_device);
  22. int             fb_close(int fd);
  23. int             fb_stat(int fd, int *width, int *height, int *depth);
  24. void           *fb_mmap(int fd, unsigned int screensize);
  25. int             fb_munmap(void *start, size_t length);
  26. int             fb_pixel(void *fbmem, int width, int height,
  27.                                                  int x, int y, unsigned short color);

  28. /************ function implementation ********************/
  29. int
  30. main(int argc, char *argv[])
  31. {
  32.         /*
  33.          * declaration for jpeg decompression
  34.          */
  35.         struct jpeg_decompress_struct cinfo;
  36.         struct jpeg_error_mgr jerr;
  37.         FILE           *infile;
  38.         unsigned char  *buffer;

  39.         /*
  40.          * declaration for framebuffer device
  41.          */
  42.         int             fbdev;
  43.         char           *fb_device;
  44.         unsigned char  *fbmem;
  45.         unsigned int    screensize;
  46.         unsigned int    fb_width;
  47.         unsigned int    fb_height;
  48.         unsigned int    fb_depth;
  49.         unsigned int    x;
  50.         unsigned int    y;

  51.         /*
  52.          * check auguments
  53.          */
  54.         if (argc != 2) {
  55.                 usage("insuffient auguments");
  56.                 exit(-1);
  57.         }

  58.         /*
  59.          * open framebuffer device
  60.          */
  61.         if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
  62.                 fb_device = FB_DEV;
  63.         fbdev = fb_open(fb_device);

  64.         /*
  65.          * get status of framebuffer device
  66.          */
  67.         fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);

  68.         /*
  69.          * map framebuffer device to shared memory
  70.          */
  71.         screensize = fb_width * fb_height * fb_depth / 8;
  72.         fbmem = fb_mmap(fbdev, screensize);

  73.         /*
  74.          * open input jpeg file
  75.          */
  76.         if ((infile = fopen(argv[1], "rb")) == NULL) {
  77.                 fprintf(stderr, "open %s failed\n", argv[1]);
  78.                 exit(-1);
  79.         }

  80.         /*
  81.          * init jpeg decompress object error handler
  82.          */
  83.         cinfo.err = jpeg_std_error(&jerr);
  84.         jpeg_create_decompress(&cinfo);

  85.         /*
  86.          * bind jpeg decompress object to infile
  87.          */
  88.         jpeg_stdio_src(&cinfo, infile);


  89.         /*
  90.          * read jpeg header
  91.          */
  92.         jpeg_read_header(&cinfo, TRUE);

  93.         /*
  94.          * decompress process.
  95.          * note: after jpeg_start_decompress() is called
  96.          * the dimension infomation will be known,
  97.          * so allocate memory buffer for scanline immediately
  98.          */
  99.         jpeg_start_decompress(&cinfo);
  100.         if ((cinfo.output_width > fb_width) ||
  101.                 (cinfo.output_height > fb_height)) {
  102.                 printf("too large JPEG file,cannot display\n");
  103.                 return (-1);
  104.         }

  105.         buffer = (unsigned char *) malloc(cinfo.output_width *
  106.                                                                           cinfo.output_components);
  107.         y = 0;
  108.         while (cinfo.output_scanline < cinfo.output_height) {
  109.                 jpeg_read_scanlines(&cinfo, &buffer, 1);
  110.                 if (fb_depth == 16) {
  111.                         unsigned short  color;
  112.                         for (x = 0; x < cinfo.output_width; x++) {
  113.                                 color = RGB888toRGB565(buffer[x * 3],
  114.                                                 buffer[x * 3 + 1], buffer[x * 3 + 2]);
  115.                                 fb_pixel(fbmem, fb_width, fb_height, x, y, color);
  116.                         }
  117.                 } else if (fb_depth == 24) {
  118.                         memcpy((unsigned char *) fbmem + y * fb_width * 3,
  119.                                    buffer, cinfo.output_width * cinfo.output_components);
  120.                 }
  121.                 y++;                                        // next scanline
  122.         }

  123.         /*
  124.          * finish decompress, destroy decompress object
  125.          */
  126.         jpeg_finish_decompress(&cinfo);
  127.         jpeg_destroy_decompress(&cinfo);

  128.         /*
  129.          * release memory buffer
  130.          */
  131.         free(buffer);

  132.         /*
  133.          * close jpeg inputing file
  134.          */
  135.         fclose(infile);

  136.         /*
  137.          * unmap framebuffer's shared memory
  138.          */
  139.         fb_munmap(fbmem, screensize);

  140.         /*
  141.          * close framebuffer device
  142.          */
  143.         fb_close(fbdev);

  144.         return (0);
  145. }

  146. void
  147. usage(char *msg)
  148. {
  149.         fprintf(stderr, "%s\n", msg);
  150.         printf("Usage: fv some-jpeg-file.jpg\n");
  151. }

  152. /*
  153. * convert 24bit RGB888 to 16bit RGB565 color format
  154. */
  155. unsigned short
  156. RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
  157. {
  158.         unsigned short  B = (blue >> 3) & 0x001F;
  159.         unsigned short  G = ((green >> 2) << 5) & 0x07E0;
  160.         unsigned short  R = ((red >> 3) << 11) & 0xF800;

  161.         return (unsigned short) (R | G | B);
  162. }

  163. /*
  164. * open framebuffer device.
  165. * return positive file descriptor if success,
  166. * else return -1.
  167. */
  168. int
  169. fb_open(char *fb_device)
  170. {
  171.         int             fd;

  172.         if ((fd = open(fb_device, O_RDWR)) < 0) {
  173.                 perror(__func__);
  174.                 return (-1);
  175.         }
  176.         return (fd);
  177. }

  178. /*
  179. * get framebuffer's width,height,and depth.
  180. * return 0 if success, else return -1.
  181. */
  182. int
  183. fb_stat(int fd, int *width, int *height, int *depth)
  184. {
  185.         struct fb_fix_screeninfo fb_finfo;
  186.         struct fb_var_screeninfo fb_vinfo;

  187.         if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
  188.                 perror(__func__);
  189.                 return (-1);
  190.         }

  191.         if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
  192.                 perror(__func__);
  193.                 return (-1);
  194.         }

  195.         *width = fb_vinfo.xres;
  196.         *height = fb_vinfo.yres;
  197.         *depth = fb_vinfo.bits_per_pixel;

  198.         return (0);
  199. }

  200. /*
  201. * map shared memory to framebuffer device.
  202. * return maped memory if success,
  203. * else return -1, as mmap dose.
  204. */
  205. void           *
  206. fb_mmap(int fd, unsigned int screensize)
  207. {
  208.         caddr_t         fbmem;

  209.         if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
  210.                                           MAP_SHARED, fd, 0)) == MAP_FAILED) {
  211.                 perror(__func__);
  212.                 return (void *) (-1);
  213.         }

  214.         return (fbmem);
  215. }

  216. /*
  217. * unmap map memory for framebuffer device.
  218. */
  219. int
  220. fb_munmap(void *start, size_t length)
  221. {
  222.         return (munmap(start, length));
  223. }

  224. /*
  225. * close framebuffer device
  226. */
  227. int
  228. fb_close(int fd)
  229. {
  230.         return (close(fd));
  231. }

  232. /*
  233. * display a pixel on the framebuffer device.
  234. * fbmem is the starting memory of framebuffer,
  235. * width and height are dimension of framebuffer,
  236. * x and y are the coordinates to display,
  237. * color is the pixel's color value.
  238. * return 0 if success, otherwise return -1.
  239. */
  240. int
  241. fb_pixel(void *fbmem, int width, int height,
  242.                  int x, int y, unsigned short color)
  243. {
  244.         if ((x > width) || (y > height))
  245.                 return (-1);

  246.         unsigned short *dst = ((unsigned short *) fbmem + y * width + x);

  247.         *dst = color;
  248.         return (0);
  249. }

复制代码

[ 本帖最后由 myforever 于 2008-10-29 12:01 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-10-29 12:03 |只看该作者
原本把原理也贴过来,帖子拍版有问题,所有就不引了

大家有兴趣来这儿看看

在Linux控制台下显示JPEG图像

http://www.b2tang.com/viewthread.php?tid=113&extra=page%3D5
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP