栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

LIBPNG库移植

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LIBPNG库移植

一、libpng库和zlib依赖库下载路径

        注意:libpng使用需要用到zlib库,因此需要安装zlip库

        libpng库链接:https://libpng.sourceforge.io/index.html

        zlib库链接:https://libpng.sourceforge.io/index.html

二、ubuntu上安装libpng     

        解压:tar -xzvf libpng-1.6.37.tar.gz && cd libpng-1.6.37

        解压后的文件目录如下图                        

        下一步进行libpng安装

        ./configure && make && make install

三、ubuntu上安装zlib        

        解压:tar -xzvf zlib-1.2.11.tar.gz && cd zlib-1.2.11

        解压后的文件目录如下图

        下一步进行zlib安装

        ./configure && make && make install

四、在ubuntu系统上验证将png解码为rgb

        参考库自带的sample-png2pnm.c并简写,代码如下:

#include 
#include 
#include 
#include 
#include "png.h"

#ifndef BOOL
#define BOOL unsigned char
#endif
#ifndef TRUE
#define TRUE (BOOL) 1
#endif
#ifndef FALSE
#define FALSE (BOOL) 0
#endif



BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,
              BOOL raw, BOOL alpha);


int main (int argc, char *argv[])
{
	FILE *fp_rd = stdin;
	FILE *fp_wr = stdout;
	FILE *fp_al = NULL;
	BOOL raw = TRUE;
	BOOL alpha = FALSE;

	if((fp_rd = fopen ("test.png", "rb")) == NULL){
		printf("fopen png errorn");
		exit (1);
	}

	if ((fp_wr = fopen ("test.rgb", "wb")) == NULL){
		printf("fopen rgb errorn");
		exit (1);
	}

	printf("%d %dn",alpha,raw);

	if (png2pnm (fp_rd, fp_wr, fp_al, 1, 0) == FALSE){
		printf("decode rgb errorn");
		exit (1);
	}

	fclose (fp_rd);
	fclose (fp_wr);

	return 0;
}

BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file,BOOL raw, BOOL alpha)
{
	png_struct    *png_ptr = NULL;
	png_info      *info_ptr = NULL;
	png_byte      buf[8];
	png_byte      *png_pixels = NULL;
	png_byte      **row_pointers = NULL;
	png_byte      *pix_ptr = NULL;
	png_uint_32   row_bytes;

	png_uint_32   width;
	png_uint_32   height;
	int           bit_depth;
	int           channels;
	int           color_type;
	int           row, col;
	int           ret;
	int           i;

	struct  timeval  start;
    struct  timeval  end1;
	struct  timeval  end2;
    unsigned long timer;

	gettimeofday(&start,NULL);

	
	ret = fread (buf, 1, 8, png_file);
	if (ret != 8){
		return FALSE;
	}	

	ret = png_sig_cmp (buf, 0, 8);
	if (ret != 0){
		return FALSE;
	}

  

 	png_ptr = png_create_read_struct (png_get_libpng_ver(NULL),NULL, NULL, NULL);
	if (!png_ptr){
    	return FALSE;
	}

	info_ptr = png_create_info_struct (png_ptr);
	if (!info_ptr){
    	png_destroy_read_struct (&png_ptr, NULL, NULL);
    	return FALSE; 
	}

	if (setjmp (png_jmpbuf (png_ptr))){
		png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
		return FALSE;
	}

	
	png_init_io (png_ptr, png_file);
	png_set_sig_bytes (png_ptr, 8); 

	
	png_read_info (png_ptr, info_ptr);

	
	png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,NULL, NULL, NULL);
	
	
	png_read_update_info (png_ptr, info_ptr);

	
	png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,NULL, NULL, NULL);

	printf("width:%d height:%d bit_depth:%d color_type:%dn",width,height,bit_depth,color_type);


	
	if (color_type == PNG_COLOR_TYPE_GRAY){
		channels = 1;
	}else if(color_type == PNG_COLOR_TYPE_GRAY_ALPHA){
		channels = 2;
	}else if (color_type == PNG_COLOR_TYPE_RGB){
		channels = 3;
	}else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA){
		channels = 4;
	}else{
		channels = 0; 
	}


	gettimeofday(&end1,NULL);


	
	row_bytes = png_get_rowbytes (png_ptr, info_ptr);

	timer = 1000000 * (end1.tv_sec-start.tv_sec)+ end1.tv_usec-start.tv_usec;
    printf("timer = %ld usn",timer);

	printf("row_bytes :%dn",row_bytes);

	if ((png_pixels = (png_byte *) malloc ((size_t) row_bytes * (size_t) height)) == NULL){
		png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
		return FALSE;
	}

	if ((row_pointers = (png_byte **)malloc ((size_t) height * sizeof (png_byte *))) == NULL){
		png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
		free (png_pixels);
		return FALSE;
	}

	
	for (i = 0; i < ((int) height); i++){
		row_pointers[i] = png_pixels + i * row_bytes;
	}


	
	png_read_image (png_ptr, row_pointers);

	gettimeofday(&end2,NULL);

	timer = 1000000 * (end2.tv_sec-end1.tv_sec)+ end2.tv_usec-end1.tv_usec;
    printf("timer = %ld usn",timer);


	
	png_read_end (png_ptr, info_ptr);

	
	png_destroy_read_struct (&png_ptr, &info_ptr, NULL);

	
	pix_ptr = png_pixels;

	printf("raw:%d,channels:%dn",raw,channels);

	for (row = 0; row < (int) height; row++){
		for (col = 0; col < (int) width; col++){
			for (i = 0; i < channels; i++){
		          fputc (*pix_ptr++, pnm_file);
			}
      	}
  	}

	if (row_pointers != NULL){
		free (row_pointers);
	}
	if (png_pixels != NULL){
		free (png_pixels);
	}


	return TRUE;

}

        结果如下(注意我的代码只适用于PNG24和PNG8(项目需要),PNG32或PNG16需要添加一点代码,这里自己可以去看sample:

五、往其它架构的嵌入式开发板上移植libpng

        libpng已经帮我们提供了只用于解码或者编码的源文件

        cd contrib/pngminim目录,选择需要使用libpng的功能

        例如这里我只需要使用解码功能,cd decoder && make,这里会提示你缺少zlib库的文件,如下图

        需要你把zlib库里面的源文件和头文件依次拷贝到decoder目录下,这里缺少的文件有:

zlib.h、crc32.h、inffast.h、inffixed.h、inflate.h、inftrees.h、zutil.h、zconf.h、adler32.c、crc32.c、inffast.c、inflate.c、inftrees.c、zutil.c

        将缺少的源文件和头文件拷贝,进行make,生成png2pnm可执行程序,如下图:

        目录里面的源文件和头文件即解码需要的所有源文件和头文件,后续可以根据嵌入式平台配置不同的交叉编译工具进行编译,encoder同decoder步骤 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/932089.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号