本文的copyright归yuweixian4230@163.com 所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
作者:yuweixian4230@163.com
博客:yuweixian4230.blog.chinaunix.net 使用了
http://blog.csdn.net/yruilin/archive/2009/01/17/3808715.aspx 的程序,对它进行的测试,在自己开发板上可以正常显示 RGB565
将代码贴下:
jpeg1.rar 编译如下: arm-linux-gcc jpeg1.c -ljpeg -o jpeg1 //需要加上jpeg库
- /*
-
-
* $Id: fv.c
-
-
* $Desp: draw jpeg to framebuffer
-
-
* $Author: rockins
-
-
* $Date: Wed Jan 3 20:15:49 CST 2007
-
-
*/
-
-
#include <stdio.h>
-
-
#include <stdlib.h>
-
-
#include <fcntl.h>
-
-
#include <linux/fb.h>
-
-
#include <sys/types.h>
-
-
#include <sys/stat.h>
-
-
#include <sys/mman.h>
-
-
#include <jpeglib.h>
-
-
#include <jerror.h>
-
-
#define FB_DEV "/dev/fb0"
-
-
/***************** function declaration ******************/
-
-
void usage(char *msg);
-
-
unsigned short RGB888toRGB565(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);
-
-
/*
-
-
* map framebuffer device to shared memory
-
-
*/
-
-
screensize = fb_width * fb_height * fb_depth / 8;
-
-
fbmem = fb_mmap(fbdev, 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 (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 = RGB888toRGB565(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 RGB565 color format
-
-
*/
-
-
unsigned short
-
-
RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
-
-
{
-
-
unsigned short B = (blue >> 3) & 0x001F;
-
-
unsigned short G = ((green >> 2) << 5) & 0x07E0;
-
-
unsigned short R = ((red >> 3) << 11) & 0xF800;
-
-
return (unsigned short) (R | G | B);
-
-
}
-
-
/*
-
-
* 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);
-
-
}
在 开发板上运行
./jpeg1 2.jpg
然后用截图软件 gsoap test.jpg /dev/fb0 保存数据
发现:原图片 2.jpg 大小才 25 KB
通过jpeg 解码后,80 KB
在开发LCD上显示很清楚
阅读(1662) | 评论(0) | 转发(0) |