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

📄 png_dec.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / image format module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "img_in.h"#ifdef GPAC_HAS_PNG#include "png.h"typedef struct{	/*io part for PNG lib*/	void *in_data;	u32 in_length, current_pos;	/*no support for scalability with PNG yet*/	u16 ES_ID;	u32 BPP, width, height, out_size, pixel_format;} PNGDec;	#define PNGCTX()	PNGDec *ctx = (PNGDec *) ((IMGDec *)ifcg->privateStack)->opaquestatic GF_Err PNG_AttachStream(GF_BaseDecoder *ifcg, u16 ES_ID, char *decSpecInfo, u32 decSpecInfoSize, u16 DependsOnES_ID, u32 objectTypeIndication, Bool UpStream){	PNGCTX();	if (ctx->ES_ID && ctx->ES_ID!=ES_ID) return GF_NOT_SUPPORTED;	ctx->ES_ID = ES_ID;	return GF_OK;}static GF_Err PNG_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID){	PNGCTX();	if (ctx->ES_ID != ES_ID) return GF_BAD_PARAM;	ctx->ES_ID = ES_ID;	return GF_OK;}static GF_Err PNG_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability){	PNGCTX();	switch (capability->CapCode) {	case GF_CODEC_WIDTH:		capability->cap.valueInt = ctx->width;		break;	case GF_CODEC_HEIGHT:		capability->cap.valueInt = ctx->height;		break;	case GF_CODEC_STRIDE:		capability->cap.valueInt = ctx->width * ctx->BPP;		break;	case GF_CODEC_FPS:		capability->cap.valueFloat = 0;		break;	case GF_CODEC_PIXEL_FORMAT:		capability->cap.valueInt = ctx->pixel_format;		break;	case GF_CODEC_OUTPUT_SIZE:		capability->cap.valueInt = 	ctx->out_size;		break;	case GF_CODEC_BUFFER_MIN:		capability->cap.valueInt = 0;		break;	case GF_CODEC_BUFFER_MAX:		capability->cap.valueInt = IMG_CM_SIZE;		break;	case GF_CODEC_PADDING_BYTES:		capability->cap.valueInt = 0;		break;	default:		return GF_NOT_SUPPORTED;	}	return GF_OK;}static GF_Err PNG_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability){	/*return unsupported to avoid confusion by the player (like color space changing ...) */	return GF_NOT_SUPPORTED;}static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length){	PNGDec *ctx = (PNGDec *)png_ptr->io_ptr;	if (ctx->current_pos + length > ctx->in_length) {		png_error(png_ptr, "Read Error");	} else {		memcpy(data, (char*) ctx->in_data + ctx->current_pos, length);		ctx->current_pos += length;	}}static void user_error_fn(png_structp png_ptr,png_const_charp error_msg){	longjmp(png_ptr->jmpbuf, 1);}static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg, 		char *inBuffer, u32 inBufferLength,		u16 ES_ID,		char *outBuffer, u32 *outBufferLength,		u8 PaddingBits, u32 mmlevel){	png_struct *png_ptr;	png_info *info_ptr;	png_byte **rows;	u32 i, stride;	PNGCTX();	if ((inBufferLength<8) || png_sig_cmp(inBuffer, 0, 8) ) return GF_NON_COMPLIANT_BITSTREAM;	ctx->in_data = inBuffer;	ctx->in_length = inBufferLength;	ctx->current_pos = 0;	png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) ctx, NULL, NULL);	if (!png_ptr) return GF_IO_ERR;	info_ptr = png_create_info_struct(png_ptr);	if (info_ptr == NULL) {		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);		return GF_IO_ERR;	}	if (setjmp(png_ptr->jmpbuf)) {		png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);		return GF_IO_ERR;	}    png_set_read_fn(png_ptr, ctx, (png_rw_ptr) user_read_data);	png_set_error_fn(png_ptr, ctx, (png_error_ptr) user_error_fn, NULL);	png_read_info(png_ptr, info_ptr);	/*unpaletize*/	if (info_ptr->color_type==PNG_COLOR_TYPE_PALETTE) {		png_set_expand(png_ptr);		png_read_update_info(png_ptr, info_ptr);	}	if (info_ptr->num_trans) {		png_set_tRNS_to_alpha(png_ptr);		png_read_update_info(png_ptr, info_ptr);	}	ctx->BPP = info_ptr->pixel_depth / 8;	ctx->width = info_ptr->width;	ctx->height = info_ptr->height;	switch (ctx->BPP) {	case 1:		ctx->pixel_format = GF_PIXEL_GREYSCALE;		break;	case 2:		ctx->pixel_format = GF_PIXEL_ALPHAGREY;		break;	case 3:		ctx->pixel_format = GF_PIXEL_RGB_24;		break;	case 4:		ctx->pixel_format = GF_PIXEL_RGBA;		break;	}	/*new cfg, reset*/	if (ctx->out_size != ctx->width * ctx->height * ctx->BPP) {		ctx->out_size = ctx->width * ctx->height * ctx->BPP;		*outBufferLength = ctx->out_size;		png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);		png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);		return GF_BUFFER_TOO_SMALL;	}	/*read*/	stride = png_get_rowbytes(png_ptr, info_ptr);	rows = (png_bytepp) malloc(sizeof(png_bytep) * ctx->height);	for (i=0; i<ctx->height; i++) {		rows[i] = outBuffer + i*stride;	}	png_read_image(png_ptr, rows);	png_read_end(png_ptr, NULL);	free(rows);	png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr);	png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);	*outBufferLength = ctx->out_size;		return GF_OK;}static const char *PNG_GetCodecName(GF_BaseDecoder *dec){	return "LibPNG " PNG_LIBPNG_VER_STRING;}Bool NewPNGDec(GF_BaseDecoder *ifcd){	IMGDec *wrap = (IMGDec *) ifcd->privateStack;	PNGDec *dec = (PNGDec *) malloc(sizeof(PNGDec));	memset(dec, 0, sizeof(PNGDec));	wrap->opaque = dec;	wrap->type = DEC_PNG;	/*setup our own interface*/		ifcd->AttachStream = PNG_AttachStream;	ifcd->DetachStream = PNG_DetachStream;	ifcd->GetCapabilities = PNG_GetCapabilities;	ifcd->SetCapabilities = PNG_SetCapabilities;	ifcd->GetName = PNG_GetCodecName;	((GF_MediaDecoder *)ifcd)->ProcessData = PNG_ProcessData;	return 1;}void DeletePNGDec(GF_BaseDecoder *ifcg){	PNGCTX();	free(ctx);}#endif

⌨️ 快捷键说明

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