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

📄 gif_decoder.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	else if(status & GIF_STATUS_END) // truncated gif file
	{
		//ASSERT(0);
		return GIF_TRUNCATED_FILE;
	}
	else if(gif_dcb.is_timeout) // hw decoder failed to decode the gif file
	{
		//ASSERT(0);
		return GIF_DECODE_TIMEOUT;
	}
	//ASSERT(0);
	return GIF_FORMAT_ERROR;	
}

/*************************************************************************
* FUNCTION
*  GIF_G2D_FillBG
*
* DESCRIPTION
*	Fill the logical screen with specified position and background color
*
* PARAMETERS
*	gif_para_struct: specifying configuration parameters
*	gif_info_struct: specifying logical screen size and background color
* RETURNS
*	gif_error_enum
*
* GLOBALS AFFECTED
*	gif_dcb
*
*************************************************************************/
kal_bool GIF_G2D_FillBG(const gif_para_struct *s, gif_info_struct *info)
{
	g2d_parameter_struct g2d; 

	// out of clip window
	if((s->dest_x+info->lwidth-1)< s->clip_x1)
		return KAL_FALSE;	
	if(s->dest_x > s->clip_x2)
		return KAL_FALSE;
	if((s->dest_y+info->lheight-1) < s->clip_y1)
		return KAL_FALSE;
	if(s->dest_y > s->clip_y2)
		return KAL_FALSE;	
	if(s->dest_x < 0)
	{
		g2d.dest_x = 0;
		g2d.dest_width = info->lwidth+s->dest_x;
	}
	else
	{
		g2d.dest_x = s->dest_x;
		g2d.dest_width = info->lwidth;

	}
	if(s->dest_y < 0)
	{
		g2d.dest_y = 0;
		g2d.dest_height = info->lheight+s->dest_y;
	}
	else
	{
		g2d.dest_y = s->dest_y;
		g2d.dest_height = info->lheight;
	}
	
	g2d.clip_start_x = s->clip_x1;
	g2d.clip_start_y = s->clip_y1;
	g2d.clip_end_x = s->clip_x2;
	g2d.clip_end_y = s->clip_y2;	
	
//	g2d.dest_pitch = s->shadow_width*2; 
	g2d.dest_pitch_width = s->shadow_width; 
//	g2d.dest_base_address = (kal_uint32)s->shadow_adrs+(s->shadow_width*g2d.dest_y+g2d.dest_x)*2;
	g2d.dest_base_address = (kal_uint32)s->shadow_adrs;

	g2d.dest_color_mode = G2D_DEST_16BPP_LUT_DISABLE;
	g2d.src_color_mode = G2D_SRC_16BPP_LUT_DISABLE;
	g2d.clip_mode = G2D_CLIP_ENABLE;
	g2d.pat_fg_color = info->bg_color;

	g2d.g2d_operation_mode=G2D_OPERATION_RECTANGLE_FILL;
	g2d_accelerator(&g2d);	
	return KAL_TRUE;
}

/*************************************************************************
* FUNCTION
*  GIF_G2D_BitBlt
*
* DESCRIPTION
*	Copy the frame into logical screen with transparent color
*
* PARAMETERS
*	gif_para_struct: specifying configuration parameters
*	gif_info_struct: specifying logical screen size and transparent flag
* RETURNS
*	gif_error_enum
*
* GLOBALS AFFECTED
*	gif_dcb
*
*************************************************************************/
void GIF_G2D_BitBlt(const gif_para_struct *s, gif_info_struct *info)
{
	g2d_parameter_struct g2d;
	
	if((s->dest_x+info->x) < 0)
	{
		if((s->dest_x+info->x+info->width-1) < 0)
			return;
		g2d.src_x = -1*(s->dest_x+info->x);
		g2d.src_width = info->width+s->dest_x+info->x;
		g2d.dest_x = 0;	
	}
	else
	{
		g2d.src_x = 0;
		g2d.src_width =info->width;
		g2d.dest_x = s->dest_x+info->x;
	}
	if((s->dest_y+info->y) < 0)
	{
		if((s->dest_y+info->y+info->height-1) <0)
			return;
		g2d.src_y = -1*(s->dest_y+info->y);
		g2d.src_height = info->height+s->dest_y+info->y;
		g2d.dest_y = 0;
	}
	else
	{
		g2d.src_y = 0;
		g2d.src_height = info->height;
		g2d.dest_y = s->dest_y+info->y;		
	}
//	g2d.src_pitch = info->width*2;
	g2d.src_pitch_width = info->width;
	g2d.src_key_color = GIF_SOFTKEY;

	g2d.dest_width = g2d.src_width;
	g2d.dest_height = g2d.src_height;
//	g2d.dest_pitch = s->shadow_width*2;
//	g2d.src_base_address = (kal_uint32)s->work_adrs+((g2d.src_y*info->width)+g2d.src_x)*2;	
//	g2d.dest_base_address = (kal_uint32)s->shadow_adrs+((g2d.dest_y*s->shadow_width)+g2d.dest_x)*2;	
	g2d.dest_pitch_width = s->shadow_width;
	g2d.src_base_address = (kal_uint32)s->work_adrs;	
	g2d.dest_base_address = (kal_uint32)s->shadow_adrs;	

	g2d.clip_start_x = s->clip_x1;
	g2d.clip_start_y = s->clip_y1;
	g2d.clip_end_x = s->clip_x2;
	g2d.clip_end_y = s->clip_y2;	
	
	g2d.src_color_mode = G2D_SRC_16BPP_LUT_DISABLE;
	g2d.dest_color_mode = G2D_DEST_16BPP_LUT_DISABLE;
	g2d.clip_mode = G2D_CLIP_ENABLE;
	g2d.bitblt_mode = BITBLT_TRANSFORM_COPY;
	g2d.src_key_mode = gif_dcb.gif_info.transparent_flag;

	g2d.g2d_operation_mode=G2D_OPERATION_BITBLT;
	g2d_accelerator(&g2d);	
}


/*************************************************************************
* FUNCTION
*  GIF_Display_HW
*
* DESCRIPTION
*	Display a GIF frame with specified parameters
*
* PARAMETERS
*	gif_para_struct: specifying configuration parameters
*	gif_info_struct: specifying logical screen size and transparent flag
* RETURNS
*	gif_error_enum
*
* GLOBALS AFFECTED
*	gif_dcb
*
*************************************************************************/
kal_int32 GIF_Display_HW(gif_para_struct *s, gif_info_struct *info)
{
	kal_uint8 *GIF_src, *GIF_end;
	kal_uint32 n; 
	gif_disposal_enum gif_disposal;
	kal_int32 status;
	kal_uint32 *ptr;

	//ENTER_CRITICAL();
	ASSERT(gif_dcb.state == GIF_STATE_READY);
	gif_dcb.state = GIF_STATE_BUSY;
	//EXIT_CRITICAL();

	if( (s->frame_number != 0)&&
		 (gif_dcb.frame_counter == 0)&&
		 (s->reset == KAL_FALSE))
		 ASSERT(0);
	
	if( (s->clip_x1 > s->clip_x2)||
		 (s->clip_y1 > s->clip_y2))
		 return GIF_FINISH_FRAME;
		 //ASSERT(0);		 
	
	if(s->reset || (s->frame_number == 0))
	{
		gif_dcb.img_adrs = s->img_adrs;
		gif_dcb.current_adrs = s->img_adrs;
		gif_dcb.img_end = s->img_adrs+s->img_size;
		GIF_Reset();
	}
	if(gif_dcb.trailer )
	{			
		status =  GIF_NO_FRAME;
		goto gif_display_end;
	}
	
	// initial guard pattern for stack and tree memorys(for every frame)
	ptr = (kal_uint32*)(gif_resource.stack+gif_resource.stack_size-4);
	*ptr = GIF_GUARD_PATTERN;
	ptr = (kal_uint32*)(gif_resource.tree+gif_resource.tree_size-4);
	*ptr = GIF_GUARD_PATTERN;	
		
	GIF_src = gif_dcb.current_adrs;
	GIF_end = gif_dcb.img_end;
	if(gif_dcb.frame_counter  == 0)
	{
		// check gif header 
		if(GIF_src[0] != 'G' || GIF_src[1] != 'I' || GIF_src[2]   != 'F') 
		{
			status = GIF_FORMAT_ERROR;
			goto gif_display_end;
		}
		
		n = GIF_src[10]; // pack field of LSD
		GIF_src += 13;		
		/*	skip the global color palette	*/
		if(n&0x80)
		{
			n=1<<((n&0x7)+1); // GCT size				
			GIF_src += 3*n;
		}
		else
		{
			//dbg_print("!!!! NO GCT EXIST!!!!\r\n");
			//ASSERT(0); // not exist of GCT			
		}
	}
	
	if(GIF_src >= (GIF_end)) 
	{
		status =  GIF_NO_FRAME;
		goto gif_display_end;
	}
   do
   {
   	kal_uint16 w,h;

    	switch(*GIF_src++)
      {	
			case '!':	// 0x21
						if(*GIF_src++==0xf9)
						{	//	Process the GIF extension block(GCE)
							if(GIF_src[1]&0x01)
							{	
								gif_dcb.gif_info.transparent_index = GIF_src[4];
								gif_dcb.gif_info.transparent_flag = 1;
							}
							// use disposal method specified by gif file or user
							if(s->disposal_force == GIF_MTK_NO_ACTION)
								gif_disposal = (GIF_src[1]&0x1c)>>2;
							else
								gif_disposal = s->disposal_force;
							
							//dbg_print("disposal %d!\r\n",gif_disposal);
							// return delay time 
							gif_dcb.gif_info.delay_time = GIF_src[2];								
							GIF_src+=6;
						}
						else // skip other extensions 
						{
							int offset;
							while(1)
							{
								offset= *GIF_src++;
								if(offset==0) break;
								GIF_src += offset;
							}
						}
						break;
			case ',': // 0x2C, image descriptor							
						w = (kal_uint16)(GIF_src[5]<< 8)|(kal_uint16)GIF_src[4];
						h = (kal_uint16)(GIF_src[7]<< 8)|(kal_uint16)GIF_src[6];
						if(w*h*2 > s->work_size)
						{
							//dbg_print("working memory is not enough, WxH: %dx%d\r\n", w,h);
							//ASSERT(0);
							status = GIF_MEM_INSUFFICEITN;														
							goto gif_display_end;
						}
						gif_dcb.timeout_period = 100 * ((w*h)/(640*480)+1); // 1 second per (640x480)
						GIF_src += 8;

						// skip LCT if exist
						n = *GIF_src++;
						if(n&0x80)
						{	
							n=1<<((n&0x7)+1);
							GIF_src += n*3;
						}
						// skip LZW code size
						GIF_src++;
						
						// skip data blocks 
						do{
						n = *GIF_src++;							
						GIF_src += n;
						}while(n != 0);  
						
						// trigger hw decoder
						DRVPDN_Disable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);
						if(gif_dcb.frame_counter == 0)	
						{						
							status = GIF_DecodeFirst(s->img_adrs,(void*)s->work_adrs, s->img_size);									
						}
						else
						{
							status = GIF_DecodeNext((void*)s->work_adrs);							
						}			
						if(status < 0)			
							goto	gif_display_end;							
						if(w != gif_dcb.gif_info.width ||
							h != gif_dcb.gif_info.height)
						{
							status = GIF_HW_DECODE_FAIL;
							goto gif_display_end;
						}						 
						if(status == GIF_LAST_FRAME)
						{
							gif_dcb.trailer = KAL_TRUE; // hardware detect the trailer
						}
						else if(GIF_src[0] == 0x3B||GIF_src[1] == 0x3B)
						{
							gif_dcb.trailer = KAL_TRUE; // software detect the trailer
						}												
						if(/*gif_dcb.frame_counter == 0 || */gif_disposal == GIF_RESTORE_BG)							
						{
							kal_bool tmp;
							
							if(!s->decode_test)
							{
								tmp = GIF_G2D_FillBG(s,&gif_dcb.gif_info); 
								if( tmp == KAL_FALSE)
								{
									if(gif_dcb.trailer == KAL_TRUE)
										status = GIF_LAST_FRAME;
									else
										status = GIF_OUT_OF_RANGE;
									goto gif_display_end;
								}
							}
						}	
						if(!s->decode_test)
							GIF_G2D_BitBlt(s,&gif_dcb.gif_info);										
						if(s->frame_number == gif_dcb.frame_counter)
						{
							gif_dcb.frame_counter++;
							gif_dcb.current_adrs = GIF_src;							
							if(gif_dcb.trailer == KAL_TRUE)
								status = GIF_LAST_FRAME;

							goto gif_display_end;
						}
						gif_dcb.frame_counter++;
						break;
         case ';': // 0x3b, trailer                  
                  //dbg_print("SW file finish!\r\n");
                  gif_dcb.trailer = KAL_TRUE;
                  status = GIF_LAST_FRAME;
                  goto gif_display_end;
            		break;
    	}
    	if(gif_dcb.trailer) 
    	{
    		status = GIF_LAST_FRAME;
    		goto gif_display_end;
    	}
	} while(GIF_src < GIF_end);

   status = GIF_TRUNCATED_FILE;

gif_display_end:	  

	if(status < 0)
		GIF_Reset();	
	if(status == GIF_LAST_FRAME)
	{
		if(s->frame_number > (gif_dcb.frame_counter-1))
			status = GIF_NO_FRAME;
	}	
	*info = gif_dcb.gif_info;
	gif_dcb.state = GIF_STATE_READY;
	DRVPDN_Enable(DRVPDN_CON3,DRVPDN_CON3_GIF,PDN_GIF);						

	return status;
}

#endif // MT6219


⌨️ 快捷键说明

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