⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 png.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
字号:
/* png.c * PNG decoding * (c) 2002 Karel 'Clock' Kulhavy * This is a part of the Links program, released under GPL. */#include "cfg.h"#ifdef G#include "links.h"#ifdef HAVE_ENDIAN_H#include <endian.h>#endif /* #ifdef HAVE_ENDIAN_H */#ifdef REPACK_16#undef REPACK_16#endif /* #ifdef REPACK_16 */#if SIZEOF_UNSIGNED_SHORT != 2#define REPACK_16#endif /* #if SIZEOF_UNSIGNED_SHORT != 2 */#ifndef REPACK_16#ifndef C_LITTLE_ENDIAN#ifndef C_BIG_ENDIAN#define REPACK_16#endif /* #ifndef C_BIG_ENDIAN */#endif /* #ifndef C_LITTLE_ENDIAN */#endif /* #ifndef REPACK_16 */	  /* Decoder structs *//* prototypes */void img_my_png_warning(png_structp, png_const_charp);void img_my_png_error(png_structp, png_const_charp);void png_info_callback(png_structp, png_infop);void a2char_from_unsigned_short(unsigned char *, unsigned short *, int);void unsigned_short_from_2char(unsigned short *, unsigned char *, int);void png_row_callback(png_structp, png_bytep, png_uint_32, int);void png_end_callback(png_structp, png_infop);/* Warning for from-web PNG images */void img_my_png_warning(png_structp a, png_const_charp b){}/* Error for from-web PNG images. */void img_my_png_error(png_structp png_ptr, png_const_charp error_string){	longjmp(png_ptr->jmpbuf,1);}void png_info_callback(png_structp png_ptr, png_infop info_ptr){	int bit_depth, color_type, intent;	double gamma;	int bytes_per_pixel=3;	struct cached_image *cimg;	cimg=global_cimg;	bit_depth=png_get_bit_depth(png_ptr, info_ptr);	color_type=png_get_color_type(png_ptr, info_ptr);	if (color_type == PNG_COLOR_TYPE_PALETTE)        	png_set_expand(png_ptr);    	if (color_type == PNG_COLOR_TYPE_GRAY &&        	bit_depth < 8) png_set_expand(png_ptr);	if (png_get_valid(png_ptr, info_ptr,        	PNG_INFO_tRNS)){		png_set_expand(png_ptr); /* Legacy version of		png_set_tRNS_to_alpha(png_ptr); */		bytes_per_pixel++;	}	if (color_type == PNG_COLOR_TYPE_GRAY ||		color_type == PNG_COLOR_TYPE_GRAY_ALPHA)		png_set_gray_to_rgb(png_ptr);	if (bit_depth==16){#ifndef REPACK_16#ifdef C_LITTLE_ENDIAN		/* We use native endianity only if unsigned short is 2-byte		 * because otherwise we have to reassemble the buffer so we		 * will leave in the libpng-native big endian.		 */		png_set_swap(png_ptr);#endif /* #ifdef C_LITTLE_ENDIAN */#endif /* #ifndef REPACK_16 */		bytes_per_pixel*=sizeof(unsigned short);	}	png_set_interlace_handling(png_ptr);	if (color_type==PNG_COLOR_TYPE_RGB_ALPHA		||color_type==PNG_COLOR_TYPE_GRAY_ALPHA){		if (bytes_per_pixel==3			||bytes_per_pixel==3*sizeof(unsigned short))			bytes_per_pixel=4*bytes_per_pixel/3;	}	cimg->width=png_get_image_width(png_ptr,info_ptr);	cimg->height=png_get_image_height(png_ptr,info_ptr);	cimg->buffer_bytes_per_pixel=bytes_per_pixel;	if (png_get_sRGB(png_ptr, info_ptr, &intent)){		gamma=sRGB_gamma;	}	else 	{                		if (!png_get_gAMA(png_ptr, info_ptr, &gamma)){			gamma=sRGB_gamma;		}	}	cimg->red_gamma=gamma;	cimg->green_gamma=gamma;	cimg->blue_gamma=gamma;	png_read_update_info(png_ptr,info_ptr);                 	cimg->strip_optimized=0;	header_dimensions_known(cimg);}/* Converts unsigned shorts to doublechars (in big endian) */void a2char_from_unsigned_short(unsigned char *chr, unsigned short *shrt, int len){	unsigned short s;	for (;len;len--,shrt++,chr+=2){		s=*shrt;		*chr=s>>8;		chr[1]=s;	}}/* Converts doublechars (in big endian) to unsigned shorts */void unsigned_short_from_2char(unsigned short *shrt, unsigned char *chr, int len){	unsigned short s;		for (;len;len--,shrt++,chr+=2){		s=((*chr)<<8)|chr[1];		*shrt=s;	}}void png_row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32	row_num, int pass){	struct cached_image *cimg;#ifdef REPACK_16	unsigned char *tmp;	int channels;#endif /* #ifdef REPACK_16 */	cimg=global_cimg;#ifdef REPACK_16	if (cimg->buffer_bytes_per_pixel>4)	{		channels=cimg->buffer_bytes_per_pixel/sizeof(unsigned			short);		if (PNG_INTERLACE_NONE==png_get_interlace_type(png_ptr,			((struct png_decoder *)cimg->decoder)->info_ptr))		{			unsigned_short_from_2char((unsigned short *)(cimg->buffer+cimg				->buffer_bytes_per_pixel *cimg->width				*row_num), new_row, cimg->width				*channels);		}else{			if ((unsigned)cimg->width > MAXINT / 2 / channels) overalloc();			tmp=mem_alloc(cimg->width*2*channels);			a2char_from_unsigned_short(tmp, (unsigned short *)(cimg->buffer				+cimg->buffer_bytes_per_pixel				*cimg->width*row_num), cimg->width*channels);			png_progressive_combine_row(png_ptr, tmp, new_row);			unsigned_short_from_2char((unsigned short *)(cimg->buffer				+cimg->buffer_bytes_per_pixel				*cimg->width*row_num), tmp, cimg->width*channels);			mem_free(tmp);		}	}else#endif /* #ifdef REPACK_16 */	{		png_progressive_combine_row(png_ptr,			cimg->buffer+cimg->buffer_bytes_per_pixel			*cimg->width*row_num, new_row);	}	cimg->rows_added=1;}void png_end_callback(png_structp png_ptr, png_infop info){	end_callback_hit=1;}/* Decoder structs */void png_start(struct cached_image *cimg){	png_structp png_ptr;	png_infop info_ptr;	struct png_decoder *decoder;	png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING,			NULL, img_my_png_error, img_my_png_warning);#ifdef DEBUG	if (!png_ptr) internal("png_create_read_struct failed\n");#endif /* #ifdef DEBUG */	info_ptr=png_create_info_struct(png_ptr);#ifdef DEBUG	if (!info_ptr) internal ("png_create_info_struct failed\n");#endif /* #ifdef DEBUG */	if (setjmp(png_ptr->jmpbuf)){error:		png_destroy_read_struct(&png_ptr, &info_ptr,			(png_infopp)NULL);		img_end(cimg);		return;	}	png_set_progressive_read_fn(png_ptr, NULL,				    png_info_callback, png_row_callback,				    png_end_callback);   	if (setjmp(png_ptr->jmpbuf)) goto error;	decoder=mem_alloc(sizeof(*decoder));	decoder->png_ptr=png_ptr;	decoder->info_ptr=info_ptr;	cimg->decoder=decoder;}void png_restart(struct cached_image *cimg, unsigned char *data, int length){	png_structp png_ptr;	png_infop info_ptr;#ifdef DEBUG	if (!cimg->decoder)		internal("decoder NULL in png_restart\n");#endif /* #ifdef DEBUG */	png_ptr=((struct png_decoder *)(cimg->decoder))->png_ptr;	info_ptr=((struct png_decoder *)(cimg->decoder))->info_ptr;	end_callback_hit=0;	if (setjmp(png_ptr->jmpbuf)){		img_end(cimg);		return;	}	png_process_data(png_ptr, info_ptr, data, length);	if (end_callback_hit) img_end(cimg);}#endif /* #ifdef G */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -