#include
/*
* Include file for users of JPEG library.
* You will need to have included system headers that define at least
* the typedefs FILE and size_t before you can include jpeglib.h.
* (stdio.h is sufficient on ANSI-conforming systems.)
* You may also wish to include "jerror.h".
*/
#include "jpeglib.h"
/*
* is used for the optional error recovery mechanism shown in
* the second part of the example.
*/
#include
/******************** JPEG COMPRESSION SAMPLE INTERFACE *******************/
/* This half of the example shows how to feed data into the JPEG compressor.
* We present a minimal version that does not worry about refinements such
* as error recovery (the JPEG code will just exit() if it gets an error).
*/
/*
* IMAGE DATA FORMATS:
*
* The standard input image format is a rectangular array of pixels, with
* each pixel having the same number of "component" values (color channels).
* Each pixel row is an array of JSAMPLEs (which typically are unsigned chars).
* If you are working with color data, then the color values for each pixel
* must be adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit
* RGB color.
*
* For this example, we'll assume that this data structure matches the way
* our application has stored the image in memory, so we can just pass a
* pointer to our image buffer. In particular, let's say that the image is
* RGB color and is described by:
*/
extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
extern int image_height; /* Number of rows in image */
extern int image_width; /* Number of columns in image */
使用framebuffer演示jpeg格式图片。
程序如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FB_DEV "/dev/fb0"
unsigned char *fbmem;
unsigned int screensize;
unsigned int fb_width;
unsigned int fb_height;
unsigned int fb_depth;
unsigned int x;
unsigned int y;
/***************** function declaration ******************/
void usage(char *msg);
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, int r, int g, int b);
unsigned char * display_jpeg(char * filename,int *w, int *h);
/************ function implementation ********************/
int main(int argc, char *argv[])
{
int fbdev;
char *fb_device;
int w ,h,i,j;
if (argc != 2) {
usage("insuffient auguments");
exit(-1);
}
if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
fb_device = FB_DEV;
fbdev = fb_open(fb_device);
fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);
screensize = fb_width * fb_height * fb_depth / 8;
fbmem = fb_mmap(fbdev, screensize);
unsigned char *imgbuf, r, g, b;
imgbuf = display_jpeg(argv[1],&w,&h);
printf(" %s: w = %d,h = %d",argv[1],w,h);
for(j = 0; j < h; j++)
{
for( i = 0; i < w; i++)
{
r = imgbuf[i*3 + j*w*3];
g = imgbuf[i*3 + j*w*3 + 1];
b = imgbuf[i*3 + j*w*3 + 2];
fb_pixel(fbmem,fb_width,fb_height,i,j,r,g,b);
}
}
fb_munmap(fbmem, screensize);
fb_close(fbdev);
return (0);
}
unsigned char * display_jpeg(char * filename, int *w, int *h)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *infile;
unsigned char *buffer;
unsigned char *temp;
if ((infile = fopen(filename, "rb")) == NULL) {
fprintf(stderr, "open %s failed/n", filename);
exit(-1);
}
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, infile);
jpeg_read_header(&cinfo, TRUE);
jpeg_start_decompress(&cinfo);
*w = cinfo.output_width;
*h = cinfo.output_height;
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 * cinfo.output_height);
temp = buffer;
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, &buffer, 1);
buffer += cinfo.output_width * cinfo.output_components;
}
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
return temp;
fclose(infile);
}
void usage(char *msg)
{
fprintf(stderr, "%s/n", msg);
printf("Usage: fv some-jpeg-file.jpg/n");
}
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);
}
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);
}
int fb_munmap(void *start, size_t length)
{
return (munmap(start, length));
}
int fb_close(int fd)
{
return (close(fd));
}
int fb_pixel(void *fbmem, int width, int height,
int x, int y, int r, int g, int b)
{
if ((x > width) || (y > height))
return (-1);
unsigned char *dst = fbmem + y * 5504 + x * 4; //'5504'为个人PC机的bpp
dst[0] = b;
dst[1] = g;
dst[2] = r;
return (0);
}