📄 jpeg.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 + -