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

📄 jpeg.c

📁 最新MTK手机软件源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	VISUAL_Register_HISR(VISUAL_JPEG_DEC_HISR_ID,jpeg_decoder_HISR);
	VISUAL_Register_HISR(VISUAL_JPEG_ENC_HISR_ID,jpeg_encoder_HISR);
	VISUAL_Register_HISR(VISUAL_JPEG_DEC_CB_HISR_ID,jpeg_decode_cb_HISR);

	IRQUnmask(IRQ_JPEG_DEC_CODE);
	IRQUnmask(IRQ_JPEG_ENC_CODE);
#endif
#ifndef __MAUI_BASIC__
	if (jpeg_codec_sleep_mode_handler==0xFF)
		jpeg_codec_sleep_mode_handler = L1SM_GetHandle();
#endif /* __MAUI_BASIC__ */
}	/* jpeg_codec_init() */

kal_uint32 jpeg_decode_time_estimate(void)
{
	kal_uint32 decode_time;

#if (defined(JPEG_DRV_V3))
	if (jpeg_file_para.jpg_progressive == KAL_TRUE)
	{
		decode_time = ((300 * jpeg_file_para.jpg_decode_width * jpeg_file_para.jpg_decode_height)/1000000 +
							(jpeg_decode_config_data.jpeg_file_size /2000 + 10))* jpeg_file_para.progressive_decode_times;
	}
	else
	{
		decode_time = ((300 * jpeg_file_para.jpg_decode_width * jpeg_file_para.jpg_decode_height)/1000000 +
							(jpeg_decode_config_data.jpeg_file_size /2000 + 10));
	}
#else
	if (jpeg_file_para.jpg_progressive==KAL_TRUE)
	{
		decode_time = ((1000 * jpeg_file_para.jpg_decode_width * jpeg_file_para.jpg_decode_height)/1000000 +
							(jpeg_decode_config_data.jpeg_file_size /2000 + 10))* jpeg_file_para.progressive_decode_times;
	}
	else
	{
		decode_time = ((1000 * jpeg_file_para.jpg_decode_width * jpeg_file_para.jpg_decode_height)/1000000 +
							(jpeg_decode_config_data.jpeg_file_size /2000 + 10));
	}
#endif
	if (decode_time<1000)
		decode_time=1000;
	return decode_time;
}

/*************************************************************************
* FUNCTION
*	   jpeg_codec_deinit
*
* DESCRIPTION
*	   This function power down the jpeg codec and resizer (for MT6218B).
*
* PARAMETERS
*
* RETURNS
*		None
*
* GLOBALS AFFECTED
*
*************************************************************************/
void jpeg_codec_deinit(void)
{
#if (defined(JPEG_DRV_V1))
	IRQMask(IRQ_JPEG_CODE);
	IRQMask(IRQ_RESZ_CODE);

	jpeg_decoder_operation_state = JPEG_DECODER_IDLE_STATE;
#elif (defined(JPEG_DRV_V2))
	jpeg_decoder_operation_state=JPEG_DECODER_IDLE_STATE;
	jpeg_encoder_operation_state=JPEG_ENCODER_IDLE_STATE;

	IRQMask(IRQ_JPEG_CODE);
#elif (defined(JPEG_DRV_V3))
	jpeg_decoder_operation_state=JPEG_DECODER_IDLE_STATE;
	jpeg_encoder_operation_state=JPEG_ENCODER_IDLE_STATE;

	IRQMask(IRQ_JPEG_DEC_CODE);
	IRQMask(IRQ_JPEG_ENC_CODE);
#endif
}	/* jpeg_codec_deinit() */

/*************************************************************************
* FUNCTION
*	   parse_exif
*
* DESCRIPTION
*	   This function parse the EXIF in a JPEG file.
*
* PARAMETERS
*		jpeg_file_handle	the file handler of JPEG file, 0 stands for the
*							   JPEG stream is in buffer already.
*     jpg_file_ptr    	the start address pointer for the parsed jpeg file
*     jpeg_file_offset	the EXIF data offset from the head of JPEG file or JPEG stream
*     exif_size			size of the EXIF data stream
*
* RETURNS
*		0	 			the EXIF data stream parsing success
*		not 0				the EXIF data stream parsing fail
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_int32 parse_exif(kal_uint32 jpeg_file_handle, kal_uint8 *jpg_file_ptr, kal_uint32 jpeg_file_buffer_size,
						  kal_uint32 jpg_file_offset,kal_uint32 exif_size,kal_uint16 *exif_file_offset)
{
	kal_uint32 index,exif_offset;
	kal_uint32 fs_read_size;
	kal_uint8 endian_flag,num_of_required_tag,num_of_current_tag,num_of_parsed_tag=0;
	kal_uint16 num_of_ifd_tag, first_ifd_offset,tag_id,tag_value=0,tag_count,tag_type=0;

	if (jpeg_file_handle!=0)
	{
		index=0;
		jpeg_DRM_seek_file((FS_HANDLE) jpeg_file_handle, jpg_file_offset, FS_FILE_BEGIN);
		jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
	}
	else
	{
		index=jpg_file_offset;
	}
	exif_offset=jpg_file_offset;

	/* parse TIFF header */
	if ((jpg_file_ptr[index]==0x49) && (jpg_file_ptr[index+1]==0x49))
	{
		endian_flag=0;	/* little endian */
		if ((jpg_file_ptr[index+2]!=0x2A)||(jpg_file_ptr[index+3]!=0x00))
			return -1;
		index+=((jpg_file_ptr[index+7]<<24)|(jpg_file_ptr[index+6]<<16)|(jpg_file_ptr[index+5]<<8)|
				  jpg_file_ptr[index+4]);
	}
	else if ((jpg_file_ptr[index+0]==0x4D) && (jpg_file_ptr[index+1]==0x4D))
	{
		endian_flag=1;	/* big endian */
		if ((jpg_file_ptr[index+3]!=0x2A)||(jpg_file_ptr[index+2]!=0x00))
			return -1;
		index+=((jpg_file_ptr[index+4]<<24)|(jpg_file_ptr[index+5]<<16)|(jpg_file_ptr[index+6]<<8)|
				  jpg_file_ptr[index+7]);
	}
	else
		return -1;

	/* find the 1st IFD pointer */
	if (endian_flag==0)
	{
		num_of_ifd_tag=(jpg_file_ptr[index+1]<<8)|(jpg_file_ptr[index]);
		index+=(num_of_ifd_tag*12+2);
		first_ifd_offset = ((jpg_file_ptr[index+3]<<24)|(jpg_file_ptr[index+2]<<16)|(jpg_file_ptr[index+1]<<8)|
				  jpg_file_ptr[index]);
	}
	else
	{
		num_of_ifd_tag=(jpg_file_ptr[index]<<8)|(jpg_file_ptr[index+1]);
		index+=(num_of_ifd_tag*12+2);
		first_ifd_offset=((jpg_file_ptr[index]<<24)|(jpg_file_ptr[index+1]<<16)|(jpg_file_ptr[index+2]<<8)|
				  jpg_file_ptr[index+3]);
	}

	if (first_ifd_offset==0)
		return -1;

	index=exif_offset+first_ifd_offset;
	if (jpeg_file_handle!=0)
	{
		jpeg_DRM_seek_file((FS_HANDLE) jpeg_file_handle, index, FS_FILE_BEGIN);
		jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
		index=0;
	}

	if (endian_flag==0)
	{
		num_of_ifd_tag=(jpg_file_ptr[index+1]<<8)|(jpg_file_ptr[index]);
	}
	else
	{
		num_of_ifd_tag=(jpg_file_ptr[index]<<8)|(jpg_file_ptr[index+1]);
	}

	index+=2;
	num_of_required_tag=5;
	num_of_current_tag=0;

	do
	{
		if (endian_flag==0)
		{
			tag_id=(jpg_file_ptr[index+1]<<8)|(jpg_file_ptr[index]);
			tag_type=(jpg_file_ptr[index+3]<<8)|(jpg_file_ptr[index+2]);
			tag_count=((jpg_file_ptr[index+7]<<24)|(jpg_file_ptr[index+6]<<16)|
						  (jpg_file_ptr[index+5]<<8)|jpg_file_ptr[index+4]);
			if (tag_type==EXIF_TAG_TYPE_SHORT)
			{
				tag_value=(jpg_file_ptr[index+9]<<8)|(jpg_file_ptr[index+8]);
			}
			else if (tag_type==EXIF_TAG_TYPE_LONG)
			{
				tag_value=((jpg_file_ptr[index+11]<<24)|(jpg_file_ptr[index+10]<<16)|
							  (jpg_file_ptr[index+9]<<8)|jpg_file_ptr[index+8]);
			}
		}
		else
		{
			tag_id=(jpg_file_ptr[index]<<8)|(jpg_file_ptr[index+1]);
			tag_type=(jpg_file_ptr[index+2]<<8)|(jpg_file_ptr[index+3]);
			tag_count=((jpg_file_ptr[index+4]<<24)|(jpg_file_ptr[index+5]<<16)|
						  (jpg_file_ptr[index+6]<<8)|jpg_file_ptr[index+7]);
			if (tag_type==EXIF_TAG_TYPE_SHORT)
			{
				tag_value=(jpg_file_ptr[index+8]<<8)|(jpg_file_ptr[index+9]);
			}
			else if (tag_type==EXIF_TAG_TYPE_LONG)
			{
				tag_value=((jpg_file_ptr[index+8]<<24)|(jpg_file_ptr[index+9]<<16)|
							  (jpg_file_ptr[index+10]<<8)|jpg_file_ptr[index+11]);
			}
		}

		switch (tag_id)
		{
			case EXIF_TAG_COMPRESSION:
				if (tag_value==EXIF_JPEG_COMPRESSED)
				{
					num_of_required_tag=2;
					jpeg_thumb_para.jfif_mode= EXIF_MODE_JPEG;
				}
				num_of_current_tag++;
			break;
			case EXIF_TAG_IMAGE_WIDTH:
				jpeg_thumb_para.jpg_width=tag_value;
				num_of_current_tag++;
			break;
			case EXIF_TAG_IMAGE_HEIGHT:
				jpeg_thumb_para.jpg_height=tag_value;
				num_of_current_tag++;
			break;
			case EXIF_TAG_PIXEL_COMPOSITION:
				if (tag_value==EXIF_NON_COMPRESSED_RGB)
					jpeg_thumb_para.jfif_mode= EXIF_MODE_RGB;
				else	/* do not support YCbCr format thumbnail */
					return -1;
				num_of_current_tag++;
			break;
			case EXIF_TAG_STRIP_OFFSET:
			case EXIF_TAG_JPEG_SOI_OFFSET:
				*exif_file_offset=tag_value;
				num_of_current_tag++;
			break;
			default:
			break;
		}
		index+=12;
		num_of_parsed_tag++;
	}	while ((num_of_required_tag!=num_of_current_tag) && (num_of_ifd_tag>num_of_parsed_tag));

	if (num_of_required_tag==num_of_current_tag)
		return 0;
	else
		return -1;
}	/* parse_exif()*/

/*************************************************************************
* FUNCTION
*	   parse_jpeg_thumbnail
*
* DESCRIPTION
*	   This function parse the parameters of compressed type thumbnail of a JPEG file.
*
* PARAMETERS
*     jpeg_file_handle  the file handler of the parsed jpeg file
*     jpg_file_ptr    	the start address pointer of the parsed jpeg file or
*								the buffer pointer for temporary JPEG data buffer
*     jpeg_file_buffer_size    the size of the parsed jpeg file or JPEG data buffer
*     jpg_file_offset	the data offset from the beginning of the JPEG file.
*     thumbnail_size    the size of the thumbnail data
*
* RETURNS
*		0			if the compressed thumbnail data parse correctly.
*		not 0		if the compressed thumbnail data parse failed.
*
* GLOBALS AFFECTED
*
*************************************************************************/
kal_int32 parse_jpeg_thumbnail(kal_uint32 jpeg_file_handle, kal_uint8 *jpg_file_ptr, kal_uint32 jpeg_file_buffer_size,
						  				kal_uint32 jpg_file_offset,kal_uint32 thumbnail_size)
{
	kal_uint8 byte,jpg_byte1,jpg_byte2;
	kal_uint32 index,index_offset;
	kal_uint16 marker_length;
	kal_uint32 jpeg_file_index=0;
	kal_uint32 fs_read_size;
	kal_uint8 i;
	kal_uint8 parse_end_flag=0;
	kal_uint32 huffman_q_table_size=0;
	kal_uint8 restart_marker_flag=0;
	index=0;

	if (jpeg_file_handle!=0)
	{
		jpeg_DRM_seek_file((FS_HANDLE) jpeg_file_handle, jpg_file_offset, FS_FILE_BEGIN);
		jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
	}

	jpg_byte1=jpg_file_ptr[index++];
	jpg_byte2=jpg_file_ptr[index++];
	jpeg_file_index=jpg_file_offset+2;

	jpeg_thumb_para.jpg_height=0xFFFF;
	jpeg_thumb_para.jpg_width=0xFFFF;
	jpeg_thumb_para.thumbnail_offset=0;
	jpeg_thumb_para.jpg_progressive=KAL_FALSE;

	if ((jpg_byte1==0xFF) && (jpg_byte2==0xD8))
	{
		do
		{
			if (jpeg_file_handle!=0)
			{
				if (jpeg_file_index>=(thumbnail_size+jpg_file_offset))
		      	break;
		   }
		   else
		   {
		   	if (index>=jpeg_file_buffer_size)
		   		break;
		   }

			do
			{
				byte=jpg_file_ptr[index++];
				if (jpeg_file_handle!=0)
				{
					jpeg_file_index++;
					if (index>=(fs_read_size-30))
					{
						index=0;
						jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
					}
				}
			} while (byte!=0xFF);
			jpg_byte1=0xFF;
			jpg_byte2=jpg_file_ptr[index++];

			if (jpeg_file_handle!=0)
			{
				jpeg_file_index++;
				if (index>=(fs_read_size-30))
				{
					index=0;
					jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
				}
			}
			switch (jpg_byte2)
			{
				case JPEG_MARKER_SOF0:
				case JPEG_MARKER_SOF2:
					if (jpg_byte2==JPEG_MARKER_SOF2)
					{
						return -1;
					}
					marker_length=(jpg_file_ptr[index++]<<8);
					marker_length += (int) (jpg_file_ptr[index++]-2);
					jpeg_thumb_para.jpg_precision=jpg_file_ptr[index++];
					jpeg_thumb_para.jpg_height=(jpg_file_ptr[index++]<<8);
					jpeg_thumb_para.jpg_height|=jpg_file_ptr[index++];
					jpeg_thumb_para.jpg_width=(jpg_file_ptr[index++]<<8);
					jpeg_thumb_para.jpg_width|=jpg_file_ptr[index++];
					jpeg_thumb_para.number_of_component=jpg_file_ptr[index++];
					jpeg_thumb_para.component_id1=jpg_file_ptr[index++];
					jpeg_thumb_para.y_h_sample_factor=(jpg_file_ptr[index]&0xF0)>>4;
					jpeg_thumb_para.y_v_sample_factor=jpg_file_ptr[index++]&0x0F;
			      jpeg_thumb_para.q_table_id1=jpg_file_ptr[index++];
					jpeg_file_index+=11;

					if (jpeg_thumb_para.number_of_component>=2)
					{
					   jpeg_thumb_para.component_id2=jpg_file_ptr[index++];
					   jpeg_thumb_para.u_h_sample_factor=(jpg_file_ptr[index]&0xF0)>>4;
					   jpeg_thumb_para.u_v_sample_factor=jpg_file_ptr[index++]&0x0F;
					   jpeg_thumb_para.q_table_id2=jpg_file_ptr[index++];
   					jpeg_file_index+=3;

						if (jpeg_thumb_para.number_of_component>=3)
						{
					      jpeg_thumb_para.component_id3=jpg_file_ptr[index++];
					      jpeg_thumb_para.v_h_sample_factor=(jpg_file_ptr[index]&0xF0)>>4;
					      jpeg_thumb_para.v_v_sample_factor=jpg_file_ptr[index++]&0x0F;
					      jpeg_thumb_para.q_table_id3=jpg_file_ptr[index++];
					      jpeg_file_index+=3;
					   }
					   else
					   {
    					   jpeg_thumb_para.component_id3=0;
	    				   jpeg_thumb_para.v_h_sample_factor=0;
		    			   jpeg_thumb_para.v_v_sample_factor=0;
			    		   jpeg_thumb_para.q_table_id3=0;
                  }
               }
               else
               {
					   jpeg_thumb_para.component_id2=0;
					   jpeg_thumb_para.u_h_sample_factor=0;
					   jpeg_thumb_para.u_v_sample_factor=0;
					   jpeg_thumb_para.q_table_id2=0;
  					   jpeg_thumb_para.component_id3=0;
   				   jpeg_thumb_para.v_h_sample_factor=0;
	    			   jpeg_thumb_para.v_v_sample_factor=0;
		    		   jpeg_thumb_para.q_table_id3=0;
               }
               parse_end_flag|=0x01;
				break;
				case JPEG_MARKER_SOS:
              	jpg_byte2=0xD9;
				break;
				case 0xC8:
				case 0x00:
				break;
				case JPEG_MARKER_DQT:
				case JPEG_MARKER_DHT:
					if (jpeg_thumb_para.thumbnail_offset==0)	/* set thumbnail_offset when first time met DQT or DHT */
						jpeg_thumb_para.thumbnail_offset=jpeg_file_index-jpg_file_offset-2;

					index_offset=(jpg_file_ptr[index++]<<8);
					index_offset += (int) (jpg_file_ptr[index++]-2);
					huffman_q_table_size+=index_offset;
					index+=index_offset;
					if (jpeg_file_handle!=0)
					{
						jpeg_file_index+=(index_offset+2);
					}
					if (jpg_byte2==JPEG_MARKER_DQT)
						parse_end_flag|=0x02;
					else
						parse_end_flag|=0x04;
					/* make sure DQT,DHT and SOF are read or table size overflow*/
					if (huffman_q_table_size>=0x800)
						jpg_byte2=0xD9;
				break;
				default:
				   if ((jpg_byte2==JPEG_MARKER_SOF1) || (jpg_byte2==JPEG_MARKER_DNL)||
				      ((jpg_byte2>=JPEG_MARKER_SOF3) && (jpg_byte2<=JPEG_MARKER_SOF15))||
				      (jpg_byte2==JPEG_MARKER_DRI) || (jpg_byte2==JPEG_MARKER_DHP) ||
				      (jpg_byte2==JPEG_MARKER_EXP) || (jpg_byte2==JPEG_MARKER_COM) ||
				      ((jpg_byte2>=JPEG_MARKER_APP0) && (jpg_byte2<=JPEG_MARKER_APP15)))
					{
						index_offset=(jpg_file_ptr[index++]<<8);
						index_offset += (int) (jpg_file_ptr[index++]-2);
						index+=index_offset;
						if (jpeg_file_handle!=0)
						{
							jpeg_file_index+=(index_offset+2);
							if (index>=(fs_read_size-30))
							{
								index=0;

								jpeg_DRM_seek_file((FS_HANDLE) jpeg_file_handle, jpeg_file_index, FS_FILE_BEGIN);
								jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr, 512, &fs_read_size);
							}
						}
						if (jpg_byte2==JPEG_MARKER_DRI)
							restart_marker_flag=1;
					}
				break;
			}
		} while (!((jpg_byte1==0xFF) && (jpg_byte2==0xD9)));
	}
	else
		return -1;

	if ((jpeg_thumb_para.y_h_sample_factor + jpeg_thumb_para.y_v_sample_factor +
		  jpeg_thumb_para.u_h_sample_factor + jpeg_thumb_para.u_v_sample_factor +
		  jpeg_thumb_para.v_h_sample_factor + jpeg_thumb_para.v_v_sample_factor)>10)
	{
		return -1;
	}

	if (jpeg_file_handle!=0)
	{
		jpeg_DRM_seek_file((FS_HANDLE) jpeg_file_handle, (thumbnail_size+jpg_file_offset-20),FS_FILE_BEGIN);
		jpeg_DRM_read_file((FS_HANDLE) jpeg_file_handle, jpg_file_ptr,20, &fs_read_size);
		for (i=1;i<20;i++)
		{
			jpg_byte2=jpg_file_ptr[fs_read_size-i];
			if (jpg_byte2==0xD9)
			{
				jpg_byte1=jpg_file_ptr[fs_read_size-i-1];
				if (jpg_byte1==0xFF)
					break;

⌨️ 快捷键说明

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