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

📄 jpeg.c

📁 s3c6400 ADS下官方测试程序
💻 C
字号:
/*----------------------------------------------------------------------
 *
 * Filename: jpeg.c
 *
 * Contents:
 *
 * History:
 *
 * Contributors:
 *
 * Copyright (c) 2003 SAMSUNG Electronics.
 *
 *----------------------------------------------------------------------
 */

#include <string.h>
#include <stdio.h>
#include "system.h"
#include "jpeg.h"
#include "jpeg_tables.h"

#include "option.h"
#include "library.h"
#include "sfr6400.h"

//#define DBG_JPEG

/*
#ifdef DBG_JPEG
#define printf(x) Dbg x
#else
#define printf(x)
#endif
*/

/*
#if 0
#define Outp32(a, d) (Dbg("Outp1w(\'h%08x, \'h%08x);\n", a, d), Outp32(a, d))
#define jpgInp32(a, d)  (Dbg("Inp1w (\'h%08x);\n", a, d), jpgInp32(a, d))
#else
#define Outp32 Outp32
#define jpgInp32 jpgInp32
#endif
*/

enum JPEG_REG
{
	JPGMOD        = (JPEG_BASE+0x000),
	JPGSTS        = (JPEG_BASE+0x004),
	JPGQHNO       = (JPEG_BASE+0x008),
	JPGDRI        = (JPEG_BASE+0x00C),
	JPGY          = (JPEG_BASE+0x010),
	JPGX          = (JPEG_BASE+0x014),
	JPGCNT        = (JPEG_BASE+0x018),
	JPGIRQEN      = (JPEG_BASE+0x01C),
	JPGIRQ        = (JPEG_BASE+0x020), // Int Pending Register
	JQTBL0        = (JPEG_BASE+0x400),
	JQTBL1        = (JPEG_BASE+0x500),
	JQTBL2        = (JPEG_BASE+0x600),
	JQTBL3        = (JPEG_BASE+0x700),
	JHDCTBL0      = (JPEG_BASE+0x800),
	JHDCTBLG0     = (JPEG_BASE+0x840),
	JHACTBL0      = (JPEG_BASE+0x880),
	JHACTBLG0     = (JPEG_BASE+0x8c0),
	JHDCTBL1      = (JPEG_BASE+0xc00),
	JHDCTBLG1     = (JPEG_BASE+0xc40),
	JHACTBL1      = (JPEG_BASE+0xc80),
	JHACTBLG1     = (JPEG_BASE+0xcc0),
	JIMGADDR0     = (JPEG_BASE+0x1000),
	JIMGADDR1     = (JPEG_BASE+0x1004),
	JHUFADDR0     = (JPEG_BASE+0x1008),
	JHUFADDR1     = (JPEG_BASE+0x100c),
	JSTART        = (JPEG_BASE+0x1010),
	JRSTART       = (JPEG_BASE+0x1014),
	RESET_CON     = (JPEG_BASE+0x1018),
	JPG_CON       = (JPEG_BASE+0x101c),
	JCOEF1        = (JPEG_BASE+0x1020),
	JCOEF2        = (JPEG_BASE+0x1024),
	JCOEF3        = (JPEG_BASE+0x1028),
	JMISC         = (JPEG_BASE+0x102c),
	JFRAME_INTV   = (JPEG_BASE+0x1030),
	RESUME        = (JPEG_BASE+0x1038),
	IMGADDR_END   = (JPEG_BASE+0x103c),	
	HUFADDR_END   = (JPEG_BASE+0x1040),	
	HUFADDR_MNT   = (JPEG_BASE+0x1044)
};

// Coefficients for RGB to YUV
#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_MOTION_DEC       (0x1<<0)
#define DISABLE_MOTION_DEC      (0x0<<0)

#define ENABLE_HW_DEC           (0x1<<2)
#define DISABLE_HW_DEC          (0x0<<2)

#define INCREMENTAL_DEC         (0x1<<3)
#define NORMAL_DEC              (0x0<<3)

JPEG oJpg;

void JPEG_Init(void)
{
	oJpg.m_bIsHeaderParsed = false;
}

void JPEG_InitRegsForDecoding1(
	u32 uSrcAddr, u32 uDstAddr,
	bool bIsHeaderOnly, bool bIncremental, bool bIsMotion
	)
{
	u32 uJpgConVal = 0;

	Outp32(JPGMOD, 0x8); // Process mode: Decoding
	Outp32(JHUFADDR0, uSrcAddr); // Address of compresed input data
	Outp32(JIMGADDR0, uDstAddr); // Address of decompresed image
	Outp32(JHUFADDR1, uSrcAddr); // Address of compresed input data
	Outp32(JIMGADDR1, uDstAddr); // Address of decompresed image
	Outp32(JPGIRQEN, 0xf<<3); // JPGIRQEN[6:3]=For several error conditions @2006.6.8

#if 0
	Outp32(JPG_CON, (bIsMotion ? ENABLE_MOTION_DEC : DISABLE_MOTION_DEC));
	u32 uJpgConVal;
	jpgInp32(JPG_CON, uJpgConVal);
	if (bIsHeaderOnly)
		uJpgConVal &= ~(1<<2);
	else
		uJpgConVal |= (1<<2);
	Outp32(JPG_CON, uJpgConVal);
#else
	uJpgConVal = (bIsMotion ? ENABLE_MOTION_DEC : DISABLE_MOTION_DEC);
	uJpgConVal |= (bIsHeaderOnly ? DISABLE_HW_DEC : ENABLE_HW_DEC);
	Outp32(JPG_CON, uJpgConVal);
	
#endif
	if (bIncremental)
		Outp32(JMISC, (1<<3));
	else
		Outp32(JMISC, (0<<3));
		
}

void JPEG_InitRegsForDecoding(
	u32 uSrcAddr, u32 uDstAddr,
	JPEG_DEC_MODE eMode, bool bIncremental, bool bIsMotion
	)
{

	u32 uJpgConVal = 0;	
	u32 uMisc = 0;

	if (eMode == HEADER || eMode == HEADER_N_BODY)
	{
		Outp32(JPGMOD, 0x8); // Process mode: Decoding		
		Outp32(JHUFADDR0, uSrcAddr); // Address of compresed input data
		Outp32(JHUFADDR1, uSrcAddr); // Address of compresed input data
		Outp32(JPGIRQEN, 0xf<<3); // JPGIRQEN[6:3]=For several error conditions @2006.6.8	
		//Outp32(JPGIRQEN, 0xf); // JPGIRQEN[6:3]=For several error conditions @2006.6.8	

		if (eMode == HEADER_N_BODY)
		{
			Outp32(JIMGADDR0, uDstAddr); // Address of decompresed image
			Outp32(JIMGADDR1, uDstAddr); // Address of decompresed image
		}


		uJpgConVal = (eMode == HEADER) ? DISABLE_HW_DEC : ENABLE_HW_DEC;
	}
	else // eMode == BODY
	{
		Outp32(JIMGADDR0, uDstAddr); // Address of decompresed image
		Outp32(JIMGADDR1, uDstAddr); // Address of decompresed image
	}

	if (eMode == BODY || eMode == HEADER_N_BODY)
	{
		uJpgConVal |= (bIsMotion == true) ? ENABLE_MOTION_DEC : DISABLE_MOTION_DEC;
		uMisc = (bIncremental == true) ? INCREMENTAL_DEC : NORMAL_DEC;
	}

	Outp32(JPG_CON, uJpgConVal);
	Outp32(JMISC, uMisc);
}

void JPEG_InitRegsForEncoding(
	u32 uRawHsz, u32 uRawVsz, u32 uRawAddr, CSPACE eRawType,
	u32 uJpgAddr, JPEG_TYPE uJpgType, bool bIsOnTheFly, bool bIsMotion)
{
	int i;

	Assert(eRawType == YCBYCR || eRawType == RGB16);

	Outp32(JPGMOD, (uJpgType == JPEG_422)? (0x1<<0) : (0x2<<0)); // Encoded to yuv422 or yuv420
	Outp32(JPGDRI, 2); // MCU inserts RST marker
	Outp32(JPGQHNO, 0x0);
	Outp32(JPGX, uRawHsz);
	Outp32(JPGY, uRawVsz);
	Outp32(JIMGADDR0, uRawAddr); // Address of input image
	Outp32(JHUFADDR0, uJpgAddr); // Address of JPEG stream
	Outp32(JIMGADDR1, uRawAddr); // Address of input image
	Outp32(JHUFADDR1, uJpgAddr); // next address of motion JPEG stream
	Outp32(JCOEF1, COEF1_RGB_2_YUV); // Coefficient value 1 for RGB to YCbCr
	Outp32(JCOEF2, COEF2_RGB_2_YUV); // Coefficient value 2 for RGB to YCbCr
	Outp32(JCOEF3, COEF3_RGB_2_YUV); // Coefficient value 3 for RGB to YCbCr

	Outp32(JMISC,
		(bIsOnTheFly ? 0 : (eRawType == YCBYCR ? 1 : 2))<<5 |
		(bIsOnTheFly ? 1 : 0)<<2
		);

	Outp32(JPG_CON, 	(bIsMotion ? ENABLE_MOTION_ENC : DISABLE_MOTION_ENC));

//	Outp32(JPGIRQEN, 0x10);
//	Outp32(JPGIRQEN, 1<<4); // Deleted @2006.6.8

	// Quantiazation and Huffman Table setting
	//-----------------------------------------

	for (i=0; i<64; i++)
		Outp32((JQTBL0+i*4), (u32)QTBL0[i]);

	for (i=0; i<64; i++)
		Outp32((JQTBL1+i*4), (u32)std_chrominance_quant_tbl_plus[i]);

	for (i=0; i<16; i++)
		Outp32((JHDCTBL0+i*4), (u32)HDCTBL0[i]);

	for (i=0; i<12; i++)
		Outp32((JHDCTBLG0+i*4), (u32)HDCTBLG0[i]);

	for (i=0; i<16; i++)
		Outp32((JHACTBL0+i*4), (u32)HACTBL0[i]);

	for (i=0; i<162; i++)
		Outp32((JHACTBLG0+i*4), (u32)HACTBLG0[i]);
}

void JPEG_StartEncodingOneFrame(
	u16 usHSz, u16 usVSz, u32 uSrcAddr, CSPACE eRawType,
	u32 uDestAddr, JPEG_TYPE eJpgType)
{
	Assert(eRawType == YCBYCR || eRawType == RGB16);

	JPEG_Reset();
	JPEG_InitRegsForEncoding(usHSz, usVSz, uSrcAddr, eRawType, uDestAddr, eJpgType, false, false);

	Outp32(JSTART, 0); // start.
	
}

// On-The-Fly Encoding
// IN On-The-Fly mode, Support only JPEG_422 Data Format
void JPEG_StartEncodingOtf(u16 usHSz, u16 usVSz, CSPACE eRawType, u32 uDstAddr)
{
	Assert(eRawType == YCBYCR || eRawType == RGB16);

	JPEG_Reset();
	JPEG_InitRegsForEncoding(usHSz, usVSz, 0, eRawType, uDstAddr, JPEG_422, true, false);
//	DisableMotionEncoding();

	Outp32(JSTART, 0); // start.
}

//Motion JPEG Encoding
void JPEG_StartEncodingMotionJPEG(
	u16 usHSz, u16 usVSz, u32 uSrcAddr, CSPACE eRawType, 
	u32 uDestAddr, JPEG_TYPE eJpgType)
{
	Assert(eRawType == YCBYCR || eRawType == RGB16);

	JPEG_Reset();
	JPEG_InitRegsForEncoding(usHSz, usVSz, uSrcAddr, eRawType, uDestAddr, eJpgType, false, true);
//	DisableMotionEncoding();

	Outp32(JSTART, 0); // start.

}

void JPEG_InitIpForMotionEncoding(
	u16 uRawHsz, u16 uRawVsz, u32 uRawAddr, CSPACE eRawType,
	u32 uJpgAddr, JPEG_TYPE eJpgType, u32 uMJpegMaxSize)
{
	Assert(eRawType == YCBYCR || eRawType == RGB16);

	printf(" Enc: x=%d, y=%d, yuv=0x%08x~0x%08x, YUV%d\n",
		uRawHsz, uRawVsz, uRawAddr, uRawAddr+(uRawHsz*uRawVsz*2), (eJpgType == JPEG_422) ? 422: 420);

	JPEG_InitRegsForEncoding(uRawHsz, uRawVsz, uRawAddr, eRawType, uJpgAddr, eJpgType, false, true); // config Registers.
	JPEG_SetNextFrameStartAddr(uJpgAddr+uMJpegMaxSize);

	Outp32(JPGCNT, 0);

	Outp32(JPG_CON, (1<<3)); // Start Motion Jpeg Encoding

	//+daedoo	
	Outp32(JSTART, 0); // start.
}

void JPEG_StartParsingHeader(u32 uJpgAddr)
{
	Assert(uJpgAddr%16 == 0);	
	printf("Dec: jpeg=%08x\n", uJpgAddr);

	JPEG_Reset();

	JPEG_InitRegsForDecoding(uJpgAddr, 0, HEADER, false, false);

	Outp32(JSTART, 1);
	
	oJpg.m_bIsHeaderParsed = true;
}

void JPEG_StartDecodingBody(u32 uRawAddr, bool bIsIncremental)
{
	Assert(oJpg.m_bIsHeaderParsed == true);

	JPEG_InitRegsForDecoding(0, uRawAddr, BODY, bIsIncremental, false);
	Outp32(JRSTART, 1);
}

void JPEG_StartDecodingOneFrame(u32 uJpgAddr, u32 uRawAddr, bool bIsIncremental)
{
	
	Assert(uJpgAddr%16 == 0);
	
	printf(" Dec: jpeg=%08x, raw=%08x\n", uJpgAddr, uRawAddr);

	JPEG_Reset();
	JPEG_InitRegsForDecoding(uJpgAddr, uRawAddr, HEADER_N_BODY, bIsIncremental, false);
	
	Outp32(JSTART, 1);
}

void JPEG_StartDecodingMotion(u32 uJpgAddr, u32 uRawAddr, u32 uMJpegMaxSize)
{
	printf(" Dec: jpeg=%08x, raw=%08x\n", uJpgAddr, uRawAddr);

	JPEG_Reset();
//  Delay(1000);

//==============================================================================================//
// For compling below func. is changed to	InitRegsForDecoding(uJpgAddr, uRawAddr, HEADER_N_BODY)
// so, below code shoule be modified when motion decoding func. is written 
#if 0
	InitRegsForDecoding(uJpgAddr, uRawAddr);
#else
	JPEG_InitRegsForDecoding(uJpgAddr, uRawAddr, HEADER_N_BODY, false, false);
#endif
//==============================================================================================//

	JPEG_SetNextFrameStartAddr(uJpgAddr + uMJpegMaxSize);

	Outp32(JPG_CON, (1<<0)); // Enable auto decoding
//  Outp32(JFRAME_INTV, 0x800000);
	Outp32(JFRAME_INTV, 0x300000);

	Outp32(JSTART, 1);
}


// Encoding Results
void JPEG_GetEncodedStreamLen(u32* uSize)
{
	//jpgInp32(JPGCNT, *uSize);
	*uSize = Inp32(JPGCNT);
}

void JPEG_GetDecodedWidthAndHeight(u32* hsz, u32* vsz)
{
	//jpgInp32(JPGX, *hsz);
	//jpgInp32(JPGY, *vsz);
	*hsz = Inp32(JPGX);
	*vsz = Inp32(JPGY);
}

// Set Next frame start addr of Jpeg data for both encoding and decoding
void JPEG_SetNextFrameStartAddr(u32 addr)
{
	Outp32(JHUFADDR1, addr);
}

// It is necessary for decoding
void JPEG_Reset(void)
{
	Outp32(RESET_CON, 0); //0: enable, 1: disable(default value)
}

// set JPG_CON[3] to 0
void JPEG_DisableMotionEncoding(void)
{
	u32 temp;

	temp = Inp32(JPG_CON);
	Outp32(JPG_CON, temp&~(1<<3));
}

// set JPG_CON[0] to 0
void JPEG_DisableMotionDecoding(void)
{
	u32 temp;

	temp = Inp32(JPG_CON);
	Outp32(JPG_CON, temp&~(1<<0));
}

void JPEG_GetIntStatus(u32* uIntStatus)
{
	//u32 codecMode;

//	jpgInp32(JPGSTS, codecMode); // It must be read.
	//jpgInp32(JPGIRQ, *uIntStatus); // It clears the pending register.
	*uIntStatus = Inp32(JPGIRQ); // It clears the pending register.
}

void JPEG_CheckDone(u32* uResult)
{
	u32 uIntStatus;

//	GetIntStatus(uIntStatus);
	 uIntStatus = Inp32(JPGIRQ); // It clears the pending register.

	*uResult = uIntStatus & (1<<6);
}

void JPEG_CheckSyntaxError(u32* uResult)
{
	u32 uIntStatus;

//	GetIntStatus(uIntStatus);
	uIntStatus = Inp32(JPGIRQ); // It clears the pending register.

	*uResult = uIntStatus & (1<<4);
}

void JPEG_CheckReadHeader(u32* uResult)
{
	u32 uIntStatus;

//	GetIntStatus(uIntStatus);
	//jpgInp32(JPGIRQ, uIntStatus); // It clears the pending register.
	uIntStatus = Inp32(JPGIRQ); // It clears the pending register.

	*uResult = uIntStatus & (1<<3);
}

void JPEG_ReadAndClearStatus(JPEG_STATUS* eStatus)
{
	u32 uStatus;//, uJpgStsReg;

	//uJpgStsReg = Inp32(JPGSTS); // Why ?
	uStatus = Inp32(JPGIRQ);
	//printf(("JPGIRQ = %02x\n", uStatus));
	//Dbg("JPGIRQ = %02x\n", uStatus);
	
	uStatus &= ((1<<6)|(1<<4)|(1<<3));
	if (uStatus == 0x08) 
		*eStatus = OK_HD_PARSING;
	else if (uStatus == 0x00) 
		*eStatus = ERR_HD_PARSING;
	else if (uStatus == 0x40)
		*eStatus = OK_ENC_OR_DEC;
	else if (uStatus == 0x10) 
		*eStatus = ERR_ENC_OR_DEC;
	else
		Assert(0);
 }

void JPEG_GetJpegType(JPEG_TYPE* eMode)
{	
	u32 uSampleMode;
	uSampleMode = Inp32(JPGMOD);

	*eMode = 
		((uSampleMode&0x7) == 0) ? JPEG_444 :
		((uSampleMode&0x7) == 1) ? JPEG_422 :
		((uSampleMode&0x7) == 2) ? JPEG_420 :
		((uSampleMode&0x7) == 3) ? JPEG_400 :
		((uSampleMode&0x7) == 6) ? JPEG_411 : (JPEG_TYPE)0xffff;
	Assert(*eMode != 0xffff);
}

void JPEG_GetJpegType1(char* pType)
{
	JPEG_TYPE eType;
	JPEG_GetJpegType(&eType);
	
	if (eType == JPEG_444)
		strcpy(pType, "JPEG 444");
	else if (eType == JPEG_422)
		strcpy(pType, "JPEG 422");
	else if (eType == JPEG_420)
		strcpy(pType, "JPEG 420");
	else if (eType == JPEG_411)
		strcpy(pType, "JPEG 411");
	else if (eType == JPEG_400)
		strcpy(pType, "JPEG 400 (Gray)");
	else
		Assert(0);
}

void JPEG_Wait_Done(void)
{
	u32 temp;

	do{
		temp = Inp32(JPGSTS);
		//Disp("jpgsts = 0x%x\n",temp);
	}while(temp);
	
}

⌨️ 快捷键说明

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