libpng库的安装与使用(交叉编译)

进入http://sourceforge.net/projects/libpng/files/下载一个libpng稳定版本源码包


libpng-1.2.56.tar.gz 下载地址点击这里!


tar -xzvf libpng-1.2.56.tar.gz 

d libpng-1.2.56                         /* 可以使用.configure --help来查看帮助信息 */

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

make && make install

如果提示错误那么就需要安装zlib库文件,以前安装过现在就不安装了。

这是tmp目录下就生成bin  include  lib  share四个目录,这里我们只用到库文件和头文件,把库文件拷贝到开发板根文件系统,把库和头文件拷贝到交叉编译环境路径下。

我交叉编译环境如下:

/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     /* 库文件路径 */


到现在我们就安装好了Libpng库文件,接下来我们用一个示例文件来演示。

mypng.c文件如下:

#include<stdio.h>
#include<libpng12/png.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 ERROR -1
#define PNG_BYTES_TO_CHECK 4
#define FB_DEVICE_NAME "/dev/fb0"
//#define DBG_PRINTF printf
#define DBG_PRINTF(...)

#define HAVE_ALPHA 1
#define NO_ALPHA 0

static int g_lcd_fd;
FILE   *g_png_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_lcd_fd = open(FB_DEVICE_NAME, O_RDWR);
	if (0 > g_lcd_fd)
	{
		DBG_PRINTF("can't open %s\n", FB_DEVICE_NAME);
	}

	ret = ioctl(g_lcd_fd, FBIOGET_VSCREENINFO, &g_tFBVar);
	if (ret < 0)
	{
		DBG_PRINTF("can't get fb's var\n");
		return -1;
	}

	ret = ioctl(g_lcd_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_lcd_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;
}

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;
}

int check_if_png(char *file_name)
{
   char buf[PNG_BYTES_TO_CHECK];

   /* Open the prospective PNG file. */
   if ((g_png_fd = fopen(file_name, "rb")) == NULL)
   {
      printf("open %s  is fail\n",file_name);
		return 0;
   }
   /* Read in some of the signature bytes */
   if (fread(buf, 1, PNG_BYTES_TO_CHECK, g_png_fd) != PNG_BYTES_TO_CHECK)
      return 0;

   /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
      Return nonzero (true) if they match */
 
  /* Close the file */
   fclose(g_png_fd); 
   return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
}

int read_png_data(char *filepath)		/* 用于解码png图片 */
{
 png_bytep 		*row_pointers;
 png_structp 	png_ptr;
 png_infop  	info_ptr;
 int        	temp;
 int 			color_type,channels,i;
 int width,height,bit_depth,flag;
 
 g_png_fd = fopen(filepath, "rb");
 if(g_png_fd == NULL) /* 文件打开失败 */
 {
	return -1; 
 }

 /* 初始化各种结构 */
 png_ptr  = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
 info_ptr = png_create_info_struct(png_ptr);
 setjmp(png_jmpbuf(png_ptr)); // 这句很重要

 rewind(g_png_fd);
 /*开始读文件*/

 png_init_io(png_ptr, g_png_fd);
 // 读文件了
 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0);


 /*获取宽度,高度,位深,颜色类型*/
 channels      = png_get_channels(png_ptr, info_ptr); /*获取通道数*/
 width = png_get_image_width(png_ptr, info_ptr);
 height = png_get_image_height(png_ptr, info_ptr);
 bit_depth = png_get_bit_depth(png_ptr, info_ptr); /* 获取位深 */
 color_type    = png_get_color_type(png_ptr, info_ptr); /*颜色类型*/
 
 /* row_pointers里边就是rgba数据 */


 row_pointers = png_get_rows(png_ptr, info_ptr);
 
 if(channels == 4 || color_type == PNG_COLOR_TYPE_RGB_ALPHA)
 {/*如果是RGB+alpha通道,或者RGB+其它字节*/ 
  flag = HAVE_ALPHA;    /* 标记 */
 
  temp = (4 * width);/* 每行有4 * out->width个字节 */
  
  for(i = 0; i < height; i++)
	{
		FBShowLine(0, temp, height, &row_pointers[i]);
	}
 }
 else if(channels == 3 || color_type == PNG_COLOR_TYPE_RGB)
 {/* 如果是RGB通道 */
	flag = NO_ALPHA;    /* 标记 */
 	printf("width=%d\n",width);
	printf("height=%d\n",height);
	printf("bit_depth=%d\n",bit_depth);
  temp = (3 * width);/* 每行有3 * out->width个字节 */
  printf("row_pointers=%d\n",sizeof(row_pointers));
  int j;
  for(i = 0; i <height; i++)
  {	
	FBShowLine(0, temp, i, &row_pointers[i]);
	
	for(j=0;j<temp;j+=3)
	{
		DBG_PRINTF("row_pointers[%d][%d]=0x%x\n",i,j,row_pointers[i][j]);
		DBG_PRINTF("row_pointers[%d][%d]=0x%x\n",i,j+1,row_pointers[i][j+1]);
		DBG_PRINTF("row_pointers[%d][%d]=0x%x\n",i,j+2,row_pointers[i][j+2]);
	}

  }

 }
 else 
	 return -1;
 
 /* 撤销数据占用的内存 */
 png_destroy_read_struct(&png_ptr, &info_ptr, 0); 
 return 0;
}

int main(int argc,char **argv)
{
	int i;
	if(argc!=2)
	{
		DBG_PRINTF("Usage: \n");
		DBG_PRINTF("%s <png_file>\n", argv[0]);
		return -1;
	}

	if (FBDeviceInit())
	{
		return -1;
	}

	FBCleanScreen(0);

	i=check_if_png(argv[1]);
	if(i==0)
	{
		DBG_PRINTF("this is not png image file\n");
	}
	
	read_png_data(argv[1]);

	return 0;
}

这样就可以在LCD上显示png图片了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HeroKern

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值