S3C6410 裸機硬體JPEG解碼

NO IMAGE

 

2012年12月25日,晚上我找到問題所在了,JPEG解碼源影象地址必須是16位元組(128位)對齊的,也就是最低4位必須為0,這個害的我好久,還好終於解決了。

修復了已知的bug;

這個是我實驗用的原圖,用工具把他變成了陣列後直接放在程式裡面了.

解碼後的圖片

附上程式碼

/*************************************************************************************************************
* 檔名			:	JpegCodec.c
* 功能			:	S3C6410 JPEG解碼底層驅動函式
* 作者			:	[email protected]
* 建立時間		:	2012年9月20日20:59
* 最後修改時間	:	2012年12月02日
* 詳細			:	JPEG硬解碼
* 					通過S3C6410 DATASHEETV1.2版以及官方WINCE的JPEG驅動的分析,得出結論,S3C6410的JPEG解碼模組不支援硬體控制自動解碼
* 					只能使用軟體控制解碼模式
* 			20121202:修復連續解碼BUG,目前有少數jpeg420,jpeg444會解碼出錯,就像windows也有可能有不支援的jpeg圖片一樣,少數圖片硬解碼
* 					失敗可以嘗試使用軟解碼即可。
* 			20121225:發現JPEG必須16位元組(128位)地址對齊,否則可能會出現解碼失敗問題。
* 			20130113:增加尺寸非8或16倍數的jpeg圖片解碼功能
* 			20130113:將程式外部依賴降低,目前只依賴外部的資料型別定義(高類聚,低耦合),列印除錯也依賴外部,不用可以修改巨集,JPEG_DBUG=0來取消,方便移植。
*************************************************************************************************************/
#include "JpegCodec.h"
#include "jpeg_tables.h"
//除錯巨集開關
#define JPEG_DBUG	0
#if JPEG_DBUG
#include "system.h"
#define jpeg_debug(format,...)	uart_printf(format,##__VA_ARGS__)
#else
#define jpeg_debug(format,...)	/\
/
#endif	//JPEG_DBUG
//jpeg編解碼模式配置
#define COEF1_RGB_2_YUV         0x4d971e
#define COEF2_RGB_2_YUV         0x2c5783
#define COEF3_RGB_2_YUV         0x836e13
#define ENABLE_MOTION_ENC       (0x1<<3)		//使能動態編碼
#define DISABLE_MOTION_ENC      (0x0<<3)
#define ENABLE_HW_DEC           (0x1<<2)
#define DISABLE_HW_DEC          (0x0<<2)
#define ENABLE_MOTION_DEC       (0x1<<0)		//使能動態解碼
#define DISABLE_MOTION_DEC      (0x0<<0)		
#define INCREMENTAL_DEC			(0x1<<3)		//增量解碼模式
#define NORMAL_DEC              (0x0<<3)		//正常解碼模式
#define YCBCR_MEMORY			(0x1<<5)
#define	ENABLE_IRQ				(0xf<<3)
//等待超時定義
#define WaitTimeOut				0xffffff			//等待超時計數器
//定義最大影象寬高度
#define MAX_JPG_WIDTH		4096
#define MAX_JPG_HEIGHT		4096
//JPEG暫存器結構定義
typedef struct
{
u32		Mode;				//模式暫存器
u32		Status;				//狀態暫存器
u32		QTblNo;
u32		RSTPos;
u32		Vertical;			//垂直解析度
u32		Horizontal;			//水平解析度
u32		DataSize;			//壓縮資料位元組數
u32		IRQ;				//中斷設定暫存器
u32		IRQStatus;			//中斷狀態暫存器	0x20
u32		Reserved0[247];
u32		QTBL0[64];							//0x400
u32		QTBL1[64];
u32		QTBL2[64];
u32		QTBL3[64];
u32		HDCTBL0[16];						//0x800
u32		HDCTBLG0[12];
u32		Reserved1[4];
u32		HACTBL0[16];
u32		HACTBLG0[162];						//0x8c0
u32		Reserved2[46];
u32		HDCTBL1[16];						//0xc00
u32		HDCTBLG1[12];
u32		Reserved3[4];
u32		HACTBL1[16];
u32		HACTBLG1[162];						//0xcc0
u32		Reserved4[46];
u32		ImageAddr0;			//目的影象地址1
u32		ImageAddr1;			//目的影象地址2
u32		JpegAddr0;			//源JPEG影象地址1
u32		JpegAddr1;			//源JPEG影象地址2
u32		Start;				//JPEG解碼開始
u32		ReStart;			//重新開始JPEG解碼
u32		SofReset;			//JPEG復位
u32		Cntl;				//控制暫存器
u32		COEF1;
u32		COEF2;
u32		COEF3;
u32		Misc;				//雜項暫存器
u32		FramIntv;
}JPEG_TypeDef;
//定義JPEG檔案標記
enum
{
UNKNOWN,
BASELINE = 0xC0,
EXTENDED_SEQ = 0xC1,
PROGRESSIVE = 0xC2
}JPG_SOF_MARKER;
//S3C6410 jpeg編解碼器基址
#define JPEG_BASE		0x78800000	
//暫存器結構指標
#define JPEG	((JPEG_TypeDef *)JPEG_BASE)
//內部靜態函式宣告
static void JPEG_Reset(void);		//JPEG解碼器軟體復位
static JPEG_TYPE JPEG_GetJpegType(void);	//獲取JPEG取樣模式
static void JPEG_GetWidthHeight(u16* width, u16* height);//獲取影象大小
static JPEG_ERROR JPEG_WaitForIRQ(void);	//等待中斷,並返回狀態
static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height);
static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height);
static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight);
static void JPEG_MemMove(u8* dest, u8* src,u32 count);
/*************************************************************************************************************************
*函式    		:	void JPEG_Init(void)
*功能    		:	JPEG解碼初始化
*引數    		:	無
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間     	:	20120920
*最後修改時間	:	20120923
*說明     	:	無
*************************************************************************************************************************/
void JPEG_Init(void)
{
//rCLK_DIV0 |= 0x03 << 24;
//Set_GateClk(SCLK_JPEG,ENABLE);	//使能JPEG模組時鐘
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_Reset(void)
*功能    		:	JPEG解碼器軟體復位
*引數    		:	無
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	無
*************************************************************************************************************************/
static void JPEG_Reset(void)
{
JPEG->SofReset = 0;
}
/*************************************************************************************************************************
*函式    		:	static JPEG_TYPE JPEG_Reset(void)
*功能    		:	獲取JPEG取樣模式
*引數    		:	無
*返回    		:	JPEG型別,見定義
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	編碼模式只有0x1,0x2兩種模式
*************************************************************************************************************************/
static JPEG_TYPE JPEG_GetJpegType(void)
{
switch (JPEG->Mode & 0x07)	//通過判斷0-2BIT
{
case 0	:	return TYPE_JPEG_444;		//色度4:4:4格式
case 1	: 	return TYPE_JPEG_422;		//色度4:2:2格式
case 2	: 	return TYPE_JPEG_420;		//色度4:2:0格式
case 3	: 	return TYPE_JPEG_400;		//灰色格式(單一組成)
case 6	: 	return TYPE_JPEG_411;		//色度4:1:1格式
default : 	return TYPE_JPEG_UNKNOWN;	
}
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_GetWidthHeight(u16* width, u16* height)
*功能    		:	獲取影象尺寸大小
*引數    		:	HSize:影象寬度緩衝區指標;VSize:影象高度緩衝區指標
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	16BIT
*************************************************************************************************************************/
static void JPEG_GetWidthHeight(u16* width, u16* height)
{
*width = JPEG->Horizontal;		//在水平方向上定義影象大小的值
*height = JPEG->Vertical;		//在垂直方向上定義影象大小的值
}
/*************************************************************************************************************************
*函式    		:	u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height)
*功能    		:	獲取解碼後資料大小
*引數    		:	jpegType:jpeg影象型別,width,height:影象尺寸
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	2010113
*最後修改時間	:	2010113
*說明    		:	無
*************************************************************************************************************************/
u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height)
{
switch(jpegType)
{
case TYPE_JPEG_444 : 	return(width*height*3);
case TYPE_JPEG_422 : 	return(width*height*2);
case TYPE_JPEG_420 :	
case TYPE_JPEG_411 : 	return((width*height)   (width*height>>1));
case TYPE_JPEG_400 : 	return(width*height);
default : 				return(0);
}
}
/*************************************************************************************************************************
*函式    		:	void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus)
*功能    		:	讀取並清除JPEG狀態
*引數    		:	Status:解碼器狀態緩衝區指標;IrqStatus:中斷狀態緩衝區指標
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	JPGSTS和JPGIRQ;JPGIRQ讀取後自動清除
* 				JPGIRQ:	BIT6結果狀態	0:不正常的處理結束; 1:正常的處理完成
* 					BIT4位流的錯誤狀態。只有在解壓縮期間有效。0:在被壓縮的檔案上,沒有語法錯誤。1:在被壓縮的檔案上,有語法錯誤。
* 					BIT3標題狀態。只有在解壓縮期間有效。0:影象大小和取樣因素值不可讀。1:影象大小和取樣因素值可讀。	
*************************************************************************************************************************/
void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus)
{
*Status = JPEG->Status;
*IrqStatus = JPEG->IRQStatus & ((1<<6)|(1<<4)|(1<<3));
}
/*************************************************************************************************************************
*函式    		:	static JPEG_ERROR JPEG_WaitForIRQ(void)
*功能    		:	等待中斷,並返回狀態
*引數    		:	無
*返回    		:	返回中斷狀態,見定義
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120922
*最後修改時間	:	2010113
*說明    		:	通過判斷JPGIRQ中斷暫存器的值返回相應狀態
*************************************************************************************************************************/
static JPEG_ERROR JPEG_WaitForIRQ(void)
{  
vu32 TimeOut = WaitTimeOut;  //初始化計數器值  
vu8 IRQStatus,Status; 
JPEG_ERROR error;
do  
{     
IRQStatus = JPEG->IRQStatus;		//讀取中斷狀態暫存器,並消除狀態 
TimeOut --;             			//計數器自減  
}  
while((IRQStatus == 0) && TimeOut);     //當發生中斷或者計數器為0時退出等待 
IRQStatus &= ((1<<6)|(1<<4)|(1<<3));
switch (IRQStatus)              		//判斷中斷狀態  
{  
case 0x00 : error =  JPEG_WAIT_TIME_OUT;break;  //超時錯誤
case 0x40 : error =  JPEG_OK;break; 			//正常完成  
case 0x08 : error =  JPEG_HEADER_OK;break;  	//頭分析完成,可以讀取大小以及取樣資訊  
case 0x10 : error =  JPEG_BITSTRE_ERROR;break;  //語法錯誤  
case 0x18 : error =  JPEG_BITSTRE_ERROR;break;  //語法錯誤  
default : error =  JPEG_OTHER_ERROR;break;      //其它錯誤  
}
Status = JPEG->Status;
return error;
} 
/*************************************************************************************************************************
*函式    		:	static void JPEG_DecodeHeader(u32 JpegAddr)
*功能    		:	開始解碼JPEG頭部資訊(軟體控制解碼)
*引數    		:	JpegAddr:	jpeg影象地址
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	用於軟體解碼的第一步,用於獲取JPEG解析度以及取樣模式資訊
*************************************************************************************************************************/
static void JPEG_DecodeHeader(u32 JpegAddr)
{
JPEG->JpegAddr0 = JpegAddr;
JPEG->JpegAddr1 = JpegAddr; 		//jpeg圖片資料地址
JPEG->Mode = 0x8; 					//設定為解碼模式
JPEG->IRQ = ENABLE_IRQ;				//使能中斷
JPEG->Cntl = DISABLE_HW_DEC;		//解碼JPEG頭部
JPEG->Misc = (NORMAL_DEC | YCBCR_MEMORY);
JPEG->Start = 1;					//開始JPEG處理
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_DecodeBody(u32 ImageAddr)
*功能    		:	開始JPEG主體解碼(軟體控制解碼)
*引數    		:	ImageAddr:	解碼後影象地址
*返回    		:	無
*依賴		: 	底層巨集定義
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	軟體控制解碼的第二步,一定要先呼叫JPEG_StartParsingHeader
*************************************************************************************************************************/
static void JPEG_DecodeBody(u32 ImageAddr)
{
JPEG->ImageAddr0 = ImageAddr;
JPEG->ImageAddr1 = ImageAddr;		//解碼資料緩衝器地址
JPEG->Cntl = 0;						//解碼JPEG頭部
JPEG->Misc = 0;
JPEG->ReStart = 1;					//開始主解碼處理
}
/*************************************************************************************************************************
*函式    		:	JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo)
*功能    		:	開始解碼一幀JPEG
*引數    		:	JpegAddr:	jpeg影象地址
* 				ImageAddr:	解碼後影象地址
* 				jpegSize:	圖片資料大小
* 				JpegInfo:	影象資訊結構指標
*返回    		:	JPEG_ERROR
*依賴		: 	JPEG_StartParsingHeader;JPEG_StartDecodingBody
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	軟體控制解碼模式
* 				修改源影象地址128位對齊bug
* 				20120113:增加尺寸非8或16倍數的jpeg圖片解碼功能,需要傳遞一個引數,即圖片大小,通過FileSize傳遞
* 							非對齊的jpeg解碼效率將低於對齊的圖片,由於解碼前需要先改寫資料。
*************************************************************************************************************************/
JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo)
{
JPEG_ERROR status;
u16 	width,height;
bool	headerFixed = FALSE;
#if JPEG_DBUG	
const char *JpegType[6] = {"JPEG 4:4:4","JPEG 4:2:2","JPEG 4:2:0","JPEG 4:0:0","JPEG 4:1:1","JPEG UNKNOWN"};
#endif
if(JpgAddr % 16)					//源地址一定要是16位元組(128位)對齊的,否則會出現各種意想不到的問題,這個問題困擾了我5個多月。
{	
jpeg_debug("jpeg addr error\r\n");
return JPEG_OTHER_ERROR;
}
JpegInfo->FileSize = jpegSize;		//儲存圖片大小
jpeg_debug("\r\n");
jpeg_debug("start jpeg decoding...\r\n");
JPEG_Reset();
JPEG_DecodeHeader(JpgAddr);			//分析JPEG文資訊
status = JPEG_WaitForIRQ();			//等待完成
if(status != JPEG_HEADER_OK)		//影象分析錯誤
{
return status;
}
JpegInfo->Type = JPEG_GetJpegType();		//獲取圖片型別
jpeg_debug("Jpeg Mod:%s\r\n",JpegType[JpegInfo->Type]);
if(JpegInfo->Type == TYPE_JPEG_UNKNOWN)	//未定義型別
{
return JPEG_TYPE_ERROR;
}
JPEG_GetWidthHeight(&(JpegInfo->Width),&(JpegInfo->Height));				//獲取圖片解析度
width = JpegInfo->Width;
height = JpegInfo->Height;
if(!JPEG_CorrectHeader(JpegInfo->Type, &(JpegInfo->Width), &(JpegInfo->Height)))
{
JPEG_WriteHeader(JpgAddr,jpegSize,JpegInfo->Width, JpegInfo->Height);
headerFixed = TRUE;
}
jpeg_debug("jpeg image size %d*%d\r\n",JpegInfo->Width,JpegInfo->Height);
if(JpegInfo->Width <= 0 || JpegInfo->Width > MAX_JPG_WIDTH || JpegInfo->Height <= 0 || JpegInfo->Height > MAX_JPG_HEIGHT)
{
return JPEG_SIZE_ERROR;
}
if(headerFixed == TRUE)
{
JPEG_Reset();
JPEG_DecodeHeader(JpgAddr);			//分析JPEG文資訊
status = JPEG_WaitForIRQ();			//等待完成
if(status != JPEG_HEADER_OK)		//影象分析錯誤
{
return status;
}
JPEG_DecodeBody(ImageAddr);			//解碼JPEG
status = JPEG_WaitForIRQ();			//等待完成
if(status == JPEG_OK)
{
jpeg_debug("Jpeg decode OK(%d)\r\n",status);
//JPEG_GetStreamLen(&(JpegInfo->DataSize));	//獲取解碼後影象大小
}
else
{
jpeg_debug("Jpeg decode error(%d)\r\n",status);
return status;
}
// for post processor, discard pixel
if(width % 4 != 0)
width = (width/4)*4;
if(height % 2 != 0)
height = (height/2)*2;
JPEG_WriteYUV(ImageAddr,JpegInfo->Width,width,JpegInfo->Height,height);
JpegInfo->Width = width;
JpegInfo->Height = height;
}
else
{
JPEG_DecodeBody(ImageAddr);			//解碼JPEG
status = JPEG_WaitForIRQ();			//等待完成
if(status == JPEG_OK)
{
jpeg_debug("Jpeg decode OK(%d)\r\n",status);
}
else
{
jpeg_debug("Jpeg decode error(%d)\r\n",status);
return status;
}
}
JpegInfo->DataSize = JPEG_GetYUVSize(JpegInfo->Type,JpegInfo->Width,JpegInfo->Height);
return status;	//返回錯誤
}
/*************************************************************************************************************************
*函式    		:	JPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_INFO *JpegInfo)
*功能    		:	壓縮一張JPEG
*引數    		:	JpegAddr:	jpeg影象地址
* 				ImageAddr:	解碼後影象地址
* 				JpegInfo:	影象資訊結構指標
*返回    		:	JPEG_ERROR
*依賴		: 	無
*作者     		:	[email protected]
*時間    		:	20130114
*最後修改時間	:	201310114
*說明    		:	只支援YCbCr4:2:2,YCbCr4:2:0的輸入格式
* 				只測試了編碼,能成功,但是沒有生成jpeg檔案進行測試,如果要生成jpeg檔案應該還需要新增相應的檔案頭和尾部。
*************************************************************************************************************************/
JPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_QUALITY_TYPE jpegQuality, JPEG_INFO *JpegInfo)
{
JPEG_ERROR status = JPEG_OK;
u32    i;
if(JpegInfo->Width <= 0 || JpegInfo->Width > MAX_JPG_WIDTH || JpegInfo->Height <= 0 || JpegInfo->Height > MAX_JPG_HEIGHT)
{
return JPEG_SIZE_ERROR;
}
JPEG_Reset();
JPEG->Mode = (JpegInfo->Type == TYPE_JPEG_422) ? (0x01 << 0) : (0x02 << 0);		//亞抽樣模式
JPEG->RSTPos = 2;																// MCU inserts RST marker
JPEG->QTblNo = (1 << 12) | (1 << 14);
JPEG->Horizontal = JpegInfo->Width;
JPEG->Vertical = JpegInfo->Height;
JPEG->ImageAddr0 = ImageAddr;
JPEG->ImageAddr1 = ImageAddr;
JPEG->JpegAddr0 = JpgAddr;
JPEG->JpegAddr1 = JpgAddr;
JPEG->COEF1 = COEF1_RGB_2_YUV; // Coefficient value 1 for RGB to YCbCr
JPEG->COEF2 = COEF2_RGB_2_YUV; // Coefficient value 2 for RGB to YCbCr
JPEG->COEF3 = COEF3_RGB_2_YUV; // Coefficient value 3 for RGB to YCbCr
JPEG->Misc = (1<<5) | (0<<2);
JPEG->Cntl = DISABLE_MOTION_ENC;
// Quantiazation and Huffman Table setting
for (i=0; i<64; i  )
JPEG->QTBL0[i] = (u32)QTBL_Luminance[jpegQuality][i];
for (i=0; i<64; i  )
JPEG->QTBL1[i] = (u32)QTBL_Chrominance[jpegQuality][i];
for (i=0; i<16; i  )
JPEG->HDCTBL0[i] = (u32)HDCTBL0[i];
for (i=0; i<12; i  )
JPEG->HDCTBLG0[i] = (u32)HDCTBLG0[i];
for (i=0; i<16; i  )
JPEG->HACTBL0[i] = (u32)HACTBL0[i];
for (i=0; i<162; i  )
JPEG->HACTBLG0[i] = (u32)HACTBLG0[i];
JPEG->Start = 0;
status = JPEG_WaitForIRQ();
if(status == JPEG_OK)
{
jpeg_debug("Jpeg encode OK!(%d)\r\n",status);
JpegInfo->FileSize = JPEG->DataSize;
}
else
{
JpegInfo->FileSize = 0;
jpeg_debug("Jpeg encode error!(%d)\r\n",status);
}
return status;
}
/*************************************************************************************************************************
*函式    		:	static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height)
*功能    		:	檢查影象的寬高時候滿足要求
*引數    		:	jpegType:	jpeg型別,見JPEG_TYPE
* 				width:		影象寬度
* 				height:		影象高度
*返回    		:	TRUE:需要重寫寬度,高度
* 				FALSE:無需重寫寬度,高度
*依賴		: 	無
*作者     		:	[email protected]
*時間    		:	20130113
*最後修改時間	:	20130113
*說明    		:	直接由S3C6410官方程式碼移植而來
* 				如果不滿足要求,將計算最接近的滿足要求的解析度,JPEG解析度需要能被8或者16整除,具體可以查閱相關資料
*************************************************************************************************************************/
static bool JPEG_CorrectHeader(JPEG_TYPE jpegType, u16 *width, u16 *height)
{
bool result = FALSE;
switch(jpegType){
case TYPE_JPEG_400 :
case TYPE_JPEG_444 : 	
{
if((*width % 8 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 8 != 0)
*width  = 8 - (*width % 8);
if(*height % 8 != 0)
*height  = 8 - (*height % 8);
}break;
case TYPE_JPEG_422 : 
{
if((*width % 16 == 0) && (*height % 8 == 0))
result = TRUE;
if(*width % 16 != 0)
*width  = 16 - (*width % 16);
if(*height % 8 != 0)
*height  = 8 - (*height % 8);
}break;
case TYPE_JPEG_420 :
case TYPE_JPEG_411 : 
{
if((*width % 16 == 0) && (*height % 16 == 0))
result = TRUE;
if(*width % 16 != 0)
*width  = 16 - (*width % 16);
if(*height % 16 != 0)
*height  = 16 - (*height % 16);
}break;
default : break;
}
return(result);
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height)
*功能    		:	重寫jpeg頭部資訊
*引數    		:	JpgAddr:		jpeg檔案的起始指標
* 				fileSize:	jpeg檔案大小
* 				width:		jpeg檔案寬度,需要重寫的寬度
* 				height:		jpeg檔案高度,需要重寫的寬度
*返回    		:	無
*依賴		: 	無
*作者     		:	[email protected]
*時間    		:	20130113
*最後修改時間	:	20130113
*說明    		:	重寫的只是記憶體中的資料
*************************************************************************************************************************/
static void JPEG_WriteHeader(u32 JpgAddr, u32 fileSize, u16 width, u16 height)
{
u32    i;
u8    *ptr = (u8 *)(JpgAddr   fileSize);
u8    *ptr2; 
u8    *SOF1;
u8    *header;
jpeg_debug("DD::Header is not multiple of MCU\r\n");
for(i=0; i < fileSize; i  )
{
ptr--;
if(*ptr == 0xFF)
{
ptr2 = ptr 1;
if((*ptr2 == BASELINE) || (*ptr2 == EXTENDED_SEQ) || (*ptr2 == PROGRESSIVE))
{
jpeg_debug("jpeg match FFC0(i : %d)\r\n", i);
SOF1 = ptr2 1;
break;                
}
}
}
jpeg_debug("jpeg start header correction\r\n");
if(i <= fileSize){
//header = (SOF2 == NULL) ? (SOF1) : (SOF2);
header = SOF1;
jpeg_debug("header: %x %x %x\r\n", header[0], header[1], header[2]);
header  = 3; //length(2)   sampling bit(1)
*header = (height>>8) & 0xFF;
*header  ;
*header = height & 0xFF;
*header  ;
*header = (width>>8) & 0xFF;
*header  ;
*header = width & 0xFF;
}
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_MemMove(u8* dest, u8* src,u32 count)
*功能    		:	由src所指記憶體區域複製count個位元組到dest所指記憶體區域
*引數    		:	src:		源地址
* 				dest:	目標地址
* 				count:	資料數量
*返回    		:	無
*依賴		: 	無
*作者     		:	[email protected]
*時間    		:	2013014
*最後修改時間	:	2013114
*說明    		:	記憶體複製,8bit對齊,為了減少外部函式的依賴
*************************************************************************************************************************/
static void JPEG_MemMove(u8* dest, u8* src,u32 count)
{
u32 i;
for(i = 0;i < count;i   )
{
dest[i] = src[i];
}
}
/*************************************************************************************************************************
*函式    		:	static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight)
*功能    		:	重寫YUV資料,將資料對齊
*引數    		:	ImageAddr:	解碼後影象地址
* 				width:		影象對齊後的寬度
* 				orgwidth:	影象原始寬度
* 				height:		影象對齊後的高度
* 				orgheight:	影象原始高度	
*返回    		:	無
*依賴		: 	無
*作者     		:	[email protected]
*時間    		:	20120920
*最後修改時間	:	2010113
*說明    		:	無
*************************************************************************************************************************/
static void JPEG_WriteYUV(u32 ImageAddr, u16 width, u16 orgwidth, u16 height, u16 orgheight)
{
u32    src, dst;
u32    i;
u8    *streamPtr;
streamPtr = (u8 *)ImageAddr;
src = 2*width;
dst = 2*orgwidth;
for(i = 1; i < orgheight; i  )
{
JPEG_MemMove(&streamPtr[dst], &streamPtr[src], 2*orgwidth);
src  = 2*width;
dst  = 2*orgwidth;
}
}

 

/*************************************************************************************************************
* 檔名			:	JpegCodec.H
* 功能			:	S3C6410 JPEG解碼底層驅動函式
* 作者			:	[email protected]
* 建立時間		:	2012年9月20日20:59
* 最後修改時間	:	2012年12月02日
* 詳細			:	JPEG硬解碼
* 					通過S3C6410 DATASHEETV1.2版以及官方WINCE的JPEG驅動的分析,得出結論,S3C6410的JPEG解碼模組不支援硬體控制自動解碼
* 					只能使用軟體控制解碼模式
* 			20121202:修復連續解碼BUG,目前有少數jpeg420,jpeg444會解碼出錯,就像windows也有可能有不支援的jpeg圖片一樣,少數圖片硬解碼
* 					失敗可以嘗試使用軟解碼即可。
* 			20121225:發現JPEG必須16位元組(128位)地址對齊,否則可能會出現解碼失敗問題。
* 			20130113:增加尺寸非8或16倍數的jpeg圖片解碼功能
* 			20130113:將程式外部依賴降低,目前只依賴外部的資料型別定義,列印除錯也依賴外部,不用可以修改巨集,JPEG_DBUG=0來取消,方便移植。
*************************************************************************************************************/
#ifndef __JPEGCODEC_H__
#define __JPEGCODEC_H__
#include "sys_types.h"		//資料型別定義
//JPEG型別定義
typedef enum
{
TYPE_JPEG_444 = 0, 		//JPEG 444
TYPE_JPEG_422 = 1, 		//JPEG 422
TYPE_JPEG_420 = 2, 		//JPEG 420
TYPE_JPEG_400 = 3, 		//JPEG 400 (Gray)
TYPE_JPEG_411 = 4,		//JPEG 411
TYPE_JPEG_UNKNOWN = 5	//未知
} JPEG_TYPE;
//JPEG DEC模式
typedef enum
{
DEC_HEADER = 0, 		//只解碼頭部資訊
DEC_BODY = 1, 			//只解碼主體
} JPEG_DEC_MODE;
//JPEG DEC模式
typedef enum
{
JPEG_OK		=		0,	//正常處理完成
JPEG_HEADER_OK	=	1,	//影象大小和取樣因素值可讀。
JPEG_BITSTRE_ERROR=	2,	//在被壓縮的檔案上,有語法錯誤
JPEG_WAIT_TIME_OUT=	3,	//等待超時
JPEG_TYPE_ERROR   = 4,	//不支援的影象型別,影象型別錯誤
JPEG_SIZE_ERROR   = 5,	//影象大小錯誤,影象解析度為0,或超出範圍
JPEG_OTHER_ERROR=	6	//其它未知錯誤,一般是地址未16位元組對齊
} JPEG_ERROR;
//JPEG 檔案資訊
typedef struct
{
u16 Width;		//影象寬度
u16 Height;		//影象高度
u32 FileSize;	//JPEG圖片大小
u32 DataSize;	//影象解碼後資料大小
JPEG_TYPE Type;	//影象型別定義
} JPEG_INFO;
//影象壓縮質量等級
typedef enum
{
JPEG_QUALITY_LEVEL_1 = 0, 	//高質量
JPEG_QUALITY_LEVEL_2 = 1,
JPEG_QUALITY_LEVEL_3 = 2,
JPEG_QUALITY_LEVEL_4 = 3	//低質量   
}JPEG_QUALITY_TYPE;
//相關函式宣告
void JPEG_Init(void);	//JPEG解碼初始化
void JPEG_ReadClearStatus(u8* Status, u8* IrqStatus);//讀取並清除JPEG狀態
u32 JPEG_GetYUVSize(JPEG_TYPE jpegType,u16 width, u16 height);	//獲取解碼後資料大小
JPEG_ERROR JPEG_DecodeOneFrame(u32 JpgAddr, u32 ImageAddr, u32 jpegSize, JPEG_INFO *JpegInfo);//開始解碼一幀JPEG
JPEG_ERROR JPEG_EncodeOneFrame(u32 JpgAddr, u32 ImageAddr, JPEG_QUALITY_TYPE jpegQuality, JPEG_INFO *JpegInfo);	//開始編碼一張JPEG
#endif // __JPEGCODEC_H__

 

/*************************************************************************************************************
* 檔名:	jpeg_tables.h
* 功能:		S3C6410 jpeg編碼表
* 作者:		[email protected]
* 建立時間:	2013年01月14日
* 最後修改時間:2013年01月14日
* 詳細:		直接使用的官方的程式碼
*************************************************************************************************************/
#ifndef __JPEG_TABLES_H__
#define __JPEG_TABLES_H__
const unsigned char QTBL_Luminance[4][64]=
{
// level 1 - high quality
{
8, 6, 6, 8, 12, 14, 16, 17,
6, 6, 6, 8, 10, 13, 12, 15,
6, 6, 7, 8, 13, 14, 18, 24,
8, 8, 8, 14, 13, 19, 24, 35,
12, 10, 13, 13, 20, 26, 34, 39,
14, 13, 14, 19, 26, 34, 39, 39,
16, 12, 18, 24, 34, 39, 39, 39,
17, 15, 24, 35, 39, 39, 39, 39
},    
// level 2
{
12, 8, 8, 12, 17, 21, 24, 23, 
8, 9, 9, 11, 15, 19, 18, 23, 
8, 9, 10, 12, 19, 20, 27, 36, 
12, 11, 12, 21, 20, 28, 36, 53, 
17, 15, 19, 20, 30, 39, 51, 59, 
21, 19, 20, 28, 39, 51, 59, 59, 
24, 18, 27, 36, 51, 59, 59, 59, 
23, 23, 36, 53, 59, 59, 59, 59 
},
// level 3
{
16, 11, 11, 16, 23, 27, 31, 30, 
11, 12, 12, 15, 20, 23, 23, 30, 
11, 12, 13, 16, 23, 26, 35, 47, 
16, 15, 16, 23, 26, 37, 47, 64, 
23, 20, 23, 26, 39, 51, 64, 64, 
27, 23, 26, 37, 51, 64, 64, 64, 
31, 23, 35, 47, 64, 64, 64, 64, 
30, 30, 47, 64, 64, 64, 64, 64 
},
// level 4 - low quality
{
20, 16, 25, 39, 50, 46, 62, 68, 
16, 18, 23, 38, 38, 53, 65, 68, 
25, 23, 31, 38, 53, 65, 68, 68, 
39, 38, 38, 53, 65, 68, 68, 68, 
50, 38, 53, 65, 68, 68, 68, 68, 
46, 53, 65, 68, 68, 68, 68, 68, 
62, 65, 68, 68, 68, 68, 68, 68, 
68, 68, 68, 68, 68, 68, 68, 68 
}
};
const unsigned char QTBL_Chrominance[4][64]=
{
// level 1 - high quality
{
9, 8, 9, 11, 14, 17, 19, 24, 
8, 10, 9, 11, 14, 13, 17, 22, 
9, 9, 13, 14, 13, 15, 23, 26, 
11, 11, 14, 14, 15, 20, 26, 33, 
14, 14, 13, 15, 20, 24, 33, 39, 
17, 13, 15, 20, 24, 32, 39, 39, 
19, 17, 23, 26, 33, 39, 39, 39, 
24, 22, 26, 33, 39, 39, 39, 39
},
// level 2
{
13, 11, 13, 16, 20, 20, 29, 37, 
11, 14, 14, 14, 16, 20, 26, 32, 
13, 14, 15, 17, 20, 23, 35, 40, 
16, 14, 17, 21, 23, 30, 40, 50, 
20, 16, 20, 23, 30, 37, 50, 59, 
20, 20, 23, 30, 37, 48, 59, 59, 
29, 26, 35, 40, 50, 59, 59, 59, 
37, 32, 40, 50, 59, 59, 59, 59 
},
// level 3
{
17, 15, 17, 21, 20, 26, 38, 48, 
15, 19, 18, 17, 20, 26, 35, 43, 
17, 18, 20, 22, 26, 30, 46, 53, 
21, 17, 22, 28, 30, 39, 53, 64, 
20, 20, 26, 30, 39, 48, 64, 64, 
26, 26, 30, 39, 48, 63, 64, 64, 
38, 35, 46, 53, 64, 64, 64, 64, 
48, 43, 53, 64, 64, 64, 64, 64 
},
// level 4 - low quality
{
21, 25, 32, 38, 54, 68, 68, 68, 
25, 28, 24, 38, 54, 68, 68, 68, 
32, 24, 32, 43, 66, 68, 68, 68, 
38, 38, 43, 53, 68, 68, 68, 68, 
54, 54, 66, 68, 68, 68, 68, 68, 
68, 68, 68, 68, 68, 68, 68, 68, 
68, 68, 68, 68, 68, 68, 68, 68, 
68, 68, 68, 68, 68, 68, 68, 68 
}
};
const unsigned char QTBL0[64]=
{
#if 1
0x10, 0x0B, 0x0A, 0x10, 0x18, 0x28, 0x33, 0x3D,
0x0C, 0x0C, 0x0E, 0x13, 0x1A, 0x3A, 0x3C, 0x37,
0x0E, 0x0D, 0x10, 0x18, 0x28, 0x39, 0x45, 0x38,
0x0E, 0x11, 0x16, 0x1D, 0x33, 0x57, 0x50, 0x3E,
0x12, 0x16, 0x25, 0x38, 0x44, 0x6D, 0x67, 0x4D,
0x18, 0x23, 0x37, 0x40, 0x51, 0x68, 0x71, 0x5C,
0x31, 0x40, 0x4E, 0x57, 0x67, 0x79, 0x78, 0x65,
0x48, 0x5C, 0x5F, 0x62, 0x70, 0x64, 0x67, 0x63
#else
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
#endif
};
//Added Quantization Table
const unsigned char std_chrominance_quant_tbl_plus[64]=
{    
0x11, 0x12, 0x18, 0x2F, 0x63, 0x63, 0x63, 0x63,
0x12, 0x15, 0x1A, 0x42, 0x63, 0x63, 0x63, 0x63,
0x18, 0x1A, 0x38, 0x63, 0x63, 0x63, 0x63, 0x63,
0x2F, 0x42, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63
};
//Quantization Table0
unsigned char std_luminance_quant_tbl[64] =
{
1,   1,   2,   1,   1,   2,   2,   2,
2,   3,   2,   2,   3,   3,   6,   4,
3,   3,   3,   3,   7,   5,   8,   4,
6,   8,   8,  10,   9,   8,   7,  11,
8,  10,  14,  13,  11,  10,  10,  12,
10,   8,   8,  11,  16,  12,  12,  13,
15,  15,  15,  15,   9,  11,  16,  17,
15,  14,  17,  13,  14,  14,  14,   1
};
//Quantization Table1
unsigned char std_chrominance_quant_tbl[64] =
{
4,   4,   4,   5,   4,   5,   9,   5,
5,   9,  15,  10,   8,  10,  15,  26,
19,   9,   9,  19,  26,  26,  26,  26,
13,  26,  26,  26,  26,  26,  26,  26,
26,  26,  26,  26,  26,  26,  26,  26,
26,  26,  26,  26,  26,  26,  26,  26,
26,  26,  26,  26,  26,  26,  26,  26,
26,  26,  26,  26,  26,  26,  26,  26
};
//Huffman Table
unsigned char HDCTBL0[16]  = {0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0};
unsigned char HDCTBLG0[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb};
unsigned char HACTBL0[16]= {0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d};
const unsigned char HACTBLG0[162]=
{
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
};
//Huffman Table0
unsigned char len_dc_luminance[16] ={ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
unsigned char val_dc_luminance[12] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
unsigned char len_ac_luminance[16] ={ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
unsigned char val_ac_luminance[162] =
{
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
};
//Huffman Table1
unsigned char len_dc_chrominance[16] ={ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
unsigned char val_dc_chrominance[12] ={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
unsigned char len_ac_chrominance[16] ={ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
unsigned char val_ac_chrominance[162] =
{
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
0x13, 0x22, 0x32, 0x81, 0x81, 0x08, 0x14, 0x42,
0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52,
0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24,
0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57,
0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,
0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77,
0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86,
0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95,
0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9
};
#endif	//__JPEG_TABLES_H__

 

 

/*************************************************************************************************************
* 檔名:	sys_types.h
* 功能:		S3C6410相關資料定義
* 作者:		[email protected]
* 建立時間:	2012年3月4日15:55
* 最後修改時間:2012年3月4日
* 詳細:		相關資料結構定義
*************************************************************************************************************/
#ifndef _SYS_TYPES_H_
#define _SYS_TYPES_H_
typedef signed long long  	s64;
typedef signed long  		s32;
typedef signed short		s16;
typedef signed char  		s8;
typedef signed long  long const sc64;  /* Read Only */
typedef signed long  const 		sc32;  /* Read Only */
typedef signed short const 		sc16;  /* Read Only */
typedef signed char  const 		sc8;   /* Read Only */
typedef volatile signed long long 	vs64;
typedef volatile signed long  		vs32;
typedef volatile signed short 		vs16;
typedef volatile signed char  		vs8;
typedef volatile signed long long  const 	vsc64;  /* Read Only */
typedef volatile signed long  const 		vsc32;  /* Read Only */
typedef volatile signed short const 		vsc16;  /* Read Only*/
typedef volatile signed char  const 		vsc8;   /* Read Only */
typedef unsigned long long 		u64;
typedef unsigned long  			u32;
typedef unsigned short 			u16;
typedef unsigned char  			u8;
typedef unsigned long long const 	uc64;  /* Read Only */
typedef unsigned long  const 		uc32;  /* Read Only */
typedef unsigned short const 		uc16;  /* Read Only */
typedef unsigned char  const 		uc8;   /* Read Only */
typedef volatile unsigned long long 	vu64;
typedef volatile unsigned long  		vu32;
typedef volatile unsigned short 		vu16;
typedef volatile unsigned char  		vu8;
typedef volatile unsigned long long const 	vuc64;  /* Read Only */ 
typedef volatile unsigned long  const 		vuc32;  /* Read Only */
typedef volatile unsigned short const 		vuc16;  /* Read Only*/
typedef volatile unsigned char  const 		vuc8;   /* Read Only */
typedef enum {FALSE= 0, TRUE = !FALSE} bool; 	
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#define U8_MAX     ((u8)255)
#define S8_MAX     ((s8)127)
#define S8_MIN     ((s8)-128)
#define U16_MAX    ((u16)65535u)
#define S16_MAX    ((s16)32767)
#define S16_MIN    ((s16)-32768)
#define U32_MAX    ((u32)4294967295uL)
#define S32_MAX    ((s32)2147483647)
#define S32_MIN    ((s32)-2147483648)
#endif

 

 

 

主函式的部分程式碼

/*************************************************************************************************************************
*函式        	:	static PIC_ERROR OpenPictureFile(const char *FileName,u8 *buff,u32 FileMaxSize)
*功能        	:	開啟一張,並將資料讀取到記憶體
*引數        	:	FileName:檔名,路徑指標;buff:讀取緩衝區;FileMaxSize:檔案最大限制
*返回        	:	PIC_ERROR
*依賴     	: 	FATFS檔案系統支援
*作者        	:	[email protected]
*時間     	:	20121207
*最後修改時間	:	20121209
*說明     	:	呼叫FATFS開啟圖片檔案
*************************************************************************************************************************/
int OpenPictureFile(const char *FileName,u8 *buff,u32 FileMaxSize)
{
FIL file;
UINT cnt;
int status;
int error = 0;
status = f_open(&file,FileName,FA_READ);				//只讀方式開啟檔案
if(status != FR_OK)										//開啟檔案錯誤
{
uart_printf("open \"%s\" error!\r\n",FileName);
error = 1;
}
else
{
//獲取檔案大小
uart_printf("file size : %dB\r\n",file.fsize);		//輸出檔案大小
if(file.fsize > FileMaxSize)
{
uart_printf("file size > %d\r\n",FileMaxSize);
error = 2;
}
else
{
status = f_read(&file,buff,file.fsize,&cnt);	//讀取檔案
uart_printf("Read File Num=%d\r\n",cnt);
if(cnt == file.fsize)							//判斷檔案是否讀取完畢
{
uart_printf("read file end!\r\n");
error =  0;
}
else
{
uart_printf("read file error!\r\n");
error = 3;
}
}
}
f_close(&file);
return error;
}
void YUV422ToRGB565(u8 *YUVBuff,u16 width,u16 height)
{
u16 x,y;
u32 RGBdata;
u32 cnt = 0;
u8 Y,U = 0,V = 0;
int R,G,B;
for(y = 0;y < height;y   )
{
for(x = 0;x < width;x    )
{
Y = YUVBuff[cnt << 1];
if((cnt % 2) == 0)
{
U = YUVBuff[(cnt << 1)   1];
V = YUVBuff[(cnt << 1)   3];
} 
R = Y   (1.370705 * (V - 128));
G = Y - (0.698001 * (V - 128)) - (0.337633 * (U-128));
B = Y   (1.732446 * (U - 128));
R = (R > 255) ? 255 : ((R < 0) ? 0 : R);
G = (G > 255) ? 255 : ((G < 0) ? 0 : G);
B = (B > 255) ? 255 : ((B < 0) ? 0 : B);
//RGBdata = (u32)(R << 16) | (G << 8) | B;
R >>= 3;
G >>= 2;
B >>= 3;
RGBdata = (R << 11)   (G << 5)   B;
LCD_DrawPoint(x,y,(u16)RGBdata);
//LCD_DrawPoint(x,y,RGB888toRGB565(RGBdata));
cnt   ;
}
}
}
u8 buff[10*1024*1024];
u8 image[10*1024*1024];
//主函式
int main(void)
{		
OS_CPU_SR  cpu_sr;
int result;
JPEG_INFO JpegInfo;
u32 p;
u32 i;
UART0_Init(DISABLE,115200);					//初始化串列埠,失能中斷接收,波特率115200
LCD_Init();									//初始化LCD
LED_Init();									//初始化LED
RunTimeInit();
JPEG_Init();
result = Explorer_Init();					//初始化資源管理器
if(result == 0)				
{
lcd_printf("Disk Init OK!\n");
}
else
{
lcd_printf("Disk Init Error(%d)!\n",result);
}
p = (u32)buff;
if((u32)buff % 16)
{
p = (p / 16   1) * 16;
}
OpenPictureFile("0:/system/ui/ico/設定.jpg",(u8 *)p,10*1024*1024);
result = JPEG_DecodeOneFrame(p,(u32)image,31654, &JpegInfo);
uart_printf("decode jpeg file %d\r\n",result);
if(result == 0)
{
YUV422ToRGB565(image,JpegInfo.Width,JpegInfo.Height);
}

 

 

附:任意檔案轉C陣列工具:http://download.csdn.net/detail/cp1300/4588229