代码改变世界

libjpeg编译安装及使用说明

2017-07-04 10:18  sinohenu  阅读(1660)  评论(0)    收藏  举报

1.下载libjpeg源代码

2.解压、编译

进入解压代码根目录后,依次执行如下命令./configue ./make ./make check ./make install

3.make install后,libjpeg库的相关文件会安装到指定的文件夹下。

4.编写测试程序,主要是将jpeg图片解码成RGB后再转化为NV21格式。

#include <jpeglib.h>
#include <iostream>
using namespace std;

#define MIN(a,b)  ((a) > (b) ? (b) : (a))
#define MAX(a,b)  ((a) < (b) ? (b) : (a))
#define  MAKE_VALUE_0_255(y)    MIN(255,(MAX(0,(y)))) 

int Bgr_SemiYuv420(unsigned char *yDst,unsigned char *uvDst,unsigned char *bgrSrc,
                   unsigned int widthSrc,unsigned int heightSrc,unsigned int strideSrc)
{
	int b0,g0,r0,b1,g1,r1, b2,g2,r2,b3,g3,r3,y_4[4],u_4[4],v_4[4],i,j,w,h;
	unsigned char *ptr,*tempy0,*tempy1,*tempuv,*tempbgr0,*tempbgr1;
	unsigned char u,v;
	h=heightSrc>>1;
	w=widthSrc>>1;	
	 
	ptr=bgrSrc;
	for (i=0;i<h;i++)
	{ 
		tempy0=yDst+2*i*widthSrc;//
		tempy1=yDst+(2*i+1)*widthSrc;
		tempuv=uvDst+i*w*2;		
		tempbgr0=ptr+2*i*strideSrc;//bgr
		tempbgr1=ptr+(2*i+1)*strideSrc;//bgr
		
		for (j=0;j<w;j++)
		{
			r0=tempbgr0[0];
			g0=tempbgr0[1];
			b0=tempbgr0[2];
			r1=tempbgr0[3];
			g1=tempbgr0[4];
			b1=tempbgr0[5];

			r2=tempbgr1[0];
			g2=tempbgr1[1];
			b2=tempbgr1[2];
			r3=tempbgr1[3];
			g3=tempbgr1[4];
			b3=tempbgr1[5];



			y_4[0] = 76*r0+150*g0+29*b0;
			y_4[0] = MAKE_VALUE_0_255(y_4[0]>>8);
			u_4[0] = (182*(r0-y_4[0])+255*128) >> 8;
			v_4[0] = (144*(b0-y_4[0])+255*128) >> 8;

			y_4[1] = 76*r1+150*g1+29*b1;
			y_4[1] = MAKE_VALUE_0_255(y_4[1]>>8);
			u_4[1] = (182*(r1-y_4[1])+255*128) >> 8;
			v_4[1] = (144*(b1-y_4[1])+255*128) >> 8;

			y_4[2] = 76*r2+150*g2+29*b2;
			y_4[2] = MAKE_VALUE_0_255(y_4[2]>>8);
			u_4[2] = (182*(r2-y_4[2])+255*128) >> 8;
			v_4[2] = (144*(b2-y_4[2])+255*128) >> 8;

			y_4[3] = 76*r3+150*g3+29*b3;
			y_4[3] = MAKE_VALUE_0_255(y_4[3]>>8);
			u_4[3] = (182*(r3-y_4[3])+255*128) >> 8;
			v_4[3] = (144*(b3-y_4[3])+255*128) >> 8;
            

			u = (unsigned char)(MAKE_VALUE_0_255( (u_4[0]+u_4[1]+u_4[2]+u_4[3]) >> 2 ));
			tempy0[0] = (unsigned char)(y_4[0]);
			tempy0[1] = (unsigned char)(y_4[1]);
			v = (unsigned char)(MAKE_VALUE_0_255( (v_4[0]+v_4[1]+v_4[2]+v_4[3]) >> 2 ));
			tempy1[0] = (unsigned char)(y_4[2]);
			tempy1[1] = (unsigned char)(y_4[3]);

			tempy0+=2;
			tempy1+=2;
			tempbgr0+=6;
			tempbgr1+=6;
			tempuv[0]=u;
			tempuv[1]=v;
			tempuv+=2;
		}
	}
	return 0;
}
int main(int argc, char *argv[])
{
	char *filename;
	if(argc != 2)
		return -1;
	else
		filename = argv[argc -1];
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	FILE * infile;		/* source file */
	int row_stride;		/* physical row width in output buffer */
	if ((infile = fopen(filename, "rb")) == NULL) 
	{
		fprintf(stderr, "can't open %s\n", filename);
		return -1;
	}
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
	//jerr.addon_message_table = cdjpeg_message_table;
	//jerr.first_addon_message = JMSG_FIRSTADDONCODE;
	//jerr.last_addon_message = JMSG_LASTADDONCODE;

	jpeg_stdio_src(&cinfo, infile);

	(void) jpeg_read_header(&cinfo, TRUE);

	(void) jpeg_start_decompress(&cinfo);
	row_stride = cinfo.output_width * cinfo.output_components;
	cout << "cinfo.output_width:" <<  cinfo.output_width << ";cinfo.output_height:" << cinfo.output_height << endl; 
	cout << "jpeg_color_space:" << cinfo.jpeg_color_space << endl;
	cout << "out_color_space:" << cinfo.out_color_space << endl;
	int width = cinfo.output_width;
	int height = cinfo.output_height;
	unsigned char *data = new unsigned char [row_stride * cinfo.output_height];

	unsigned char * p;
	while (cinfo.output_scanline < cinfo.output_height) {
		p = (unsigned char *)data + row_stride * cinfo.output_scanline;
		(void) jpeg_read_scanlines(&cinfo, &p , 1);
		int i = 0;
		for(i = 0;i < row_stride;i+= 3)
		{
			unsigned char tmp;
			tmp = p[i];
			p[i] = p[i + 2];
			p[i + 2] = tmp;
		}
	}
	char *y=NULL;
	char *uv=NULL;
	y = new char[width*height];
    uv = new char[height*height];
	Bgr_SemiYuv420((unsigned char*)y,(unsigned char*)uv, (unsigned char *)data,
	width,height, row_stride);
	FILE *yuv_file = fopen("test.yuv", "wb");
	fwrite(y, width*height, 1, yuv_file);
	fwrite(uv, width*height/2, 1, yuv_file);
	fclose(yuv_file);
	delete [] uv;
	delete [] y;
	(void) jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	fclose(infile);
	delete [] data;
	return 0;
}

 CMakeList.txt内容如下:

PROJECT(sdk_video_samples)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_SKIP_RPATH TRUE)

SET(
	SDK_VIDEO_INCLUDE_DIR
	${CMAKE_CURRENT_SOURCE_DIR}/../include 
	CACHE PATH
	"SDK_VIDEO HEADER FILE PATH"
)

if(MSVC)
	SET(
	SDK_VIDEO_LIB_DIR
	${CMAKE_CURRENT_SOURCE_DIR}/../lib
	CACHE PATH
	"SDK_VIDEO LIBRARIES PATH"
	)
else()
	SET(
		SDK_VIDEO_LIB_DIR
		${CMAKE_CURRENT_SOURCE_DIR}/../lib
		CACHE PATH
		"SDK_VIDEO LIBRARIES PATH"
	)
endif()

MESSAGE("${SDK_VIDEO_LIB_DIR}")

INCLUDE_DIRECTORIES(
	${PROJECT_SOURCE_DIR}
	${SDK_VIDEO_INCLUDE_DIR}
)

LINK_DIRECTORIES(${SDK_VIDEO_LIB_DIR})

SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -O2 -std=gnu++0x")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -O2 -std=gnu++0x")

FILE(GLOB samples ${PROJECT_SOURCE_DIR}/*.cpp)

FOREACH (sample ${samples})
	STRING(REGEX MATCH "[^/]+$" sample_file ${sample})
	STRING(REPLACE ".cpp" "" sample_basename ${sample_file})
	ADD_EXECUTABLE(jpeg_${sample_basename} ${sample})
	TARGET_LINK_LIBRARIES(jpeg_${sample_basename} jpeg)
	if (NOT WIN32)
		TARGET_LINK_LIBRARIES(jpeg_${sample_basename} pthread)
	else()

	endif()

	INSTALL(TARGETS jpeg_${sample_basename} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin)
ENDFOREACH()

5.执行脚本,运行程序

export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH
./jpeg_test 1.jpg