libjpeg使用

libjpeg-turbo:libjpeg.txt
——————/Outline of typical usage
//Allocate and initialize a JPEG decompression object
	struct jpeg_decompress_struct cinfo;
	struct jpeg_error_mgr jerr;
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_decompress(&cinfo);
//Specify the source of the compressed data (eg, a file)
FILE * infile;
if ((infile = fopen(filename, "rb")) == NULL)
{
	fprintf(stderr, "can't open %s\n", filename);
	exit(1);
}
jpeg_stdio_src(&cinfo, infile);
//Call jpeg_read_header() to obtain image info
	jpeg_read_header(&cinfo, TRUE);
//Set parameters for decompression
jpeg_start_decompress(...);
while (scan lines remain to be read)
	jpeg_read_scanlines(...);
jpeg_finish_decompress(...);
//Release the JPEG decompression object
	jpeg_destroy_decompress(&cinfo);
Before diving into procedural details, it is helpful to understand the image data format that the JPEG library expects or returns.
The standard input image format is a rectangular array of pixels, with each pixel having the same number of "component" or "sample" values (color channels). You must specify how many components there are and the colorspace interpretation of the components. Most applications will use RGB data (three components per pixel) or grayscale data (one component per pixel).
PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE.A remarkable number of people manage to miss this, only to find that their programs don't work with grayscale JPEG files.
——————/
jpeg_start_decompress(&cinfo);
printf("output_width = %d\n", cinfo.output_width);
……
启动解压后,output_width等变量才有值

unsigned int scale_num, scale_denom
Scale the image by the fraction scale_num/scale_denom. Default is
1/1, or no scaling. Currently, the only supported scaling ratios
are M/8 with all M from 1 to 16, or any reduced fraction thereof (such
as 1/2, 3/4, etc.) (The library design allows for arbitrary
scaling ratios but this is not likely to be implemented any time soon.)
Smaller scaling ratios permit significantly faster decoding since
fewer pixels need be processed and a simpler IDCT method can be used.
//但事实上,只有1/2、1/4、1/8可行
——————/
#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"
#define DBG_PRINTF printf

static int g_fd;
static struct fb_var_screeninfo g_tFBVar;
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 (g_fd<0)
	{
		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;
	}
	printf("LCD:xres=%d,yres=%d,bits_per_pixel=%d\n",g_tFBVar.xres,g_tFBVar.yres,
		g_tFBVar.bits_per_pixel);
	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 (g_pucFBMem<0)	
	{
		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;

	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 FBShowLine(int iXStart, int iXEnd, int iY, unsigned char *pucRGBArray)
{
	int i = iXStart * 3;
	int iX;
	unsigned int dwColor;
	
	if (iY >= g_tFBVar.xres)
		return;
	if (iXEnd >= g_tFBVar.yres)
	{
		iXEnd = g_tFBVar.yres;		
	}
	
	for (iX = iXStart; iX < iXEnd; iX++)
	{
		/* dwColor格式RRGGBB,pucRGBArray首元素RR */
		dwColor = (pucRGBArray[i]<<16) + (pucRGBArray[i+1]<<8) + (pucRGBArray[i+2]<<0);
		i += 3;
		FBShowPixel(iY,iX,dwColor);
	}
	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;
}

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())
	{
		printf("FBDeviceInit error\n");
		return -1;
	}
	FBCleanScreen(0);	//黑色	

	// 初始化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);
	// 获得jpg信息
	jpeg_read_header(&cinfo, TRUE);
	printf("%d,%d,%d\n", cinfo.image_width,cinfo.image_height,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(&cinfo);
	printf("%d,%d,%d\n",cinfo.output_width,cinfo.output_height,cinfo.output_components);
	// 一行的数据长度
	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = malloc(row_stride);
	// 一行一行获得解压的数据
	while (cinfo.output_scanline < cinfo.output_height) 
	{
		jpeg_read_scanlines(&cinfo, &buffer, 1);	//可多行,故buffer取址
		FBShowLine(0, cinfo.output_width, cinfo.output_scanline, buffer); // 写到LCD
	}
	free(buffer);
	jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	return 0;
}
root@lyl:/home/test# arm-linux-gcc libjpeg.c -o libjpeg -ljpeg
-I /home/libjpeg-turbo-1.2.1/tmp/include/ -I /home/libjpeg-turbo-1.2.1/tmp/lib/ -ljpeg

[root@FriendlyARM /test]# ./libjpeg 1080p.jpg
LCD:xres=800,yres=1280,bits_per_pixel=32
1920,1080,3
enter scale M/N:
1/1
scale to : 1/1
1920,1080,3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值