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

📄 gif_decoder_v2.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif
/*
   if(gif_dcb.info.transparent_index == gif_dcb.info.bg_index)
    return KAL_FALSE;
*/
    g2d_begin(G2D_OWNER_GDI,NULL);

    dest.base_address = (kal_uint32)cfg->output_buffer_adrs;
    dest.clip_x1 = cfg->clip_x1;
    dest.clip_y1 = cfg->clip_y1;
    dest.clip_x2 = cfg->clip_x2;
    dest.clip_y2 = cfg->clip_y2;
    switch(cfg->out_format)
    {
    case GIF_OUT_INDEX:
        dest.color_mode = FIRE_DEST_COLOR_8BPP_LUT_DIS;
        break;
    default: 
	case GIF_OUT_RGB565:
        dest.color_mode = FIRE_DEST_COLOR_16BPP_RGB565;
        break;
	case GIF_OUT_RGB888: 
        dest.color_mode = FIRE_DEST_COLOR_24BPP_RGB888;
        break;
    }
    dest.pitch = cfg->shadow_w;
    dest.height = cfg->shadow_h;
    dest.width = cfg->shadow_w;
    dest.x = 0;
    dest.y = 0;

    g2d_set_dest_buffer(G2D_OWNER_GDI, &dest);

    data.start_x = cfg->dest_x;
    data.start_y = cfg->dest_y;
    data.width = cfg->expect_w;
    data.height = cfg->expect_h;
    
    r=DRV_Reg32(GIF_BG_COLOR)& 0xff;
    g=(DRV_Reg32(GIF_BG_COLOR)& 0xff00)>>8;
    b=(DRV_Reg32(GIF_BG_COLOR)& 0xff0000)>>16;
    data.fill_color = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
    
    data.gradient_fill_mode = KAL_FALSE;
    data.tilt_mode = KAL_FALSE;
    g2d_fill_rectangle(G2D_OWNER_GDI, &data);

    g2d_end(G2D_OWNER_GDI);
    
	return KAL_TRUE;
}

/*INTERNAL_FUNC kal_uint8 gif_resz_ratio(kal_uint16 real, kal_uint16 expect)
{
	kal_uint32 ratio, i;

	if(real <= expect || expect == 0)
	{
		return 0;
	}
	else
	{
		ratio = real/expect;	// must > 1
		
		if(ratio*(kal_uint32)expect < (kal_uint32)real)
			ratio++;
		i = 1;
		while(i<16)
		{
			if(ratio <= (1<<i))
			{
				return (i);
			}
			else
			{
				i++;
			}				
		}
		return ((i-1));
	}
}
*/
/*************************************************************************
* FUNCTION
*  gif_decode_hw
*
* DESCRIPTION
*	1. decode one following frame
*	2. using polling instead interrupt event
*
* PARAMETERS
*
* RETURNS
*	KAL_TRUE	: a frame has been decoded
*	KAL_FALSE: decode fail
*
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
INTERNAL_FUNC void gif_decode_hw(gif_config_struct *cfg)
{
	gif_info_struct *info = &gif_dcb.info;
	kal_uint32 out_format = cfg->out_format;
	kal_uint32 reg;
	kal_uint8 resz_w, resz_h, ct_size;
	hw_bytestream_dcb_struct *bytestream;	
	gif_cache_struct *cache = &gif_cache[gif_cache_index];

	DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
	DRV_WriteReg32(GIF_IRQ_EN, GIF_IRQ_EN_OFF);
	//GIF_RESET();
	// the working buffer must be 4 byte aligned(remove after integration)	
	ASSERT(((kal_uint32)cfg->stack_adrs & 3 ) == 0);
	ASSERT(((kal_uint32)cfg->tree_adrs & 3 ) == 0);
	ASSERT(((kal_uint32)cfg->LCT_adrs & 3 ) == 0);
	DRV_WriteReg32(GIF_TREE_START_ADDR, cfg->tree_adrs);
	DRV_WriteReg32(GIF_TREE_END_ADDR, cfg->tree_adrs+cfg->tree_size);	
	DRV_WriteReg32(GIF_STK_START_ADDR, cfg->stack_adrs);
	DRV_WriteReg32(GIF_STK_END_ADDR,cfg->stack_adrs+cfg->stack_size);	
	// DRV_WriteReg32(GIF_OUTFILE_START_ADDR, cfg->output_buffer_adrs);
	// DRV_WriteReg32(GIF_OUTFILE_END_ADDR, cfg->output_buffer_adrs+ cfg->output_buffer_size);
	DRV_WriteReg32(GIF_INFILE_COUNT, cfg->file_buffer_size);	
		
	// calculate the resize ratio
	{
		kal_uint32 bytes_per_pixel;
		
		switch(cfg->out_format)
		{
		case GIF_OUT_INDEX: bytes_per_pixel=1;break;
		case GIF_OUT_RGB565: bytes_per_pixel=2;break;
		case GIF_OUT_RGB888: bytes_per_pixel=3;break;
		default: bytes_per_pixel=1;break;
		}
		if(cfg->expect_w==0) cfg->expect_w = info->lwidth;
		if(cfg->expect_h==0) cfg->expect_h = info->lheight;
		
		cfg->cal_work_buffer_info_func(
						&resz_w,
						&info->wb_dest_x,&info->wb_dest_y,
						&info->wb_width,&info->wb_height,
						cfg->work_buffer_size / bytes_per_pixel,
						info->lwidth,info->lheight,
						cfg->dest_x,cfg->dest_y,
						cfg->expect_w,cfg->expect_h,
						cfg->clip_x1,cfg->clip_y1,cfg->clip_x2,cfg->clip_y2);
		resz_h = resz_w;
	}

	info->use_work_buf = KAL_FALSE;
	info->resz_w = resz_w;
	info->resz_h  = resz_h;
	
	if((info->lwidth>>resz_w) != cfg->expect_w
	||(info->lheight>>resz_h)!= cfg->expect_h)
		info->use_work_buf = KAL_TRUE;
	
	if(resz_w || resz_h)
	{
		gif_dcb.resz_enable = KAL_TRUE;
		gif_dcb.resz_w = resz_w;
		gif_dcb.resz_h = resz_h;
		reg = (resz_h << 6)|(resz_w << 2)|1;
		DRV_WriteReg32(GIF_RESZ_CTRL, reg);
	}
	else
	{
		DRV_WriteReg32(GIF_RESZ_CTRL, 0);
	}

	// configure the clipping 
	if(cfg->clip_enable)
	{
		kal_int32 x, y;
		
		out_format |= GIF_OUT_FORMAT_CLIP_EN;
		if(info->use_work_buf)
		{
			DRV_WriteReg32(GIF_LCD_WH, (info->wb_width<< 16)|info->wb_height);
			DRV_WriteReg32(GIF_CLIP_XY, (0 << 16)|0);
			DRV_WriteReg32(GIF_CLIP_WH, (info->wb_width<< 16)|info->wb_height);
			x = info->wb_dest_x;
			y = info->wb_dest_y;
		}
		else
		{
			DRV_WriteReg32(GIF_LCD_WH, ((cfg->shadow_w << 16)|cfg->shadow_h));
			DRV_WriteReg32(GIF_CLIP_XY, ((cfg->clip_x1 << 16)|cfg->clip_y1));
			DRV_WriteReg32(GIF_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(GIF_IMG_XY, ((x<< 16)|(y & 0xffff)));
		DRV_WriteReg32(GIF_IMG_OFFSET_XY, (((info->x >> resz_w) << 16)|
			(info->y >> resz_h)));		
	}
	else
	{
		DRV_WriteReg32(GIF_IMG_XY, 0);
		DRV_WriteReg32(GIF_IMG_OFFSET_XY, 0);
	}
	
	if(gif_dcb.partial_enable == KAL_TRUE)
		out_format |= GIF_OUT_FORMAT_PARTIAL_EN;
		
	if(cfg->pack_enable)
	{
		out_format |= (GIF_OUT_FORMAT_PACK_EN)|(info->bpp<< 9);	
		reg = cfg->p_resz_w_Q|(cfg->p_resz_w_N<<10)|(cfg->p_resz_w_D << 20);		
		DRV_WriteReg32(GIF_PACK_RESZ_W, reg);
		reg = cfg->p_resz_h_Q|(cfg->p_resz_h_N<<10)|(cfg->p_resz_h_D << 20);				
		DRV_WriteReg32(GIF_PACK_RESZ_H, reg);		
	}	
	DRV_WriteReg32(GIF_MIN_CODE_SIZE, info->min_code);
	DRV_WriteReg32(GIF_INTERLACE_CTRL, info->interlaced);
	GIF_SET_WIDTH_HEIGHT(info->w,info->h);
	if(info->LCT_flag)
	{
		DRV_WriteReg32(GIF_CT_START_ADDR, cfg->LCT_adrs);
		ct_size = info->LCT_size;
	}
	else
	{
		DRV_WriteReg32(GIF_CT_START_ADDR, cache->GCT);
		ct_size = cache->GCT_size;
	}
	if(!info->use_work_buf && info->transparent_flag && cfg->transparent_enable)
	{	
		// always not output while encounter tc_index
		reg = 3|(info->transparent_index << 2); 
		DRV_WriteReg32(GIF_TRANS_CTRL, reg);
	}
	else
	{
		DRV_WriteReg32(GIF_TRANS_CTRL, 0);
	}
	// set background color (RGB888) or index
	if(out_format != GIF_OUT_INDEX)
	{		
		if(cache->GCT_flag)
			DRV_WriteReg32(GIF_BG_COLOR, cache->GCT[cache->bg_index]);
		else
			DRV_WriteReg32(GIF_BG_COLOR, 0xffffff); // use white color as the backgruoud color if no GCT
	}
	else
	{
		DRV_WriteReg32(GIF_BG_COLOR, cache->bg_index << 24);
	}
	
	// update the lzw start address and the input buffer count
	GIF_TELL(&bytestream);
	if(cfg->decode_mode == GIF_DECODE_FILE )
	{
		/* HW issue that the ipnut file count can't be too small */
		if(bytestream->type.file.buffer_content_size<GIF_REFILL_THRESH)
		 GIF_REFILL();
		
		gif_dcb.lzw_start = (kal_uint32)bytestream->type.file.buffer_reader;
		DRV_WriteReg32(GIF_INFILE_START_ADDR,gif_dcb.lzw_start);
		if(gif_dcb.partial_enable)
			DRV_WriteReg32(GIF_INFILE_COUNT,bytestream->type.file.buffer_content_size);						
	}
	else
	{
		gif_dcb.lzw_start = (kal_uint32)bytestream->type.mem.buffer_ptr+bytestream->type.mem.buffer_offset;
		DRV_WriteReg32(GIF_INFILE_START_ADDR,gif_dcb.lzw_start);
	}
	DRV_WriteReg32(GIF_OUT_FORMAT, out_format);	
	if( info->use_work_buf)
	{
		kal_uint8 r,g,b;
		kal_uint32 *ct;
		kal_uint32 color, src_key,i;

		// report src_key(transparent index)
		// remove src_key color with different index
		DRV_WriteReg32(GIF_OUTFILE_START_ADDR, cfg->work_buffer_adrs);
		DRV_WriteReg32(GIF_OUTFILE_END_ADDR, cfg->work_buffer_adrs+ cfg->work_buffer_size);
		ct = (kal_uint32*)DRV_Reg32(GIF_CT_START_ADDR);
		color = ct[info->transparent_index];
		b = (color)&0xff;
		g = (color>>8)&0xff;
		r = (color>>16)&0xff;	
		if(cfg->out_format == GIF_OUT_RGB888)
			src_key = (r<<16)|(g<<8)|b;
		else if(cfg->out_format == GIF_OUT_RGB565)
			src_key = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);			
		else // GIF_OUT_INDEX
			src_key = info->transparent_index;
		
		// remove the color of differnet trans.index but the same with transparent color 
		for(i=0;i<=ct_size;i++)
		{
			if(cfg->out_format == GIF_OUT_RGB888)
			{
				if(src_key == ct[i])
				{
					ct[i] ^= (1<<17);
				}
			}
			else if(cfg->out_format == GIF_OUT_RGB565)
			{ 
				kal_uint32 r1,b1,g1;
				kal_uint32 c;
				
				b1 = (ct[i])&0xff;
				g1 = (ct[i]>>8)&0xff;
				r1 = (ct[i]>>16)&0xff;
				c = ((r1>>3)<<11)|((g1>>2)<<5)|(b1>>3);
				if( c == src_key)
				{
					ct[i] ^= (1<<20);
				}
			}
		}
		ct[info->transparent_index] = color; // restore again, because it was be changed.
		info->src_key_2d = src_key;
	}
	else
	{
		DRV_WriteReg32(GIF_OUTFILE_START_ADDR, cfg->output_buffer_adrs);
		DRV_WriteReg32(GIF_OUTFILE_END_ADDR, cfg->output_buffer_adrs+ cfg->output_buffer_size);
	}
	
	if(gif_dcb.cur_fn==0)
	 gif_last_disposal_method=gif_cur_disposal_method;	
	
	// handling the disposal method according the the previou frame.
	if(cfg->disposal_en && (gif_last_disposal_method == GIF_RESTORE_BG))
		gif_g2d_fillbg();
	
	DRV_WriteReg32(GIF_IRQ_EN, GIF_IRQ_EN_ALL);	
	GIF_START_TIMER();
	GIF_START();			
}

/*************************************************************************
* FUNCTION
*  gif_init
*
* DESCRIPTION
*	get resource memeory from caller(share the same resource with SW decoder)
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
void gif_init(void)
{
	if(gif_hisr == 0)
	{
   	//gif_hisr = kal_create_hisr("GIF_HISR",2,512,gif_hisr_entry,NULL);
   	VISUAL_Register_HISR(VISUAL_GIF_HISR_ID,gif_hisr_entry);
   	IRQ_Register_LISR(IRQ_GIF_CODE, gif_lisr_entry,"gif_lisr");
   	IRQSensitivity(IRQ_GIF_CODE,LEVEL_SENSITIVE);   	
	}
	IRQUnmask(IRQ_GIF_CODE);	
	
	// initialize the GPT
	if(gif_gpt_handle == 0)
		GPTI_GetHandle(&gif_gpt_handle);
	gif_cache_counter = GIF_CACHE_INIT_COUTNER;
	gif_state = GIF_STATE_READY;
}
/*************************************************************************
* FUNCTION
*  gif_decode_process
*
* DESCRIPTION
*	get resource memeory from caller(share the same resource with SW decoder)
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
INTERNAL_FUNC gif_report_status_enum gif_decode_process(gif_config_struct *cfg)
{
	gif_info_struct *my_info = &gif_dcb.info;
	gif_cache_struct *cache = &gif_cache[gif_cache_index];
	gif_report_status_enum status = GIF_DECODING;
	
	gif_cur_disposal_method=GIF_NO_ACTION;
	
	gif_get_last_disposal(gif_dcb.cur_fn,&gif_last_disposal_method);
	
   do
   {
    	switch(GIF_GET_U8())
      {	
			case GIF_EXT_LABEL:	// 0x21
						if(GIF_GET_U8() == GIF_GCE_LABEL)
						{	//	Process the GIF extension block(GCE)(0xf9)
							kal_uint8 a,b;

							GIF_FLUSH(1);
							a = GIF_GET_U8(); 
							my_info->disposal = (a>>2)&7;
							
							gif_cur_disposal_method=my_info->disposal;

							my_info->delay_time = GIF_GET_U16();
							b = GIF_GET_U8(); 
							if(a&GIF_GCE_PACK_TC_FLAG )
							{									
								my_info->transparent_index = b; 
								my_info->transparent_flag = KAL_TRUE;									
							}
							else
							{
								my_info->transparent_flag = KAL_FALSE;
							}
							GIF_FLUSH(1);
						}
						else // skip other extensions 
						{
							kal_uint32 len;
							while(1)
							{
								len = GIF_GET_U8();
								if(len ==0) break;
								GIF_FLUSH(len);
							}
						}
						break;
			case GIF_IMD_LABEL: // 0x2C, ',' image descriptor		
			{
						kal_uint8 a;
					
						my_info->x = GIF_GET_U16();
						my_info->y = GIF_GET_U16();
						my_info->w = GIF_GET_U16();
						my_info->h = GIF_GET_U16();					
						gif_dcb.timeout_period = GIF_TIMEOUT_PERIOD;	 
						a = GIF_GET_U8();
						my_info->LCT_flag = ((a&GIF_IMD_PACK_LCT_FLAG) != 0);
						my_info->interlaced = ((a&GIF_IMD_PACK_INTERLACE) != 0);
						if(my_info->LCT_flag)
						{	// retreive the LCT
							kal_uint32 i,bpp;
							
							bpp = (a&GIF_IMD_PACK_LCT_SIZE) + 1;
							my_info->bpp = bpp;
							my_info->LCT_size = (1 << bpp)-1;							

⌨️ 快捷键说明

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