libjpeg测试程序
来源:互联网 发布:淘宝信用卡套现流程 编辑:程序博客网 时间:2024/05/29 17:17
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <pthread.h>
#include <string.h>
#include <jpeglib.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,int yoffset);
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;//解压的jpeg所有信息
struct jpeg_error_mgr jerr;//jpeg错误处理对象
int i=1;
FILE *infile;//要显示的文件
unsigned char *buffer;//缓冲区
/*
* declaration for framebuffer device
*/
int fbdev;//打开的framebuffer设备号
char *fb_device;//framebuffer设备名
unsigned char *fbmem;//LCD内存映射
unsigned int screensize;//LCD屏幕大小
unsigned int fb_width;//LCD宽度
unsigned int fb_height;//LCD高度
unsigned int fb_depth;//LCD像素几个字节
unsigned int x;
unsigned int y;
//if (argc != 2) {
//usage("insuffient auguments");//判断命令行参数
//exit(-1);
//}
if ((fb_device = "/dev/fb0") == NULL)
fb_device = FB_DEV;
fbdev = fb_open(fb_device);//打开LCD设备并返回设备号
//获取framebuffer的信息:宽度、高度、每像素二进制位数
fb_stat(fbdev, &fb_width, &fb_height, &fb_depth,-1);
printf("%d %d %d\n",fb_width,fb_height,fb_depth);
screensize = fb_width* fb_height * fb_depth / 8*2;//计算LCD大小,一帧数据多少个字节
fbmem = fb_mmap(fbdev, screensize);//映射LCD内存
cinfo.err = jpeg_std_error(&jerr);//注册错误处理函数
jpeg_create_decompress(&cinfo);//创建jpeg对象
int n=2;
//while(1)
{
#if 0
if(n%2==0)
{
fbmem=fbmem+screensize/2;
}
else
{
fbmem=fbmem-screensize/2;
}
n++;
#endif
//fbmem=fbmem+640*480*2;
if ((infile = fopen(argv[i], "rb")) == NULL) {//打开jpeg二进制格式文件
printf("%s\n",argv[i]);
fprintf(stderr, "open %s failed\n", argv[1]);
exit(-1);
}
jpeg_stdio_src(&cinfo, infile);//绑定jpeg源文件和jpeg对象
jpeg_read_header(&cinfo, TRUE);//读取jpeg头信息
cinfo.scale_num=1;
cinfo.scale_denom=1;//压缩比例1:4,
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);
}
//分配内存,output_components记录的使每像素的颜色数,每种颜色一个字节
buffer = (unsigned char *) malloc(cinfo.output_width *cinfo.output_components);
y = 0;
//fb_stat(fbdev, &fb_width, &fb_height, &fb_depth,480);
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++) {//output_width为解码的图片宽度
//转换颜色
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++; // 下一行图片
}
//关闭文件
fclose(infile);
//完成转换,并释放对象
jpeg_finish_decompress(&cinfo);
i++;
if(i>=argc)
{
i=1;
}
fb_stat(fbdev, &fb_width, &fb_height, &fb_depth,0);
sleep(1);
}
jpeg_destroy_decompress(&cinfo);
//释放行缓冲区
free(buffer);
//释放framebuffer内存
fb_munmap(fbmem, screensize);
//关闭LCD设备
fb_close(fbdev);
return (0);
}
void usage(char *msg)
{
fprintf(stderr, "%s\n", msg);
printf("Usage: fv some-jpeg-file.jpg\n");
}
//从24真彩色转换为16位真彩色
unsigned short RGB888toRGB565(unsigned char red, unsigned char green, unsigned char blue)
{
unsigned short B = (blue >> 3) & 0x001F;//取高5位
unsigned short G = ((green >> 2) << 5) & 0x07E0;//取高6位,并移动位置
unsigned short R = ((red >> 3) << 11) & 0xF800;//取高5位并移动位置
return (unsigned short) (R | G | B);//合并为16的像素数据
}
//打开framebuffer设备并返回打开的设备号
int fb_open(char *fb_device)
{
int fd;
if ((fd = open(fb_device, O_RDWR)) < 0) {
perror(__func__);
return (-1);
}
return (fd);
}
//获取framebuffer的信息:宽度、高度、每像素二进制位数
int fb_stat(int fd, int *width, int *height, int *depth,int yoffset)
{
//FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO。前者返回与Framebuffer有关的固定的信息,比如图形硬件上实际的帧缓存空间的大小、能否硬件加速等信息。而后者返回的是与Framebuffer有关的可变信息。
struct fb_fix_screeninfo fb_finfo;
struct fb_var_screeninfo fb_vinfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {//返回framebuffer物理信息
perror(__func__);
return (-1);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {////返回framebuffer可变信息
perror(__func__);
return (-1);
}
*width = fb_vinfo.xres;//宽度
*height = fb_vinfo.yres;//高度
*depth = fb_vinfo.bits_per_pixel;//var.bits_per_pixel为16每像素二进制位数
printf("%d\n",fb_vinfo.yres_virtual);
if(yoffset<0)
{
return (0);
}
fb_vinfo.yoffset=yoffset;
if (ioctl(fd,FBIOPAN_DISPLAY, &fb_vinfo)) {////返回framebuffer可变信息
perror(__func__);
return (-1);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {////返回framebuffer可变信息
perror(__func__);
return (-1);
}
printf("%d\n",fb_vinfo.yoffset);
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);//返回缓冲区指针
}
//释放framebuffer内存
int fb_munmap(void *start, size_t length)
{
return (munmap(start, length));
}
//关闭LCD
int fb_close(int fd)
{
return (close(fd));
}
//显示像素fbmem为framebuffer内存缓冲区,width为LCD宽度,height为LCD高度,x,为写入的行位置,y为写入的行
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 *) fbmem强制转换为整形
unsigned short *dst = ((unsigned short *) fbmem + y * width + x);//计算位置
//printf("%x %x\n",dst,((unsigned short *) fbmem + y * width + x));
*dst = color;
return (0);
}
- libjpeg测试程序
- libJPEG调用程序
- LIBJPEG
- libjpeg
- 使用libjpeg显示JPEG图像在framebuffer 测试(八)
- 程序测试
- 测试程序
- 测试程序
- 测试程序
- 测试程序
- 程序测试
- 程序测试
- 测试程序
- 测试程序
- 测试程序
- 程序测试
- 测试程序
- 测试程序
- Zlib压缩类库使用
- tslib触摸屏测试程序源码
- 模板类的使用
- 查找单词的题目,很有意思,我提供了两个版本
- Hbase 各regionServer 时间不一致
- libjpeg测试程序
- What does "#! /usr/bin/ksh" mean?
- 三星继续稳居美国手机市场头名位置 苹果仅列第三
- 我的vim(配置+插件)
- [算法学习]不改变正负数之间相对顺序重新排列数组.时间O(N),空间O(1)
- Comparing Java and C# Generics
- D2010 RTTI + Attribute 简单实现ORM
- libjepg编译及使用
- OPENSSL编程起步