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

📄 png_decoder.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* DESCRIPTION
*	start to parse the first IDAT chunk
*
* PARAMETERS
*	len: length of the first IDAT chunk
*
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_IDAT_Handler(kal_uint32 len)
{
	if(!(png_dcb.flags & PNG_HAVE_IHDR))
		PNG_RAISE(1);
	png_dcb.flags |= PNG_HAVE_IDAT;
	png_decode_hw(len);
}
/*************************************************************************
* FUNCTION
*  png_decode_process
*
* DESCRIPTION
*	start to parse the PNG image.
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_decode_process(void)
{	
	kal_uint8 buf[8];

	PNG_GET_ARRAY(buf,8);
	if(kal_mem_cmp(buf, png_signature, 8)!= 0)
		PNG_RAISE(1);
	
	while(PNG_IS_EOF()!= KAL_TRUE)
	{
		kal_uint32 len;
		
		len = PNG_GET_U32();	
		png_crc_reset();
		png_crc_read(buf,4);
		if(!kal_mem_cmp(buf,png_IHDR,4))
		{
			png_IHDR_Handler(len);
		}
		else if(!kal_mem_cmp(buf,png_PLTE,4))
		{
			png_PLTE_Handler(len);
		}
		else if(!kal_mem_cmp(buf,png_tRNS,4))
		{
			png_tRNS_Handler(len);
		}
		else if(!kal_mem_cmp(buf,png_IDAT,4))
		{
			png_IDAT_Handler(len);
			return ;
		}
		else if(!kal_mem_cmp(buf,png_bKGD,4))
		{
			png_bKGD_Handler(len);
		}
		else if(!kal_mem_cmp(buf,png_IEND,4))
		{
			PNG_RAISE(1);
		}
		else
		{
			PNG_FLUSH(len+PNG_CRC_LEN);
		}
	}
	PNG_RAISE(1);
	//return PNG_FORMAT_ERROR;	
}
/*************************************************************************
* FUNCTION
*  png_hisr_entry
*
* DESCRIPTION
*	1. hisr entry function of the PNG interrupt
*	2. calling the callback function registered by the caller
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_hisr_entry(void)
{
	kal_uint32 status;
	png_report_status_enum report;
	
	PNG_STOP_TIMER();
	status = DRV_Reg(PNG_IRQ_STATUS);
	png_dcb.status = status;
	if(status == PNG_IRQ_STATUS_IMG_COMPLETE)
	{
		//1:  check the ADLER checksum
		report = PNG_FINISH_IMAGE;
		png_state = PNG_STATE_READY;
		PNG_RESET();
	}
	else if(status == PNG_IRQ_STATUS_BLOCK_END)
	{		
		if( DRV_Reg(PNG_DECODE_EN)== 0 )
			DRV_WriteReg(PNG_DECODE_EN, 1);
		report = PNG_BLOCK_END;
	}	
	else if(status == PNG_IRQ_STATUS_IN_EMPTY)
	{		
		report = PNG_INPUT_EMPTY;
	}
	else
	{
		report = PNG_FORMAT_ERROR;
		png_state = PNG_STATE_READY;
		PNG_RESET();
	}
	png_dcb.cb(report);
	DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);
	IRQUnmask(IRQ_PNG_CODE);
}
/*************************************************************************
* FUNCTION
*  png_lisr_entry
*
* DESCRIPTION
*	lisr entry function of the png interrupt
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_lisr_entry(void)
{
	IRQMask(IRQ_PNG_CODE);
	//kal_activate_hisr(png_hisr);
	visual_active_hisr(VISUAL_PNG_HISR_ID);	
}
/*************************************************************************
* FUNCTION
*  png_init
*
* DESCRIPTION
*	Initialization of the driver of the PNG decoder
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
void png_init(void)
{
	if(png_hisr == 0)
	{
   	//png_hisr = kal_create_hisr("PNG_HISR",2,512,png_hisr_entry,NULL);
   	VISUAL_Register_HISR(VISUAL_PNG_HISR_ID,png_hisr_entry);
   	png_hisr=VISUAL_PNG_HISR_ID;
   	IRQ_Register_LISR(IRQ_PNG_CODE, png_lisr_entry,"png_lisr");
   	IRQSensitivity(IRQ_PNG_CODE,LEVEL_SENSITIVE);   	
	}
	if(png_gpt_handle == 0)
		GPTI_GetHandle(&png_gpt_handle);
	png_state = PNG_STATE_READY;
	IRQUnmask(IRQ_PNG_CODE);			
}
/*************************************************************************
* FUNCTION
*  png_decode_start
*
* DESCRIPTION
*	1. start to decode a PNG image (async interface )
*	2. calling the callback function while the PNG interrupt is generated or
*		GPT timer is expired		
*
* PARAMETERS
*	cfg:	configuration of the driver of PNG decoder
*	info: information of the decoded PNG image
*
* RETURNS
*	PNG_DECODING: the driver is decoding the PNG image without any error
*	PNG_FORMAT_ERROR: the input PNG image is invalid
*
* GLOBALS AFFECTED
*	
*************************************************************************/
png_report_status_enum png_decode_start_hw(png_config_struct *cfg, png_inform_struct *info)
{
	png_report_status_enum status;
	
	ASSERT(png_state == PNG_STATE_READY);
	png_state = PNG_STATE_BUSY;	
	ASSERT(cfg->cb != NULL);
	
	kal_mem_set(&png_dcb, 0, sizeof(png_dcb));
	png_dcb.cb = cfg->cb;
	png_dcb.cfg = cfg;
	if(cfg->decode_mode == PNG_DECODE_FILE)
	{
		// reserve 4 bytes for the partial input limiation
		png_dcb.file_size = hw_bytestream_create_file(HW_BYTESTREAM_PNG, 
			cfg->file_handle,
			(kal_uint8*)(cfg->in_buffer_adrs), 
			cfg->in_buffer_size);
		if(png_dcb.file_size)
		{
			//png_dcb.in_count = png_dcb.file_size;
			if(png_dcb.file_size > cfg->in_buffer_size)
				png_dcb.partial_en = KAL_TRUE;			
		}
		else
		{
			png_state = PNG_STATE_READY;
			status = PNG_FORMAT_ERROR;
			goto end;
		}
	}
	else // the total file is in the memory
	{
		hw_bytestream_create(HW_BYTESTREAM_PNG,(kal_uint8*)cfg->in_buffer_adrs,cfg->in_buffer_size);
 		png_dcb.file_size = cfg->in_buffer_size;
 		// png_dcb.in_count = png_dcb.file_size;
	}
	png_dcb.timeout_period = cfg->png_timeout_period;
	status = PNG_DECODING;
	PNG_TRY
	png_decode_process();
	PNG_CATCH_BEGIN
	png_state = PNG_STATE_READY;		
	status = PNG_FORMAT_ERROR;
	PNG_CATCH_END
	//if(info->use_work_buf == KAL_TRUE)
		//status = PNG_USE_G2D;
	kal_mem_cpy(info, &png_dcb.info, sizeof(png_inform_struct) );
end:
	
	return status;		
}
/*************************************************************************
* FUNCTION
*  png_decode_resume
*
* DESCRIPTION
*	1. keep decoding the remaing PNG images
*	2. calling the callback function while the PNG interrupt is generated or
*		GPT timer is expired		
*
* PARAMETERS
*	
* RETURNS
*	PNG_DECODING: the driver is decoding the PNG image without any error
*	PNG_FORMAT_ERROR: the input PNG image is invalid
*	PNG_FINISH_IMAGE: the total image has been decoded successfully
*
* GLOBALS AFFECTED
*	
*************************************************************************/
png_report_status_enum png_decode_resume(void)
{
	kal_uint32 status;
	png_report_status_enum report;

	ASSERT(png_state == PNG_STATE_BUSY);
	DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);	
	status = png_dcb.status;
	report = PNG_DECODING;
	
	PNG_TRY
	if(status == PNG_IRQ_STATUS_BLOCK_END)
	{
		if(!png_dcb.is_IEND)
		{
			png_assemble_idat();			
			DRV_WriteReg32(PNG_IN_START, png_idat_buf);
			DRV_WriteReg32(PNG_IN_COUNT, idat_buf_len+4);
			if(png_dcb.z_count >= 4)
			{
				DRV_WriteReg32(PNG_IDAT_COUNT, png_dcb.z_count);
			}
			else if(png_dcb.z_count > 0)
			{
				kal_uint32 reg,i;
				kal_uint8 *ptr = (kal_uint8*)png_idat_buf;
				
				for(reg=0,i=0; i<png_dcb.z_count; i++)
				{
					 reg |= (ptr[i] << (8*i));
				}
				DRV_WriteReg32(PNG_IDAT_BUFFER, reg);
				DRV_WriteReg32(PNG_IDAT_COUNT, png_dcb.z_count);
			}	
			else
				DRV_WriteReg32(PNG_IDAT_COUNT, idat_buf_len);
			
			PNG_RESUME();
		}
		else
		{
			PNG_RESET();
			png_state = PNG_STATE_READY;
			report =  PNG_FINISH_IMAGE;
		}
	}
	else if(status == PNG_IRQ_STATUS_IN_EMPTY)
	{
		PNG_RAISE(1);
	}
	PNG_CATCH_BEGIN
	png_state = PNG_STATE_READY;				
	report = PNG_FORMAT_ERROR;
	PNG_CATCH_END

	return report;	
}
/*************************************************************************
* FUNCTION
*  png_decode_stop
*
* DESCRIPTION
*	stop decoding the PNG image (abort in the meddle of the decoding process)
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
void png_decode_stop_hw(void)
{
	png_state = PNG_STATE_READY;
	
	DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);
	IRQMask(IRQ_PNG_CODE);
	DRV_WriteReg32(PNG_IRQ_EN, 0);
	PNG_RESET();
	IRQUnmask(IRQ_PNG_CODE);
	DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_PNG,PDN_PNG);	
}
#endif //USE_HW_PNG_DECODER_V1

//------------------------------------------------------------------------//
//							Unit Test Code 												  //	
//------------------------------------------------------------------------//
#if defined (PNG_MODULE_BURN_TEST)
#undef PNG_UNIT_TEST
// --------------------remove --------------------------//
#define MT6228_BURNING_SYSRAM_SIZE  128*1024
#pragma arm section zidata = "SYSRAMZI"
__align(4) kal_uint8 g_burning_sysram[MT6228_BURNING_SYSRAM_SIZE];
#pragma arm section zidata
kal_bool g_burning_sysram_ready = KAL_TRUE;

kal_uint8* drvtest_get_sysram(kal_uint32 *p_size)
{
	if(g_burning_sysram_ready == KAL_FALSE)
	{
		while(1);	
	}
	
	*p_size = MT6228_BURNING_SYSRAM_SIZE;
	
	g_burning_sysram_ready = KAL_FALSE;
	
	return g_burning_sysram;
}

void drvtest_release_sysram(void)
{
	g_burning_sysram_ready = KAL_TRUE;
}
// --------------------remove --------------------------//

kal_eventgrpid my_Events;
png_report_status_enum cb_status;
png_config_struct png_config;
png_inform_struct png_info;
volatile kal_bool png_stop_now = KAL_FALSE;

#define MY_GET_BUF(a,b,c)		a = (kal_uint32*)b; b += (c);
#define PNG_OUTPUT_SIZE		(sizeof basn6a08_result)

void png_callback(png_report_status_enum status)
{
	cb_status = status;
	kal_set_eg_events(my_Events,1,KAL_OR);		
}

#include "basn6a08.c"
#include "basn6a08_result.c"
kal_bool png_module_burn_test(void)
{	
	png_config_struct *p = &png_config;
	png_report_status_enum status;
	kal_uint32 flag,bytes,buf_size;
	kal_uint8 *buffer;
	extern kal_uint8* drvtest_get_sysram(kal_uint32 *p_size);
	extern void drvtest_release_sysram(void);

	png_init();
	my_Events = kal_create_event_group("my Events");
	
	p->in_buffer_adrs = (kal_uint32)basn6a08;
	p->in_buffer_size = sizeof basn6a08 ;

	buffer = drvtest_get_sysram(&buf_size);
	p->output_buffer_adrs = (kal_uint32)buffer;
	buffer += PNG_OUTPUT_SIZE;
	p->output_buffer_size = PNG_OUTPUT_SIZE+1024;

	MY_GET_BUF(p->hclen, buffer, HCLEN_LEN);
	MY_GET_BUF(p->hlen, buffer, HLEN_LEN);
	MY_GET_BUF(p->hlit, buffer, HLIT_LEN);
	MY_GET_BUF(p->hdist, buffer, HDIST_LEN);
	MY_GET_BUF(p->buff0, buffer, BUFF0_LEN);
	MY_GET_BUF(p->buff1, buffer, BUFF1_LEN);
	MY_GET_BUF(p->LZ77, buffer, LZ77_LEN);
	MY_GET_BUF(p->color_table, buffer, 1024);
	MY_GET_BUF(p->color_table_t, buffer, 256);
	
	p->shadow_w = 32;
	p->shadow_h = 32;
	p->clip_x1 = 0;
	p->clip_y1 = 0;
	p->clip_x2 = 32;
	p->clip_y2 = 32;
	p->dest_x = 0;
	p->dest_y = 0;

	p->expect_w = 0;
	p->expect_h = 0;
	
	p->clip_en = KAL_FALSE;
	p->out_format = RGB888;
	p->cb = png_callback;
	
	status = png_decode_start(p, &png_info);
	if(status ==  PNG_FORMAT_ERROR)
		goto end;		
	kal_retrieve_eg_events(my_Events,(1),KAL_OR_CONSUME,&flag,KAL_SUSPEND);			
	while(1)
	{
		if (cb_status == PNG_BLOCK_END)
		{
			if(!png_stop_now)
			{
				status = png_decode_resume();
				if(status == PNG_DECODING)
					kal_retrieve_eg_events(my_Events,(1),KAL_OR_CONSUME,&flag,KAL_SUSPEND);										
				else if(status == PNG_FINISH_IMAGE)
				{
					goto end;
				}
				else
				{
					goto end;
				}
			}
			else
			{
				png_decode_stop();
				goto end;
			}				
		}
		else if(cb_status == PNG_INPUT_EMPTY)
		{
			ASSERT(0);
		}
		else if(cb_status == PNG_FINISH_IMAGE)
		{
			ASSERT(0);
			goto end;
		}
		else	// PNG_DECODE_TIMEOUT, PNG_FORMAT_ERROR			
		{				
			png_decode_stop();
			break;
		}				
	}

end:	
	drvtest_release_sysram();
	// compare the result
	if(memcmp((kal_uint8*)p->output_buffer_adrs, basn6a08_result, PNG_OUTPUT_SIZE))
	{
		return KAL_FALSE;
	}
	else
	{
		return KAL_TRUE;
	}
	
}

void png_test_main(void)
{
	png_module_burn_test();
}

#endif // PNG_MODULE_BURN_TEST
// #define PNG_UINT_TEST
#if defined (PNG_UINT_TEST)
#include "lcd_if.h"
#include "lcd_sw.h"
#include "lcd_sw_inc.h"
#include "msdc_def.h"
#include "sd_def.h"
#include "rtfiles.h"

// unit test code start here
//#define FILE_BUFFER_SIZE		(16*1024)
#define FILE_BUFFER_SIZE		(16*1024)
#define OUT_BUFFER_SIZE			(LCD_WIDTH*LCD_HEIGHT*2)

kal_uint32 hdist[HDIST_LEN/4];
kal_uint32 hlit[HLIT_LEN/4];
kal_uint32 LZ77[LZ77_LEN/4];
kal_uint32 hclen[HCLEN_LEN/4];
kal_uint32 hlen[HLEN_LEN/4];
kal_uint32 buff0[BUFF0_LEN/4];
kal_uint32 buff1[BUFF1_LEN/4];
kal_uint32 color_table[CT_LEN];
kal_uint32 color_table_t[CT_LEN];	// transparent pallete

png_internal_buffer_struct png_buffers = 	{hclen, 
	hlen, hlit, hdist, buff0, 
	buff1,LZ77, color_table, color_table_t};

kal_uint8 in_buffer[FILE_BUFFER_SIZE];
kal_uint16 lcd_buffer[LCD_WIDTH*LCD_HEIGHT];

kal_uint8 file_name[256];
kal_wchar file_name_w[256];
kal_uint32 file_size;

kal_eventgrpid my_Events;
png_report_status_enum cb_status;
png_config_struct png_config;
png_inform_struct png_info;
volatile kal_bool png_stop_now = KAL_FALSE;

static kal_uint32 t1, t2;
void GPT3_Init_my(void)
{
	// clear pdn bit of GPT
	DRV_Reg(0x80000324) = 1;
	// set clock
	DRV_Reg(0x80100024) = 0; // 16k Hz
	// start free running
	DRV_Reg(0x8010001c) = 1;	
}


kal_uint32 GPT3_GetCount(void)
{
	volatile kal_uint32 t;

	t = DRV_Reg(0x80100020);
	return t;
}

kal_uint32 GPT3_TimeDiff(kal_uint32 time1)
{
	kal_uint32 time2;

	time2 = DRV_Reg(0x80100020);
	if(time2 >= time1)
		return (time2 - time1);
		
	return (0xffff - time1 + time2);
}

⌨️ 快捷键说明

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