Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1562986
  • 博文数量: 290
  • 博客积分: 3468
  • 博客等级: 中校
  • 技术积分: 3461
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-28 22:21
文章分类

全部博文(290)

文章存档

2016年(13)

2015年(3)

2014年(42)

2013年(67)

2012年(90)

2011年(75)

分类: 嵌入式

2013-07-25 12:11:07


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <string.h>
  5. #include <linux/fb.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <sys/mman.h>
  9. #include <jpeglib.h>
  10. #include <jerror.h>

  11. #define FB_DEV "/dev/fb0"
  12. #define        PWHERE() printf("FILE:%s, FUN:%s,LINE:%d\n", __FILE__, __FUNCTION__, __LINE__)

  13. static unsigned char *fbmem;
  14. static unsigned int fb_width;
  15. static unsigned int fb_height;
  16. static unsigned int fb_depth;

  17. /*
  18. * declaration for framebuffer device
  19. */
  20. static int fbdev;
  21. static char *fb_device;
  22. static unsigned int screensize;

  23. /***************** function declaration ******************/
  24. void usage(char *msg);
  25. unsigned short RGB888toRGB565(unsigned char red,
  26.                 unsigned char green, unsigned char blue);
  27. int fb_open(char *fb_device);
  28. int fb_close(int fd);
  29. int fb_stat(int fd, int *width, int *height, int *depth);
  30. void *fb_mmap(int fd, unsigned int screensize);
  31. int fb_munmap(void *start, size_t length);
  32. int fb_pixel_32(void *fbmem, int width, int height,
  33.                 int x, int y, unsigned int color);
  34. int fb_pixel_16(void *fbmem, int width, int height,
  35.                 int x, int y, unsigned short color);

  36. /************ function implementation ********************/
  37. void usage(char *msg)
  38. {
  39.     fprintf(stderr, "%s\n", msg);
  40.     printf("Usage: fv some-jpeg-file.jpg\n");
  41. }

  42. /*
  43.  * convert 24bit RGB888 to 16bit RGB565 color format
  44.  */
  45. unsigned short RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
  46. {
  47.     unsigned short B = (blue >> 3) & 0x001F;
  48.     unsigned short G = ((green >> 2) << 5) & 0x07E0;
  49.     unsigned short R = ((red >> 3) << 11) & 0xF800;

  50.     return (unsigned short) (R | G | B);
  51. }
  52. /*
  53.  * convert 24bit RGB888 to 32bit RGB8888 color format
  54.  */
  55. unsigned int RGB888toRGB8888(unsigned char red, unsigned char green, unsigned char blue)
  56. {
  57.     unsigned int B = (blue) & 0x00000FF;
  58.     unsigned int G = (green << 8) & 0x0000FF00;
  59.     unsigned int R = (red << 16) & 0x00FF0000;
  60.     unsigned int A = (255 << 24) & 0xFF000000;
  61.     return (unsigned int ) (R | G | B |A);

  62. }


  63. /*
  64.  * open framebuffer device.
  65.  * return positive file descriptor if success,
  66.  * else return -1.
  67.  */
  68. int fb_open(char *fb_device)
  69. {
  70.     int fd;

  71.     if ((fd = open(fb_device, O_RDWR)) < 0) {
  72.         perror(__func__);
  73.         return (-1);
  74.     }
  75.     return (fd);
  76. }

  77. /*
  78.  * get framebuffer's width,height,and depth.
  79.  * return 0 if success, else return -1.
  80.  */
  81. int fb_stat(int fd, int *width, int *height, int *depth)
  82. {
  83.     struct fb_fix_screeninfo fb_finfo;
  84.     struct fb_var_screeninfo fb_vinfo;

  85.     if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
  86.         perror(__func__);
  87.         return (-1);
  88.     }

  89.     if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
  90.         perror(__func__);
  91.         return (-1);
  92.     }

  93.     *width = fb_vinfo.xres;
  94.     *height = fb_vinfo.yres;
  95.     *depth = fb_vinfo.bits_per_pixel;

  96.     return (0);
  97. }

  98. /*
  99.  * map shared memory to framebuffer device.
  100.  * return maped memory if success,
  101.  * else return -1, as mmap dose.
  102.  */
  103. void *fb_mmap(int fd, unsigned int screensize)
  104. {
  105.     caddr_t fbmem;

  106.     if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
  107.                     MAP_SHARED, fd, 0)) == MAP_FAILED) {
  108.         perror(__func__);
  109.         return (void *) (-1);
  110.     }

  111.     return (fbmem);
  112. }

  113. /*
  114.  * unmap map memory for framebuffer device.
  115.  */
  116. int fb_munmap(void *start, size_t length)
  117. {
  118.     return (munmap(start, length));
  119. }

  120. /*
  121.  * close framebuffer device
  122.  */
  123. int fb_close(int fd)
  124. {
  125.     return (close(fd));
  126. }


  127. void init_device (void)
  128. {
  129.     
  130.     /*
  131.      * open framebuffer device
  132.      */
  133.     if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
  134.         fb_device = FB_DEV;
  135.     fbdev = fb_open(fb_device);
  136.     if (fbdev < 0) {
  137.         perror("open fb error");
  138.         exit(-1);
  139.     }

  140.     /*
  141.      * get status of framebuffer device
  142.      */
  143.     fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);

  144.     /*
  145.      * map framebuffer device to shared memory
  146.      */
  147.     screensize = fb_width * fb_height * fb_depth / 8;
  148.     fbmem = fb_mmap(fbdev, screensize);
  149. }
  150. /*
  151.  * display a pixel on the framebuffer device.
  152.  * fbmem is the starting memory of framebuffer,
  153.  * width and height are dimension of framebuffer,
  154.  * x and y are the coordinates to display,
  155.  * color is the pixel's color value.
  156.  * return 0 if success, otherwise return -1.
  157.  */
  158. int fb_pixel_32(void *fbmem, int width, int height,
  159.             int x, int y, unsigned int color)
  160. {
  161.     if ((x > width) || (y > height))
  162.         return (-1);

  163.     unsigned int *dst = ((unsigned int *) fbmem + y * width + x);

  164.     *dst = color;
  165.     return 0;
  166. }

  167. int fb_pixel_16(void *fbmem, int width, int height,
  168.             int x, int y, unsigned short color)
  169. {
  170.     if ((x > width) || (y > height))
  171.         return (-1);

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

  173.     *dst = color;
  174.     return 0;
  175. }

  176. void draw_chessboard_16(unsigned short color)
  177. {
  178.     unsigned int x,y;
  179.     int step = 50;
  180.     // draw line H dirction step by 50
  181.     for (y = step; y < fb_height - step; y += step) {
  182.         for (x = 100; x < fb_width - step; x++) {
  183.             fb_pixel_16(fbmem,fb_width, fb_height,x,y,color); //color(16bit):R(5) G(6) B(5)
  184.                     //color(24bit):R(8) G(8) B(8)      //color(32bit):R(10) G(12) B(10)    
  185.         }
  186.     }

  187.     // draw line V dirction step by 50
  188.     for(x = 100; x < fb_width - step; x += step) {
  189.         for(y = step; y < fb_height - step; y++) {
  190.             fb_pixel_16(fbmem,fb_width, fb_height,x,y,color);
  191.         }
  192.     }

  193. }

  194. void draw_chessboard_32(unsigned int color)
  195. {
  196.     unsigned int x,y;
  197.     int step = 50;
  198.     // draw line H dirction step by 50
  199.     for (y = step; y < fb_height -step; y += step) {
  200.         for (x = 100; x < fb_width -step; x++) {
  201.             fb_pixel_32(fbmem,fb_width, fb_height,x,y,color); //color(16bit):R(5) G(6) B(5)
  202.                     //color(24bit):R(8) G(8) B(8)      //color(32bit):R(10) G(12) B(10)    
  203.         }
  204.     }

  205.     // draw line V dirction step by 50
  206.     for(x = 100; x < fb_width - step; x += step) {
  207.         for(y = step; y < fb_height -step; y++) {
  208.             fb_pixel_32(fbmem,fb_width, fb_height,x,y,color);
  209.         }
  210.     }
  211. }


  212. FILE *open_pic(char *filename)
  213. {
  214.      /*
  215.      * open input jpeg file
  216.      */
  217.     FILE *fp;
  218.     if ((fp= fopen(filename, "rb")) == NULL) {
  219.         fprintf(stderr, "open %s failed\n", filename);
  220.         exit(-1);
  221.     }

  222.     return fp;
  223. }

  224. int close_pic(FILE *fp)
  225. {    /*
  226.      * close jpeg inputing file
  227.      */

  228.     return fclose(fp);
  229. }

  230. void display_pic(unsigned char *buffer, struct jpeg_decompress_struct cinfo)
  231. {
  232.     int x = 0,y = 0;
  233.     unsigned short color;
  234.     unsigned int color_int;

  235.     int pic_w = cinfo.output_width;
  236.     int pic_h = cinfo.output_height;
  237.     int pic_bytes = cinfo.output_components;

  238. //    printf("w:%d, h:%d,bytes:%d\n", pic_w, pic_h, pic_bytes);

  239.     int offset = 0;

  240.     if (fb_depth == 16) {
  241.         unsigned short color_buf[pic_w * pic_h];
  242.         memset(color_buf, 0, sizeof(color_buf));

  243.         if(pic_h == fb_height && pic_w == fb_width) {
  244.             while (y < pic_h) {
  245.                 for (x = 0; x < pic_w; x++) {
  246.                     color_buf[y*pic_w + x] = RGB888toRGB565(buffer[x * 3],
  247.                                         buffer[x * 3 + 1], buffer[x * 3 + 2]);
  248.                 }
  249.                 y++;
  250.                 buffer += pic_w * pic_bytes;
  251.             }

  252.             memcpy((unsigned char*) fbmem, color_buf, sizeof(color_buf));
  253.         } else {
  254.             while (y < pic_h) {
  255.                 for (x = 0; x < pic_w; x++) {
  256.                     color_buf[y*pic_w + x] = RGB888toRGB565(buffer[x * 3],
  257.                                         buffer[x * 3 + 1], buffer[x * 3 + 2]);
  258.                 }
  259.                 offset = pic_w * y ;
  260.                 memcpy((unsigned char*) fbmem + y*fb_width*fb_depth/8,
  261.                         color_buf + offset, pic_w*fb_depth/8);
  262.                 y++;
  263.                 buffer += pic_w * pic_bytes;
  264.             }
  265.         }
  266.     } else if (fb_depth == 24) {
  267.         if(pic_h == fb_height && pic_w == fb_width) {
  268.             memcpy((unsigned char *) fbmem, buffer, pic_w * pic_h * pic_bytes);
  269.         } else {
  270.             while (y < pic_h) {
  271.                 memcpy((unsigned char*) fbmem + y*fb_width*fb_depth/8,
  272.                         buffer, pic_w*fb_depth/8);
  273.                 y++;
  274.                 buffer += pic_w * fb_depth/8;
  275.             }
  276.         }
  277.     } else if (fb_depth == 32) {
  278.         unsigned int color_buf[pic_w * pic_h];
  279.         memset(color_buf, 0, sizeof(color_buf));

  280.         //当图片大小与分辨相同时,使用此方法显示更快
  281.         if(pic_h == fb_height && pic_w == fb_width) {
  282.             while (y < pic_h) {
  283.                 for (x = 0; x < pic_w; x ++) {
  284.                     color_buf[y*pic_w + x] = RGB888toRGB8888(buffer[x * 3],
  285.                                         buffer[x * 3 + 1], buffer[x * 3 + 2]);
  286.                 }
  287.                 y++;
  288.                 buffer += pic_w * pic_bytes;
  289.             }

  290.             memcpy((unsigned char*) fbmem, color_buf, sizeof(color_buf));

  291.         } else {
  292.             while (y < pic_h) {
  293.                 for (x = 0; x < pic_w; x ++) {
  294.                     color_buf[y*pic_w + x] = RGB888toRGB8888(buffer[x * 3],
  295.                                         buffer[x * 3 + 1], buffer[x * 3 + 2]);
  296.                 }
  297.                 offset = pic_w * y ;
  298.                 memcpy((unsigned char*) fbmem + y*fb_width*fb_depth/8,
  299.                         color_buf + offset, pic_w*fb_depth/8);
  300.                 y++;
  301.                 buffer += pic_w * pic_bytes;
  302.             }
  303.         }
  304.     }
  305. }


  306. int    decompress_display_pic(FILE *infile)
  307. {
  308.     /*
  309.     * declaration for jpeg decompression
  310.     */

  311.     struct jpeg_decompress_struct cinfo;
  312.     struct jpeg_error_mgr jerr;
  313.     unsigned char *buffer;

  314.     /*
  315.      * init jpeg decompress object error handler
  316.      */
  317.     cinfo.err = jpeg_std_error(&jerr);
  318.     jpeg_create_decompress(&cinfo);

  319.     /*
  320.      * bind jpeg decompress object to infile
  321.      */
  322.     jpeg_stdio_src(&cinfo, infile);

  323.     /*
  324.      * read jpeg header
  325.      */
  326.     jpeg_read_header(&cinfo, TRUE);

  327.     /*
  328.      * decompress process.
  329.      * note: after jpeg_start_decompress() is called
  330.      * the dimension infomation will be known,
  331.      * so allocate memory buffer for scanline immediately
  332.      */
  333.     jpeg_start_decompress(&cinfo);
  334.     if ((cinfo.output_width > fb_width) ||
  335.         (cinfo.output_height > fb_height)) {
  336.         printf("fb_width = %d,fb_height = %d\n",fb_width,fb_height);    
  337.         printf("cinfo.output_width = %d,cinfo.output_height = %d\n",cinfo.output_width,cinfo.output_height);
  338.         printf("too large JPEG file,cannot display\n");
  339.         return (-1);
  340.     }

  341. //    printf("cinfo.output_width = %d,cinfo.output_height = %d\n",cinfo.output_width,cinfo.output_height);
  342. //    printf("output_components: %d\n", cinfo.output_components);
  343.     int buffer_size = cinfo.output_width * cinfo.output_components;
  344.     buffer = (unsigned char *) malloc(buffer_size);

  345.     unsigned char *pic_buf = NULL;
  346.     unsigned char *tmp_buf = NULL;
  347.     int pic_size = cinfo.output_width * cinfo.output_height * cinfo.output_components;
  348.     pic_buf = (unsigned char *) malloc(pic_size);
  349.     tmp_buf = pic_buf;
  350.     memset(buffer, 0, sizeof(buffer_size));
  351.     memset(pic_buf, 0, sizeof(pic_size));

  352.     while (cinfo.output_scanline < cinfo.output_height) {
  353.         jpeg_read_scanlines(&cinfo, &buffer, 1);
  354.         memcpy(tmp_buf, buffer, buffer_size);
  355.         tmp_buf += buffer_size;
  356.     }

  357.     //display_pic(tmp_buf, pic_w, pic_h, pic_bytes);
  358.     /*
  359.      * finish decompress, destroy decompress object
  360.      */
  361.     jpeg_finish_decompress(&cinfo);
  362.     jpeg_destroy_decompress(&cinfo);

  363.     display_pic(pic_buf, cinfo);

  364.     /*
  365.      * release memory buffer
  366.      */
  367.     free(buffer);
  368.     free(pic_buf);
  369.     buffer = NULL;
  370.     pic_buf = NULL;
  371. }


  372. void delay_s(unsigned int m)
  373. {
  374.     unsigned int i;
  375.     unsigned long l;
  376.     unsigned long n=60000000;

  377.     for (i=0; i<m; i++)
  378.         for(l=0; l<n; l++);
  379. }


  380. int main(int argc, char *argv[])
  381. {
  382.     //initzilation device
  383.     init_device();
  384.     printf("the max size:fb_width = %d,fb_height = %d, fb_depth = %d\n",fb_width,fb_height,fb_depth);

  385.     /*
  386.     * check auguments
  387.     */
  388. /*
  389.     if (argc != 2){
  390.             printf("the max size:fb_width = %d,fb_height = %d, fb_depth = %d\n",fb_width,fb_height,fb_depth);
  391.      usage("insuffient auguments");
  392.      exit(-1);
  393.     }
  394. */    
  395.     //display a picture as the chess board background
  396.     FILE *fp1 = NULL;
  397.     FILE *fp2 = NULL;

  398.     fp1 = open_pic("./3.jpg");
  399.     fp2 = open_pic("./4.jpg");

  400.     while (1) {
  401.         decompress_display_pic(fp1);
  402.         delay_s(1);
  403.         decompress_display_pic(fp2);
  404.         delay_s(1);
  405.         rewind(fp1);
  406.         rewind(fp2);
  407.     }

  408.     fclose(fp1);
  409.     fclose(fp2);
  410.     /*draw chess board*/
  411.     /*
  412.     if (fb_depth == 32)
  413.         draw_chessboard_32(0x0000ff00);
  414.     else if (fb_depth == 16)
  415.         draw_chessboard_16(0xf800);
  416.     */
  417.     /*
  418.      * unmap framebuffer's shared memory
  419.      */
  420.     fb_munmap(fbmem, screensize);

  421.     /*
  422.      * close framebuffer device
  423.      */
  424.     fb_close(fbdev);

  425.     return (0);
  426. }



makefile


点击(此处)折叠或打开

  1. CC = gcc -g

  2. TARGET testProg

  3. OBJS = pic.o

  4. all:$(TARGET)

  5. $(TARGET):$(OBJS)
  6.     $(CC) -o $@ $^ -ljpeg -lm

  7. .PHONY:clean
  8.     
  9. clean:
  10.     rm *.o $(TARGET) -f
  11. cleanobj:
  12.     rm *.o -f


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