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

📄 png_decoder.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}

	// transparent control
	if(png_dcb.flags & PNG_HAVE_tRNS)
	{
		reg = PNG_TRAN_CON_TRAN_ENABLE;
		if(cfg->out_format == ARGB4444 || cfg->out_format == ARGB8888)
		{
			reg |= PNG_TRAN_CON_ARGB;		
		}
		if(info->color_type == COLOR_TYPE_INDEX)
		{
			if(info->num_trans == 1)
			{
				DRV_WriteReg32(PNG_TRAN_KEY1, (info->trans.index<<16));
			}
			else
			{
				//DRV_WriteReg32(PNG_TRAN_TABLE, cfg->color_table_t);
				reg |= PNG_TRAN_CON_TRAN_TABLE;		
			}			
		}
		else if(info->color_type == COLOR_TYPE_GRAY)
		{
			DRV_WriteReg32(PNG_TRAN_KEY1, (info->trans.gray << 16));			
		}
		else if(info->color_type == COLOR_TYPE_RGB)
		{
			DRV_WriteReg32(PNG_TRAN_KEY1, (info->trans.color.r));	
			DRV_WriteReg32(PNG_TRAN_KEY2, (info->trans.color.g << 16)|
				(info->trans.color.g));	
		}
		else
			PNG_RAISE(1);
		
		// background control
		if(png_dcb.flags & PNG_HAVE_bKGD)
		{
			if(info->color_type == COLOR_TYPE_INDEX)
			{
				DRV_WriteReg32(PNG_BACK_GROUND, info->bKGD.index << 24);
			}
			else if(info->color_type == COLOR_TYPE_GRAY)
			{
				kal_uint32 gray;
				
				gray = info->bKGD.gray;
				if(info->bit_depth > 8)
					gray = gray >> (8);
				DRV_WriteReg32(PNG_BACK_GROUND, gray << 24);				
			}
			else if(info->color_type == COLOR_TYPE_RGB)
			{
				kal_uint32 r,g,b;
				r = info->bKGD.color.r;
				g = info->bKGD.color.g;
				b = info->bKGD.color.b;
				if(info->bit_depth > 8)
				{
					r = r >> (info->bit_depth -8);
					g = g >> (info->bit_depth -8);
					b = b >> (info->bit_depth -8);
				}
				DRV_WriteReg32(PNG_BACK_GROUND, ((r<<16)|(g<<8)|b));				
			}
		}
		else
		{	// no bKGD
			if((info->color_type == COLOR_TYPE_GRAY || info->color_type ==
				COLOR_TYPE_INDEX) && info->num_trans == 1)
			{
				info->use_work_buf = KAL_TRUE;
				reg = 0;
			}
			else if(info->use_work_buf)
			{
				// without bKGD and output to working buffer
				info->use_work_buf = KAL_TRUE;
				reg = 0;
			}
			else
			{
				reg |= PNG_TRAN_CON_TRAN_OUT;
			}
		}
		DRV_WriteReg32(PNG_TRAN_CON, reg);	
	}	
	else
	{
		DRV_WriteReg32(PNG_TRAN_CON, 0);	
	}
	
	// configure the clipping 
	if(cfg->clip_en)
	{
		kal_int32 x, y;
		
		out_format |= PNG_OUT_FORMAT_CLIP_EN;
		if(info->use_work_buf)
		{
			DRV_WriteReg32(PNG_LCD_WH, ((info->wb_width<< 16)|info->wb_height));
			DRV_WriteReg32(PNG_CLIP_XY, ((0 << 16)|0));
			DRV_WriteReg32(PNG_CLIP_WH, ((info->wb_width)<< 16)|
				(info->wb_height));
			x = info->wb_dest_x;
			y = info->wb_dest_y;
		}
		else
		{
			DRV_WriteReg32(PNG_LCD_WH, ((cfg->shadow_w << 16)|cfg->shadow_h));
			DRV_WriteReg32(PNG_CLIP_XY, ((cfg->clip_x1 << 16)|cfg->clip_y1));
			DRV_WriteReg32(PNG_CLIP_WH, ((cfg->clip_x2- cfg->clip_x1+ 1)<< 16)|
				(cfg->clip_y2- cfg->clip_y1+ 1));
			x = cfg->dest_x  ;
			y = cfg->dest_y ;
		}
		if(x < 0 )
		{
			
			x *= -1;
			x |= 0x8000;			
		}
		if(y < 0 )
		{
			
			y *= -1;
			y |= 0x8000;			
		}		
		DRV_WriteReg32(PNG_IMG_XY, ((x<< 16)|(y & 0xffff)));
	}
	else
	{
		DRV_WriteReg32(PNG_IMG_XY, 0);
	}
	DRV_WriteReg8(PNG_OUT_FROMAT, out_format);
	DRV_WriteReg8(PNG_IRQ_EN, PNG_IRQ_EN_ALL);
	
	if(info->use_work_buf)
	{
		kal_uint8 r,g,b,bit_depth;
		kal_uint32 *ct;
		kal_uint16 gray;
		kal_uint32 color, src_key=0,count,i;
		
		DRV_WriteReg32(PNG_OUT_START, cfg->work_buffer_adrs);
		DRV_WriteReg32(PNG_OUT_END, cfg->work_buffer_adrs+cfg->work_buffer_size-2);
		if(info->color_type == COLOR_TYPE_GRAY)
		{
			gray = info->trans.gray;
			bit_depth = info->bit_depth;
			gray = png_get_gray_scale(bit_depth, gray);		
			r = g = b = gray;
			if(cfg->out_format == RGB888)
				src_key = (r<<16)|(g<<8)|b;
			else
				src_key = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
			
		}
		else if(info->color_type == COLOR_TYPE_INDEX)
		{			
			ct = (kal_uint32*)cfg->color_table;
			color = ct[info->trans.index];
			b = (color)&0xff;
			g = (color>>8)&0xff;
			r = (color>>16)&0xff;	
			if(cfg->out_format == RGB888)
				src_key = (r<<16)|(g<<8)|b;
			else
				src_key = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);			
			count = png_dcb.info.num_plte;
			// remove the color of differnet trans.index but the same with transparent color 
			for(i=0;i<=count;i++)
			{
				if(cfg->out_format == RGB888)
				{
					if(src_key == ct[i])
					{
						ct[i] ^= (1<<17); // xor R
					}
				}
				else if(cfg->out_format == RGB565)
				{ 
					kal_uint32 r1,b1,g1;
					b1 = (ct[i])&0xff;
					g1 = (ct[i]>>8)&0xff;
					r1 = (ct[i]>>16)&0xff;	
					if(((r1>>3)<<11)|((g1>>2)<<5)|(b1>>3) == src_key)
					{
						ct[i] ^= (1<<20);	// xor R
					}					
				}
			}
			ct[info->trans.index] = color;
			//png_remove_srckey_color(info->trans.index);
		}
		// src_key for 2d engine to perform bitblit
		png_dcb.info.src_key = src_key;
		// not decode until the caller give the working buffer
	}
	else
	{
		DRV_WriteReg32(PNG_OUT_START, cfg->output_buffer_adrs);
		DRV_WriteReg32(PNG_OUT_END, cfg->output_buffer_adrs+cfg->output_buffer_size-2);
	}
		PNG_DECODE_RUN();	

}
/*************************************************************************
* FUNCTION
*  png_crc_reset
*
* DESCRIPTION
*	reset the crc value 
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_crc_reset(void)
{
	png_dcb.crc = 0xffffffffL;
}
/*************************************************************************
* FUNCTION
*  png_crc_finish
*
* DESCRIPTION
*	check the crc value is correct or not
*
* PARAMETERS
*	
* RETURNS
*  KAL_TRUE:	the crc value is correct
*	KAL_FALSE:	the crc value is wrong
*
* GLOBALS AFFECTED
*	
*************************************************************************/
static kal_bool png_crc_finish(void)
{
	kal_uint32 crc;

	crc = PNG_GET_U32();
	if((crc ^ 0xffffffff) == png_dcb.crc)
		return KAL_TRUE;

	return KAL_FALSE;	
}
/*************************************************************************
* FUNCTION
*  png_crc_read
*
* DESCRIPTION
*	1. read the data into buffer 
*	2. calculate the crc value
*
* PARAMETERS
*	buf:	buffer to contain the read data
*	len:	number to data to be read
*
* RETURNS
*   
* GLOBALS AFFECTED
*	png_dcb.crc
*
*************************************************************************/
static void png_crc_read(void *buf,kal_uint32 len)
{
	extern kal_uint32 png_update_crc(kal_uint32 crc, kal_uint8 *buf,
                         kal_uint32 len);

	PNG_GET_ARRAY(buf,len);
	png_dcb.crc = png_update_crc(png_dcb.crc, (kal_uint8*)buf, len);
}
/*************************************************************************
* FUNCTION
*  png_get_uint_32
*
* DESCRIPTION
*	 Grab an unsigned 32-bit integer from a buffer in big-endian format
*
* PARAMETERS
*	buf: buffer containing data to be translated
*
* RETURNS
*	unsigned 32-bit integer
*
* GLOBALS AFFECTED
*	
*************************************************************************/
static kal_uint32 png_get_uint_32(kal_uint8* buf)
{
   kal_uint32 i = ((kal_uint32)(*buf) << 24) +
      ((kal_uint32)(*(buf + 1)) << 16) +
      ((kal_uint32)(*(buf + 2)) << 8) +
      (kal_uint32)(*(buf + 3));

   return (i);
}
/*************************************************************************
* FUNCTION
*  png_get_uint_16
*
* DESCRIPTION
*	Grab an unsigned 16-bit integer from a buffer in big-endian format.
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static kal_uint16 png_get_uint_16(kal_uint8* buf)
{
   kal_uint16 i = (kal_uint16)(((kal_uint16)(*buf) << 8) +
      (kal_uint16)(*(buf + 1)));

   return (i);
}
/*************************************************************************
* FUNCTION
*  png_IHDR_Handler
*
* DESCRIPTION
*	1. parse the IHDR chunk
*	2. check if the line buffer is large enough
*
* PARAMETERS
*	len: length of the IHDR
*
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_IHDR_Handler(kal_uint32 len)
{
	kal_uint8 buf[13];
	png_inform_struct *info = &png_dcb.info;
	kal_uint32 size,byte;

	if(png_dcb.flags & PNG_HAVE_IHDR)
	{
		PNG_RAISE(1);
	}
	else
		png_dcb.flags |= PNG_HAVE_IHDR;		
	if(len != 13)
	{
		PNG_RAISE(1);
	}
	png_crc_read(buf,13);
	if(!png_crc_finish())
	{
		PNG_RAISE(1);
	}
	info->img_w = png_get_uint_32(buf);
	info->img_h = png_get_uint_32(buf+4);
	info->bit_depth = buf[8];
	info->color_type = buf[9];
	info->interlaced = buf[12];
	byte = (info->bit_depth > 8)?(2):(1);
	size = png_type_channel[info->color_type]*byte*info->img_w;
	if(size > BUFF0_LEN)
		PNG_RAISE(1);
		
}
/*************************************************************************
* FUNCTION
*  png_PLTE_Handler
*
* DESCRIPTION
*	parse the PLTE chunk
*
* PARAMETERS
*	len: length of the PLTE
*
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_PLTE_Handler(kal_uint32 len)
{
	kal_uint32 *ct = png_dcb.cfg->color_table;
	png_inform_struct *info = &png_dcb.info;
	kal_uint32 count = (1 << info->bit_depth),i;
	
	if(!(png_dcb.flags & PNG_HAVE_IHDR) ||
		(png_dcb.flags & PNG_HAVE_PLTE)||
		(png_dcb.flags & PNG_HAVE_IDAT))		
	{
		PNG_RAISE(1);	
	}
	else
		png_dcb.flags |= PNG_HAVE_PLTE;
	if(len > 3*count || (len%3))
	{
		PNG_RAISE(1);
	}
	count = len/3;
	info->num_plte = count-1;
	for(i=0;i<count;i++)
	{
		kal_uint8 buf[3];
		kal_uint32 c;

		png_crc_read(buf,3);
		c = (buf[0]<<16)|(buf[1]<<8)|(buf[2]);
		
		// replace MMI's source key color with XOR 1
		if(png_dcb.cfg->out_format == RGB565)
		{
			kal_uint32 x;
			
			x = ((buf[0]>>3)<<11)|((buf[1]>>2)<<5)|(buf[2]>>3);
			if(x == png_dcb.cfg->src_key)
			{
				//png_dcb.src_hit = KAL_TRUE;
				c ^= 0x8;
			}			
		}
		else if(png_dcb.cfg->out_format == RGB888)
		{
			if(c == png_dcb.cfg->src_key)
			{
				//png_dcb.src_hit = KAL_TRUE;
				c ^= 1;
			}
		}
			
		ct[i] = c;
	}
	if(!png_crc_finish())
	{
		PNG_RAISE(1);	
	}
}
/*************************************************************************
* FUNCTION
*  png_tRNS_Handler
*
* DESCRIPTION
*	parse the tRNS chunk
*
* PARAMETERS
*	len: length of the tRNS chunk
*
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_tRNS_Handler(kal_uint32 len)
{
	png_inform_struct *info = &png_dcb.info;
	kal_uint32 count = (1 << info->bit_depth);
	kal_uint8 buf[6];
	
	if(!(png_dcb.flags & PNG_HAVE_IHDR) ||
		(png_dcb.flags & PNG_HAVE_tRNS)||
		(png_dcb.flags & PNG_HAVE_IDAT))		
	{
		PNG_RAISE(1);	
	}
	else
		png_dcb.flags |= PNG_HAVE_tRNS;

	if(info->color_type == COLOR_TYPE_INDEX)
	{				
		if(len > count)
		{
			PNG_RAISE(1);
		}
		info->num_trans = len;
		if(len ==1)
		{
			 png_crc_read(&info->trans.index,1);
		}
		else
		{
			kal_uint8 *ptr = (kal_uint8*)png_dcb.cfg->color_table_t;			
			png_crc_read(ptr,len);
		}
		if(!png_crc_finish())
		{
			PNG_RAISE(1);		
		}
	}
	else if(info->color_type == COLOR_TYPE_GRAY)
	{		
		if(len != 2)
		{
			PNG_RAISE(0);
		}
		png_crc_read(buf,2);
		info->trans.gray = png_get_uint_16(buf);
		if(!png_crc_finish())
		{
			PNG_RAISE(1);		
		}
		info->num_trans = 1;
	}
	else if(info->color_type == COLOR_TYPE_RGB)
	{		
		if(len != 6)
		{
			PNG_RAISE(0);
		}
		png_crc_read(buf,6);
		if(!png_crc_finish())
		{
			PNG_RAISE(1);		
		}
		info->num_trans = 1;
		info->trans.color.r = png_get_uint_16(buf);
		info->trans.color.g = png_get_uint_16(buf+2);
		info->trans.color.b = png_get_uint_16(buf+4);				
	}
	else
	{
		PNG_RAISE(1);
	}

}
/*************************************************************************
* FUNCTION
*  png_bKGD_Handler
*
* DESCRIPTION
*	parse the bKGD chunk
*
* PARAMETERS
*	len: length of the bKGD chunk
*
* RETURNS
*   
* GLOBALS AFFECTED
*	
*************************************************************************/
static void png_bKGD_Handler(kal_uint32 len)
{
	png_inform_struct *info = &png_dcb.info;
	
	if(!(png_dcb.flags & PNG_HAVE_IHDR) ||
		(png_dcb.flags & PNG_HAVE_bKGD)||
		(png_dcb.flags & PNG_HAVE_IDAT))	
	{
		PNG_RAISE(1);	
	}
	else
		png_dcb.flags |= PNG_HAVE_bKGD;

	if(info->color_type == COLOR_TYPE_INDEX)
	{
		if(len != 1)
			PNG_RAISE(1);
		png_crc_read(&info->bKGD.index,1);
	}
	else if(info->color_type == COLOR_TYPE_GRAY || info->color_type == COLOR_TYPE_GRAY_A)
	{
		if(len != 2)
			PNG_RAISE(1);
		png_crc_read(&info->bKGD.gray,2);
	}
	else if(info->color_type == COLOR_TYPE_RGB || info->color_type == COLOR_TYPE_RGB_A)
	{
		kal_uint8 buf[6];
		if(len != 6)
			PNG_RAISE(1);
		png_crc_read(buf,6);
		info->bKGD.color.r = png_get_uint_16(buf);
		info->bKGD.color.g = png_get_uint_16(buf+2);
		info->bKGD.color.b = png_get_uint_16(buf+4);				
	}
	if(!png_crc_finish())
		PNG_RAISE(1);

}
/*************************************************************************
* FUNCTION
*  png_IDAT_Handler

⌨️ 快捷键说明

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