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

📄 gif_decoder_v2.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
							for(i=0; i<=my_info->LCT_size; i++)
							{
								kal_uint8 r,g,b;
								kal_uint32 e;

								r = GIF_GET_U8();
								g = GIF_GET_U8();
								b = GIF_GET_U8();
								e = (r<<16)|(g<<8)|(b);
								// replace MMI's source key color with XOR 1
								if(cfg->out_format == GIF_OUT_RGB565)
								{
									kal_uint16 x;
									
									x = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
									if(x == cfg->src_key)
									{
										e ^= 0x8;
									}
								}
								else // 888 and index color type
								{
									if(e == cfg->src_key)
									{
										e ^= 1;
									}
								}
								cfg->LCT_adrs[i] = e;
							}
						}							
						// get minimum code size
						my_info->min_code = GIF_GET_U8();
						gif_decode_hw(cfg);
						goto end;
			}
						break;
         case GIF_TRAILER_LABEL: // 0x3b, trailer      
         			gif_dcb.trailer = KAL_TRUE;         			
      				cache->total_fn = gif_dcb.cur_fn-1;
      				status =  GIF_NO_FRAME;
      				gif_state = GIF_STATE_READY;
            		goto end;
    	}

	} while(GIF_IS_EOF()!= KAL_TRUE);
end:
	return status;
   
}
/*************************************************************************
* FUNCTION
*  gif_decode_start
*
* DESCRIPTION
*	start to decode a specified frame of a gif image (non blocking)
*
* PARAMETERS
*	
* RETURNS
*	GIF_DECODING
*  GIF_INVALID_FORMAT
*	GIF_NO_FRAME
*
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
gif_report_status_enum gif_decode_start(gif_config_struct *cfg, gif_info_struct *info)
{	
	kal_uint32 offset;	
	gif_cache_struct *cache;
	kal_bool cache_hit;
	gif_report_status_enum status;
	gif_info_struct *my_info = &gif_dcb.info;
	
	ASSERT(gif_state == GIF_STATE_READY);
	gif_state = GIF_STATE_BUSY;
	// ASSERT(cfg->file_buffer_size >= GIF_MIN_FILE_BUF_SIZE);	
	ASSERT(cfg->gif_cb != NULL);

	kal_mem_set(&gif_dcb, 0, sizeof(gif_dcb));
	gif_dcb.cfg = cfg;
	gif_dcb.gif_cb = cfg->gif_cb;
    gif_last_disposal_method = 0;
	if(cfg->decode_mode == GIF_DECODE_FILE)
	{
		
		gif_dcb.file_size = hw_bytestream_create_file(HW_BYTESTREAM_GIF, cfg->file_handle,(kal_uint8*)cfg->file_buffer_adrs, cfg->file_buffer_size);
		if(gif_dcb.file_size)
		{
			if(gif_dcb.file_size > cfg->file_buffer_size)
				gif_dcb.partial_enable = KAL_TRUE;
		}
	}
	else // GIF_DECODE_MEMORY: the total gif file is in the memory
	{
		hw_bytestream_create(HW_BYTESTREAM_GIF,(kal_uint8*)cfg->file_buffer_adrs,cfg->file_buffer_size);
 		gif_dcb.file_size = cfg->file_buffer_size;
	}
	
	GIF_TRY
	// get a cache 
	cache_hit = gif_get_cache(cfg->cache_id, &cache, KAL_TRUE);
	offset = 0;
	if( cache_hit == KAL_TRUE)
	{
 		gif_get_cache_offset(cfg->frame_number,&offset);
 		if(cfg->frame_number > cache->total_fn || (offset+10) >= gif_dcb.file_size)
		{
			gif_state = GIF_STATE_READY;
			return GIF_NO_FRAME;
		}
		GIF_SEEK(offset);
	}
	else
	{	 
		kal_uint8 a;
		
 		if(GIF_GET_U8()!= 'G' || GIF_GET_U8() != 'I' || GIF_GET_U8() != 'F') 
		{
			kal_print("GIF_INVALID_FORMAT");
			cache->id = 0;
			status = GIF_INVALID_FORMAT;
			gif_state = GIF_STATE_READY;
			goto end;
		}
		GIF_FLUSH(3);
 		cache->lwidth = GIF_GET_U16();
		cache->lheight = GIF_GET_U16();
		a = GIF_GET_U8(); 
		cache->GCT_flag = ((a&0x80) == 0x80);
		cache->bpp = ((a&0x7)+1);
		if(cfg->pack_enable == KAL_TRUE)
			ASSERT(cache->bpp == 1 || cache->bpp == 2 || cache->bpp == 4 || cache->bpp == 8);
		cache->GCT_size = (1 << (cache->bpp))-1; // 255 means 256 
		cache->bg_index = GIF_GET_U8(); 
		GIF_FLUSH(1);
		// retreive the golbal color table
		if(cache->GCT_flag)
		{
			kal_uint32 i;
			
			for(i=0; i<=cache->GCT_size; i++)
			{
				kal_uint8 r,g,b;
				kal_uint32 e;

				r = GIF_GET_U8();
				g = GIF_GET_U8();
				b = GIF_GET_U8();
				e = (r<<16)|(g<<8)|(b);
				// replace MMI's source key color with XOR 1 Blue
				if(cfg->out_format == GIF_OUT_RGB565)
				{
					kal_uint16 x;
					
					x = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);
					if(x == cfg->src_key)
					{
						e ^= 0x8;
					}
				}
				else // 888 and index color type
				{
					if(e == cfg->src_key)
					{
						e ^= 1;
					}
				}
				cache->GCT[i]=e;
			}
		}
		cache->frame_offset[0] = GIF_TELL(NULL);
	}	
	if(cfg->out_format == GIF_OUT_INDEX && cfg->GCT_adrs != NULL)
	{
		kal_mem_cpy(cfg->GCT_adrs,cache->GCT,sizeof(cache->GCT) );
	}					
	
	my_info->lwidth = cache->lwidth;
	my_info->lheight = cache->lheight;
	my_info->GCT_flag = cache->GCT_flag;
	my_info->GCT_size = cache->GCT_size;
	my_info->bg_index = cache->bg_index;	
	my_info->bpp = cache->bpp;
	
	status = gif_decode_process(cfg);
	if(status == GIF_NO_FRAME)
		cache->total_fn = cfg->frame_number -1;
	*info = gif_dcb.info;
	GIF_CATCH_BEGIN
	gif_state = GIF_STATE_READY;		
	status = GIF_INVALID_FORMAT;
	GIF_CATCH_END

end:
	
	return status;	
}

/*************************************************************************
* FUNCTION
*  gif_decode_resume
*
* DESCRIPTION
*	get resource memeory from caller(share the same resource with SW decoder)
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
gif_report_status_enum gif_decode_resume(gif_config_struct *cfg, gif_info_struct *info)
{

	hw_bytestream_dcb_struct *bytestream;		
	gif_status_enum int_status;
	gif_report_status_enum status = GIF_DECODING;
	// kal_uint32 offset;

	GIF_TRY
	int_status = gif_dcb.int_status;
	if(int_status == GIF_STATUS_INEMPTY)
	{		
		DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
		GIF_TELL(&bytestream);
		GIF_FLUSH(bytestream->type.file.buffer_content_size);
		GIF_REFILL();
		gif_dcb.lzw_start = (kal_uint32)bytestream->type.file.buffer_ptr;
		DRV_WriteReg32(GIF_INFILE_START_ADDR, gif_dcb.lzw_start);	
		DRV_WriteReg32(GIF_INFILE_COUNT, bytestream->type.file.buffer_size);	
		// status = GIF_DECODING;
		GIF_START_TIMER();
		GIF_RESUME();		 
	}		
	else if(int_status == GIF_STATUS_COMPLETE)
	{
		status = gif_decode_process(cfg);
		*info = gif_dcb.info;
	}
	GIF_CATCH_BEGIN
	gif_state = GIF_STATE_READY;				
	status = GIF_INVALID_FORMAT;
	GIF_CATCH_END

	return status;

}

/*************************************************************************
* FUNCTION
*  gif_decode_stop
*
* DESCRIPTION
*	get resource memeory from caller(share the same resource with SW decoder)
*
* PARAMETERS
*	
* RETURNS
*   
* GLOBALS AFFECTED
*	gif_dcb
*************************************************************************/
void gif_decode_stop(void)
{
	gif_state = GIF_STATE_READY;
	
	DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
	GIF_RESET();
	DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
}

// #define GIF_UINT_TEST
#if defined (GIF_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		(32*1024)
#define OUT_BUFFER_SIZE			(LCD_WIDTH*LCD_HEIGHT*2)
#define GIF_STACK_SIZE			(0x1000+4)
#define GIF_TREE_SIZE			(0x4000+4)
#define GIF_CT_SIZE				(256)	// x4

gif_config_struct gif_config;
gif_info_struct gif_info;
kal_uint8 in_buffer[FILE_BUFFER_SIZE];
kal_uint16 lcd_buffer[LCD_WIDTH*LCD_HEIGHT];
kal_uint16 lcd_buffer_i[LCD_WIDTH*LCD_HEIGHT];

kal_uint32 gif_tree[GIF_TREE_SIZE/sizeof(kal_uint32)];
kal_uint32 gif_stack[GIF_STACK_SIZE/ sizeof(kal_uint32)];
kal_uint32 gif_lct[GIF_CT_SIZE];
kal_uint8 file_name[256];
kal_wchar file_name_w[256];
kal_uint32 file_size;

#define  GIF_NUM		4
gif_config_struct gif_cfg[GIF_NUM];
kal_uint8 in_buf[GIF_NUM][FILE_BUFFER_SIZE];
kal_uint8 f_name[GIF_NUM][256];
kal_wchar f_name_w[GIF_NUM][256];
kal_uint32 fs[GIF_NUM];

kal_eventgrpid GIF_Events;
gif_status_enum cb_status;
kal_uint32 cb_fn;

volatile kal_bool  gif_stop_now = KAL_FALSE;

// test case 1:	one file, in order
// test case 2: 	one image in memory, in order
// test case 3:	one file in any order
// test case 4:	one image in memory decoded in any order.
// test case 5: 	four images (2 files and 2 in memory) decoded in order.
// test case 6: 	8 images (4 files and 4 in memory) decoded in any order.
// test case 7:	one image more than 100 frames decoded in order
// test case 8:	one image more than 100 frames decoded in order
// test case 9:	various clip, resizing ratio, and dest_x, dest_y
// test case 10:	pack mode
// test case 11:	various output mode(RGB888) ???
// test case 12: decode a very large file of 1,792,163 bytes(it takes about 2.9s)
// test case 13: verify timeout mechanism
void GPT3_Init_my(void)
{
	// clear pdn bit of GPT
	DRV_Reg(0x80000324) = 1;
	// set clock
	DRV_Reg(0x80100024) = 4; // 4: 1k, 7: 125hz
	// start free running
	DRV_Reg(0x8010001c) = 1;	
}


kal_uint32 GPT3_GetCount(void)
{
	return DRV_Reg(0x80100020);
}

kal_uint32 GPT3_TimeDiff(kal_uint32 time1)
{
	kal_uint32 time2;

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

static void init_lcd_layer_window(void)
{
	lcd_layer_struct layer_data = {0};

	layer_data.source_key=0xFFFF;
	layer_data.source_key_enable=KAL_FALSE;
	layer_data.color_palette_enable=KAL_FALSE;
	layer_data.color_palette_select=0;
	layer_data.opacity_enable=KAL_FALSE;
	layer_data.opacity_value=10;
	layer_data.x_offset=0;
	layer_data.y_offset=0;
	layer_data.frame_buffer_address=(kal_uint32) lcd_buffer;
	layer_data.row_number=LCD_HEIGHT;
	layer_data.column_number=LCD_WIDTH;
	layer_data.rotate_value=0;
	layer_data.source_color_format = LCD_LAYER_SOURCE_COLOR_RGB565;
	config_lcd_layer_window(0,&layer_data);

}	/* init_lcd_layer_window() */
static void LCD_Init(void)
{
	lcd_init(MAIN_LCD,0xF800);
	init_lcd_layer_window();
	SET_LCD_ROI_WINDOW_OFFSET(0,0);
	SET_LCD_ROI_WINDOW_SIZE(LCD_WIDTH,LCD_HEIGHT);
	memset(lcd_buffer, 0x55, sizeof lcd_buffer);

}
static void LCDDisplay_adrs( kal_uint16 w, kal_uint16 h, kal_uint16 x, kal_uint16 y, void* adrs)
{
	lcd_frame_update_struct lcd_data;

	lcd_power_up();
	SET_LCD_LAYER0_WINDOW_SIZE(w,h);
	SET_LCD_LAYER0_WINDOW_OFFSET(x,y);
	
	REG_LCD_LAYER0_BUFF_ADDR = (kal_uint32) adrs;
	lcd_data.module_id=LCD_UPDATE_MODULE_MEDIA;
	lcd_data.lcd_id=MAIN_LCD;
	lcd_data.fb_update_mode=LCD_SW_TRIGGER_MODE;
	lcd_data.lcm_start_x=0;
	lcd_data.lcm_start_y=0;
	lcd_data.lcm_end_x=LCD_WIDTH-1;
	lcd_data.lcm_end_y=LCD_HEIGHT-1;
	lcd_data.roi_offset_x=0;
	lcd_data.roi_offset_y=0;
	lcd_data.update_layer=LCD_LAYER0_ENABLE;
	
	lcd_fb_update(&lcd_data);	
}
static void GIF_Display(void *adrs, kal_uint16 w, kal_uint16 h)
{
	LCDDisplay_adrs(w,h,0,0,adrs);
}

kal_uint32 fast_semi_crc(kal_uint8* src,kal_uint32 size)
{
	register kal_uint32 crc,temp,i;
	crc = 0;   
	for(i=0;i<size;i++)
	{
		if(crc >>15) temp=1; else temp=0;
		crc = (((crc<<1) & 0x0ffff) + temp) ^ (kal_uint32)*src;
		src++;
	}
	return crc;
}
kal_uint32 gif_get_cache_key_from_file(kal_uint8* filename,kal_uint32 file_size)
{
	// Compute the cache key by filename and file size 
	kal_uint32 cache_id;

	cache_id = (kal_uint32) fast_semi_crc((kal_uint8 *) filename, (kal_uint32)strlen((char *)filename));
	cache_id ^= (kal_uint32) file_size;

	return cache_id;
}

void gif_callback(gif_status_enum status, kal_uint32 fn)
{

	cb_status = status;
	cb_fn = fn;
	kal_set_eg_events(GIF_Events,1,KAL_OR);

		
}
// file mode, multi frame, no partila input, no resizing
void test_case_1(void)
{
	gif_config_struct *p = &gif_config;
	gif_report_status_enum status;

	//sprintf(file_name, "c:\\gif\\test1.gif"); // single frame
	sprintf(file_name, "c:\\gif\\3d_book2.gif"); // multi frame
	kal_wsprintf(file_name_w,(char*)file_name);
	p->decode_mode = GIF_DECODE_FILE;	
	p->file_handle = DRM_open_file(file_name_w,FS_READ_ONLY|FS_OPEN_NO_DIR,0);
	if(p->file_handle < 0 )
		ASSERT(0);
	DRM_file_size(p->file_handle, &file_size);
	p->cache_id = gif_get_cache_key_from_file(file_name, file_size);	
	p->file_buffer_adrs = in_buffer;
	p->file_buffer_size = file_size;
	p->output_buffer_adrs = (kal_uint8*)lcd_buffer;
	p->output_buffer_size = sizeof lcd_buffer;
	p->stack_adrs = gif_stack;
	p->stack_size = GIF_STACK_SIZE;
	p->tree_adrs = gif_tree;
	p->tree_size = GIF_TREE_SIZE;
	p->LCT_adrs = gif_lct;

	p->shadow_w = LCD_WIDTH;
	p->shadow_h = LCD_HEIGHT;
	p->clip_x1 = 0;
	p->clip_y1 = 0;
	p->clip_x2 = LCD_WIDTH-1;
	p->clip_y2 = LCD_HEIGHT-1;
	p->dest_x = 0;
	p->dest_y = 0;

	p->expect_w = LCD_WIDTH;
	p->expect_h = LCD_HEIGHT;
	
	p->pack_enable =  KAL_FALSE;
	// 1:1 ratio (pack mode)
	p->p_resz_w_Q = 0;
	p->p_resz_w_N = 1;
	p->p_resz_w_D = 0;
	p->p_resz_h_Q = 0;
	p->p_resz_h_N = 1;
	p->p_resz_h_D = 0;

	p->clip_enable = KAL_TRUE;
	p->out_format = GIF_OUT_RGB565;
	p->gif_cb = gif_callback;
	
	p->frame_number = 0;		
	// decoding until GIF_NO_FRAME is occurs
	while(1)
	{		
		kal_uint32 flag;
		
		status = gif_decode_start(p, &gif_info);
		if(status ==  GIF_INVALID_FORMAT || status == GIF_NO_FRAME)
			goto end;		
		kal_retrieve_eg_events(GIF_Events,(1),KAL_OR_CONSUME,&flag,KAL_SUSPEND);						
			
		while(1)
		{
			if(cb_status == GIF_STATUS_INEMPTY)
			{

⌨️ 快捷键说明

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