免费注册 查看新帖 |

Chinaunix

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

9261EK上显示jpeg图片到framebuffer上 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-04-29 10:39 |只看该作者 |倒序浏览
    这学期开学以来都在忙一个电表项目的前期准备工作,几乎没有搞linux了,最近又重新拾了起来,但是现在又要打止了,因为电表又要开始搞了,所以这几天我会陆续将最近搞的一点小东西发上来,希望对大家能有所帮助,也希望大家多提提意见。
在9261EK上的framebuffer上显示jpeg图片
1、  首先安装jpeg库,在此不在赘述。注意一定要把库放到交叉编译器的正确位置,否则就要用-l参数指定库的路径。
2、  如下程序将图片显示到farmebuffer上,因为9261的lcd控制器是基于BGR555标准的,因此需要先将RGB888转换为BGR555,才能在framebuffer上显示
3、  交叉编译
arm-none-linux-gnueabi-gcc -o displaypic displaypic.c –ljpeg
将编译好的displaypic下载到开发板,将分辨率小于240*320图片也下载到开发板,如下即可将pic.jpg显示到LCD上。
./ displaypic pic.jpg
4、  以下程序是根据网上的一篇《Linux控制台下显示JPEG图像》中的程序改编的。
#include                                                        
#include
#include
#include
#include
#include
#include
#include
#include
#define   FB_DEV       "/dev/fb0"
/***************** function declaration ******************/
void            usage(char *msg);
unsigned short  RGB888toRGB555(unsigned char red,
                                                    unsigned char green, unsigned char blue);
int             fb_open(char *fb_device);
int             fb_close(int fd);
int             fb_stat(int fd, int *width, int *height, int *depth);
void           *fb_mmap(int fd, unsigned int screensize);
int             fb_munmap(void *start, size_t length);
int             fb_pixel(void *fbmem, int width, int height,
                                           int x, int y, unsigned short color);

/************ function implementation ********************/
int
main(int argc, char *argv[])
{
       /*
        * declaration for jpeg decompression
        */
       struct jpeg_decompress_struct cinfo;
       struct jpeg_error_mgr jerr;
       FILE           *infile;
       unsigned char  *buffer;
       /*
        * declaration for framebuffer device
        */
       int             fbdev;
       char           *fb_device;
       unsigned char  *fbmem;
       unsigned int    screensize;
       unsigned int    fb_width;
       unsigned int    fb_height;
       unsigned int    fb_depth;
       unsigned int    x;
       unsigned int    y;
       /*
        * check auguments
        */
       if (argc != 2) {
              usage("insuffient auguments");
              exit(-1);
       }
       /*
        * open framebuffer device
        */
       if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
              fb_device = FB_DEV;
       fbdev = fb_open(fb_device);
       /*
        * get status of framebuffer device
        */
       fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);
       printf("%d ",fb_width);
       printf("%d ",fb_height);
       printf("%d\n",fb_depth);
       /*
        * map framebuffer device to shared memory
        */
       screensize = fb_width * fb_height * fb_depth / 8; //所需映射内存的大小
       fbmem = fb_mmap(fbdev, screensize); //映射内存的起始地址
       memset (fbmem, 0, screensize);//清屏
       /*
        * open input jpeg file
        */
       if ((infile = fopen(argv[1], "rb")) == NULL) {
              fprintf(stderr, "open %s failed\n", argv[1]);
              exit(-1);
       }
       /*
        * init jpeg decompress object error handler
        */
       cinfo.err = jpeg_std_error(&jerr);
       jpeg_create_decompress(&cinfo);
       /*
        * bind jpeg decompress object to infile
        */
       jpeg_stdio_src(&cinfo, infile);
       /*
        * read jpeg header
        */
       jpeg_read_header(&cinfo, TRUE);

       /*
        * decompress process.
        * note: after jpeg_start_decompress() is called
        * the dimension infomation will be known,
        * so allocate memory buffer for scanline immediately
        */
       jpeg_start_decompress(&cinfo);
       if ((cinfo.output_width > fb_width) ||
              (cinfo.output_height > fb_height)) {
              printf("too large JPEG file,cannot display\n");
              return (-1);
       }
       buffer = (unsigned char *) malloc(cinfo.output_width *
                                                                 cinfo.output_components);//为一条扫描线上的像素点分配存储空间
       y = 0;
//while将显示图片内容到framebuffer上
       while (cinfo.output_scanline
              jpeg_read_scanlines(&cinfo, &buffer, 1);
              if (fb_depth == 16) {
                     unsigned short  color;
                     for (x = 0; x
                            color = RGB888toRGB555(buffer[x * 3],
                                          buffer[x * 3 + 1], buffer[x * 3 + 2]);
                            fb_pixel(fbmem, fb_width, fb_height, x, y, color);//显示一个像素点
                     }
              } else if (fb_depth == 24) {
                     memcpy((unsigned char *) fbmem + y * fb_width * 3,
                               buffer, cinfo.output_width * cinfo.output_components);
              }
              y++;                                   // next scanline
       }
       /*
        * finish decompress, destroy decompress object
        */
       jpeg_finish_decompress(&cinfo);
       jpeg_destroy_decompress(&cinfo);
       /*
        * release memory buffer
        */
       free(buffer);

       /*
        * close jpeg inputing file
        */
       fclose(infile);
       /*
        * unmap framebuffer's shared memory
        */
       fb_munmap(fbmem, screensize);
       /*
        * close framebuffer device
        */
       fb_close(fbdev);
       return (0);
}
void
usage(char *msg)
{
       fprintf(stderr, "%s\n", msg);
       printf("Usage: fv some-jpeg-file.jpg\n");
}
/*
* convert 24bit RGB888 to 16bit RGB555 color format
*/
unsigned short
RGB888toRGB555(unsigned char red, unsigned char green, unsigned char blue)
{
       unsigned short  B = (blue 7C00;
       unsigned short  G = (green  
       unsigned short  R = (red >> 3);

       return (unsigned short) (B | G | R);
}
/*
* open framebuffer device.
* return positive file descriptor if success,
* else return -1.
*/
int
fb_open(char *fb_device)
{
       int             fd;

       if ((fd = open(fb_device, O_RDWR))
              perror(__func__);
              return (-1);
       }
       return (fd);
}
/*
* get framebuffer's width,height,and depth.
* return 0 if success, else return -1.
*/
int
fb_stat(int fd, int *width, int *height, int *depth)
{
       struct fb_fix_screeninfo fb_finfo;
       struct fb_var_screeninfo fb_vinfo;
       if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo))
              {
              perror(__func__);
              return (-1);
              }
       if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo))
              {
              perror(__func__);
              return (-1);
              }
       *width = fb_vinfo.xres;
       *height = fb_vinfo.yres;
       *depth = fb_vinfo.bits_per_pixel;
       return (0);
}
/*
* map shared memory to framebuffer device.
* return maped memory if success,
* else return -1, as mmap dose.
*/
void           *
fb_mmap(int fd, unsigned int screensize)
{
       caddr_t         fbmem;

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

       return (fbmem);
}
/*
* unmap map memory for framebuffer device.
*/
int
fb_munmap(void *start, size_t length)
{
       return (munmap(start, length));
}
/*
* close framebuffer device
*/
int
fb_close(int fd)
{
       return (close(fd));
}

/*
* display a pixel on the framebuffer device.
* fbmem is the starting memory of framebuffer,
* width and height are dimension of framebuffer,
* x and y are the coordinates to display,
* color is the pixel's color value.
* return 0 if success, otherwise return -1.
*/
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);
}




本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/84904/showart_1913883.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP