Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178404
  • 博文数量: 43
  • 博客积分: 2516
  • 博客等级: 少校
  • 技术积分: 500
  • 用 户 组: 普通用户
  • 注册时间: 2008-11-09 10:25
文章分类

全部博文(43)

文章存档

2011年(1)

2009年(11)

2008年(31)

我的朋友

分类: LINUX

2009-04-29 10:39:18

    这学期开学以来都在忙一个电表项目的前期准备工作,几乎没有搞linux了,最近又重新拾了起来,但是现在又要打止了,因为电表又要开始搞了,所以这几天我会陆续将最近搞的一点小东西发上来,希望对大家能有所帮助,也希望大家多提提意见。 

9261EK上的framebuffer上显示jpeg图片

1  首先安装jpeg库,在此不在赘述。注意一定要把库放到交叉编译器的正确位置,否则就要用-l参数指定库的路径。

2  如下程序将图片显示到farmebuffer上,因为9261lcd控制器是基于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 < cinfo.output_height) {

              jpeg_read_scanlines(&cinfo, &buffer, 1);

              if (fb_depth == 16) {

                     unsigned short  color;

                     for (x = 0; x < cinfo.output_width; 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 <<7) & 0x7C00;

       unsigned short  G = (green  << 2) & 0x03E0;

       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)) < 0) {

              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);

}

 

 

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

chinaunix网友2010-04-17 21:25:56

您好,我也在做这方面的工作,但是刚接触,我在apt-get install libjpeg6后,不知道将什么库文件放到什么交叉编译文档里,请指教