您的位置:首页 > 其它

libjpeg编译使用详解

2015-12-29 16:20 549 查看
一、交叉编译libjpeg

# tar -xzvf libjpeg-turbo-1.2.1.tar.gz

#cd libjpeg-turbo-1.2.1

#mkdir tmp

# ./configure --prefix=$PWD/tmp --host=arm-linux

#make

#make install /* 会安装在当前目录下面tmp目录里面 */

二、交叉编译jpg2rgb.c

方法一:编译器后面直接跟上头文件,库文件。路径是我们开始编译出来的路径。

arm-linux-gcc -o jpg2rgb jpg2rgb.c -I /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/include -L /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/lib -ljpeg

cp jpg2rgb /work/nfs_root/fs_mini_mdev_new

cp libjpeg-turbo-1.2.1/tmp/lib/*so* /work/nfs_root/fs_mini_mdev_new/lib/ -d

方法二:把库文件,头文件放在交叉编译里面库文件,头文件的路径下面。

把编译出来的头文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include
cd /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/include

cp * /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/usr/include

把编译出来的库文件应该放入:/usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

cd /home/book/workspace/project/libjpeg-turbo-1.2.1/tmp/lib

cp *so* -d /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib

cp *so* /work/nfs_root/ /* 把库文件复制到开发板lib目录下,我们用的是动态库所以需要拷贝 */

arm-linux-gcc -o jpg2rgb jpg2rgb.c -ljpeg /* 要指定jpeg库,数学库则指定m */

jpg2rgb.c文件如下:

#include <stdio.h>

#include "jpeglib.h"

#include <setjmp.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <sys/ioctl.h>

#include <sys/mman.h>

#include <linux/fb.h>

#include <string.h>

#include <stdlib.h>

#define FB_DEVICE_NAME "/dev/fb0" /* 指定lcd驱动自动创建的设别节点名 */

#define DBG_PRINTF printf /* 方便调试打印 */

static int g_fd;

static struct fb_var_screeninfo g_tFBVar; /* lcd相关的参数,在这篇文章中重点是libjpeg */

static struct fb_fix_screeninfo g_tFBFix;

static unsigned char *g_pucFBMem;

static unsigned int g_dwScreenSize;

static unsigned int g_dwLineWidth;

static unsigned int g_dwPixelWidth;

static int FBDeviceInit(void)

{

int ret;

g_fd = open(FB_DEVICE_NAME, O_RDWR);

if (0 > g_fd)

{

DBG_PRINTF("can't open %s\n", FB_DEVICE_NAME);

}

ret = ioctl(g_fd, FBIOGET_VSCREENINFO, &g_tFBVar);

if (ret < 0)

{

DBG_PRINTF("can't get fb's var\n");

return -1;

}

ret = ioctl(g_fd, FBIOGET_FSCREENINFO, &g_tFBFix);

if (ret < 0)

{

DBG_PRINTF("can't get fb's fix\n");

return -1;

}

g_dwScreenSize = g_tFBVar.xres * g_tFBVar.yres * g_tFBVar.bits_per_pixel / 8;

g_pucFBMem = (unsigned char *)mmap(NULL , g_dwScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);

if (0 > g_pucFBMem)

{

DBG_PRINTF("can't mmap\n");

return -1;

}

g_dwLineWidth = g_tFBVar.xres * g_tFBVar.bits_per_pixel / 8;

g_dwPixelWidth = g_tFBVar.bits_per_pixel / 8;

return 0;

}

static int FBShowPixel(int iX, int iY, unsigned int dwColor)

{

unsigned char *pucFB;

unsigned short *pwFB16bpp;

unsigned int *pdwFB32bpp;

unsigned short wColor16bpp; /* 565 */

int iRed;

int iGreen;

int iBlue;

if ((iX >= g_tFBVar.xres) || (iY >= g_tFBVar.yres))

{

DBG_PRINTF("out of region\n");

return -1;

}

pucFB = g_pucFBMem + g_dwLineWidth * iY + g_dwPixelWidth * iX;

pwFB16bpp = (unsigned short *)pucFB;

pdwFB32bpp = (unsigned int *)pucFB;

switch (g_tFBVar.bits_per_pixel)

{

case 8:

{

*pucFB = (unsigned char)dwColor;

break;

}

case 16:

{

iRed = (dwColor >> (16+3)) & 0x1f;

iGreen = (dwColor >> (8+2)) & 0x3f;

iBlue = (dwColor >> 3) & 0x1f;

wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;

*pwFB16bpp
= wColor16bpp;

break;

}

case 32:

{

*pdwFB32bpp = dwColor;

break;

}

default :

{

DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);

return -1;

}

}

return 0;

}

static int FBCleanScreen(unsigned int dwBackColor)

{

unsigned char *pucFB;

unsigned short *pwFB16bpp;

unsigned int *pdwFB32bpp;

unsigned short wColor16bpp; /* 565 */

int iRed;

int iGreen;

int iBlue;

int i = 0;

pucFB = g_pucFBMem;

pwFB16bpp = (unsigned short *)pucFB;

pdwFB32bpp = (unsigned int *)pucFB;

switch (g_tFBVar.bits_per_pixel)

{

case 8:

{

memset(g_pucFBMem, dwBackColor, g_dwScreenSize);

break;

}

case 16:

{

iRed = (dwBackColor >> (16+3)) & 0x1f;

iGreen = (dwBackColor >> (8+2)) & 0x3f;

iBlue = (dwBackColor >> 3) & 0x1f;

wColor16bpp = (iRed << 11) | (iGreen << 5) | iBlue;

while (i < g_dwScreenSize)

{

*pwFB16bpp
= wColor16bpp;

pwFB16bpp++;

i += 2;

}

break;

}

case 32:

{

while (i < g_dwScreenSize)

{

*pdwFB32bpp
= dwBackColor;

pdwFB32bpp++;

i += 4;

}

break;

}

default :

{

DBG_PRINTF("can't support %d bpp\n", g_tFBVar.bits_per_pixel);

return -1;

}

}

return 0;

}

static int FBShowLine(int iXStart, int iXEnd, int iY, unsigned char *pucRGBArray)

{

int i = iXStart * 3;

int iX;

unsigned int dwColor;

if (iY >= g_tFBVar.yres)

return -1;

if (iXStart >= g_tFBVar.xres)

return -1;

if (iXEnd >= g_tFBVar.xres)

{

iXEnd = g_tFBVar.xres;

}

for (iX = iXStart; iX < iXEnd; iX++)

{

/* 0xRRGGBB */

dwColor = (pucRGBArray[i]<<16) + (pucRGBArray[i+1]<<8) + (pucRGBArray[i+2]<<0);

i += 3;

FBShowPixel(iX, iY, dwColor);

}

return 0;

}

/* 下面才是本文的重点 */

/*

Allocate and initialize a JPEG decompression object // 分配和初始化一个decompression结构体

Specify the source of the compressed data (eg, a file) // 指定源文件

Call jpeg_read_header() to obtain image info
// 用jpeg_read_header获得jpg信息

Set parameters for decompression // 设置解压参数,比如放大、缩小

jpeg_start_decompress(...); // 启动解压:jpeg_start_decompress

while (scan lines remain to be read)

jpeg_read_scanlines(...);
// 循环调用jpeg_read_scanlines

jpeg_finish_decompress(...); // jpeg_finish_decompress

Release the JPEG decompression object // 释放decompression结构体

*/

/* Uage: jpg2rgb <jpg_file>

*/

int main(int argc, char **argv)

{

struct jpeg_decompress_struct cinfo;

struct jpeg_error_mgr jerr;

FILE * infile;

int row_stride;

unsigned char *buffer;

if (argc != 2)

{

printf("Usage: \n");

printf("%s <jpg_file>\n", argv[0]);

return -1;

}

if (FBDeviceInit()) /* 初始化Lcd */

{

return -1;

}

FBCleanScreen(0); /* 清屏lcd */

// 分配和初始化一个decompression结构体

cinfo.err = jpeg_std_error(&jerr);

jpeg_create_decompress(&cinfo);

// 指定源文件

if ((infile = fopen(argv[1], "rb")) == NULL) {

fprintf(stderr, "can't open %s\n", argv[1]);

return -1;

}

jpeg_stdio_src(&cinfo, infile);

// 用jpeg_read_header获得jpg信息

jpeg_read_header(&cinfo, TRUE);

/* 源信息 */

printf("image_width = %d\n", cinfo.image_width);

printf("image_height = %d\n", cinfo.image_height);

printf("num_components = %d\n", cinfo.num_components);

// 设置解压参数,比如放大、缩小

printf("enter scale M/N:\n");

scanf("%d/%d", &cinfo.scale_num, &cinfo.scale_denom);

printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);

// 启动解压:jpeg_start_decompress

jpeg_start_decompress(&cinfo);

/* 输出的图象的信息 */

printf("output_width = %d\n", cinfo.output_width);

printf("output_height = %d\n", cinfo.output_height);

printf("output_components = %d\n", cinfo.output_components);

// 一行的数据长度

row_stride = cinfo.output_width * cinfo.output_components;

buffer = malloc(row_stride);

// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据

while (cinfo.output_scanline < cinfo.output_height)

{

(void) jpeg_read_scanlines(&cinfo, &buffer, 1);

// 写到LCD去

FBShowLine(0, cinfo.output_width, cinfo.output_scanline, buffer);

}

free(buffer);

jpeg_finish_decompress(&cinfo);

jpeg_destroy_decompress(&cinfo);

return 0;

}

上文中红色以下的才是本文的重点,lcd驱动才以前驱动部分已经讲得很明白了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: