MC3302_SDK_V1.1.9_202507281.../bsp/ramboot/common/jpegd_sw.c
2025-11-11 12:08:31 +08:00

1127 lines
24 KiB
C
Executable File

#include <common.h>
typedef unsigned int UINT32;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
#define MAKEWORD(a, b) ((UINT16)((unsigned char)(a)) | ((UINT16)((unsigned char)(b)) << 8))
#define FUNC_OK 0
#define FUNC_MEMORY_ERROR 1
#define FUNC_FILE_ERROR 2
#define FUNC_FORMAT_ERROR 3
#define M_SOF0 0xc0
#define M_DHT 0xc4
#define M_EOI 0xd9
#define M_SOS 0xda
#define M_DQT 0xdb
#define M_DRI 0xdd
#define M_APP0 0xe0
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */
const int Zig_Zag[8][8]=
{
{0,1,5,6,14,15,27,28},
{2,4,7,13,16,26,29,42},
{3,8,12,17,25,30,41,43},
{9,11,18,24,31,40,44,53},
{10,19,23,32,39,45,52,54},
{20,22,33,38,46,51,55,60},
{21,34,37,47,50,56,59,61},
{35,36,48,49,57,58,62,63}
};
const int unzig_zag[80] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63,
63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
63, 63, 63, 63, 63, 63, 63, 63
};
#define MAX2(x,y) ( (x)>(y) ? (x):(y) )
#define OK 0
#define ERROR 1
int InitTag(void);
void InitTable(void);
int Decode(void);
int DecodeMCUBlock(void);
int HufBlock(UINT8 dchufindex,UINT8 achufindex);
int DecodeElement(void);
void IQtIZzMCUComponent(int flag);
void IQtIZzBlock(int *s,int *d,int flag);
void GetYUV(int flag);
void StoreBuffer(void);
UINT8 ReadByte(void);
void Initialize_Fast_IDCT(void);
void Fast_IDCT(int * block);
void idctrow(int * blk);
void idctcol(int * blk);
UINT32 jpeg_w = 0,jpeg_h = 0;
UINT32 jpeg_p;
int SampRate_Y_H,SampRate_Y_V,SampRate_U_H,SampRate_U_V,SampRate_V_H,SampRate_V_V;
int H_YtoU,V_YtoU,H_YtoV,V_YtoV,Y_in_MCU,U_in_MCU,V_in_MCU;
UINT8 *lpJpegBuf,*lp,*lpPtr;
int qt_table[3][64];
int comp_num;
UINT8 comp_index[3];
UINT8 YDcIndex,YAcIndex,UVDcIndex,UVAcIndex,HufTabIndex;
int *YQtTable,*UQtTable,*VQtTable;
UINT8 MyAnd[9]={0,1,3,7,0x0f,0x1f,0x3f,0x7f,0xff};
int code_pos_table[4][16];
int code_len_table[4][16];
UINT16 code_value_table[4][256];
UINT16 huf_max_value[4][16],huf_min_value[4][16];
int BitPos,CurByte,rrun,vvalue;
int MCUBuffer[640],BlockBuffer[64];
int QtZzMCUBuffer[640];
int ycoef,ucoef,vcoef,IntervalFlag,interval = 0;
int Y[256],U[256],V[256];
int sizei,sizej;
int restart;
int iclip[1024];
int value_type;
unsigned int jpeg_decode_sw(void *jpg, void *y, void *uv)
{
UINT32 funcret;
lpJpegBuf = jpg;
InitTable();
funcret = InitTag();
if(funcret != FUNC_OK) {
printf("JPEG: init tag ERROR.\n");
return ERROR;
}
lpPtr = y;
if((SampRate_Y_H == 0) || (SampRate_Y_V == 0)) {
return ERROR;
}
int mod = jpeg_w%8;
if (mod != 0) {
jpeg_p = (jpeg_w + (8-mod)) * 2;
} else {
jpeg_p = jpeg_w * 2;
}
funcret = Decode();
printf("JPEG: width=%d height=%d pitch=%d\n", jpeg_w, jpeg_h, jpeg_p);
if(funcret == FUNC_OK)
{
printf("JPEG: decode OK.\n");
return OK;
}
else
{
printf("JPEG: decode FAILED.\n");
return ERROR;
}
}
int InitTag(void)
{
UINT32 finish;
UINT8 id;
int llength,i,j,k,huftab1,huftab2,huftabindex,ccount;
UINT8 hf_table_index,qt_table_index,comnum;
UINT8 *lptemp;
int temp2;
finish = ERROR;
lp = lpJpegBuf + 2; /* SOI */
while(finish != OK)
{
id = *(lp + 1);
lp += 2;
switch(id)
{
case M_APP0:
llength = MAKEWORD(*(lp + 1),*lp);
lp += llength; /* Skip JFIF segment marker */
break;
case M_DQT:
temp2 = 2;
llength = MAKEWORD(*(lp + 1), *lp);
if (llength > 256) {
printf("M_DQT len %d is out of range!\n", llength);
return FUNC_FORMAT_ERROR;
}
qt_table_index = *(lp + 2) & 0x0f;
if (qt_table_index >= 3)
{
printf("qt_table_index err %d\n", qt_table_index);
return FUNC_FORMAT_ERROR;
}
lptemp = lp + 3;
if (llength < 80) {
for(i = 0;i < 64;i++) {
qt_table[qt_table_index][i] = (int)(*(lptemp++));
}
} else {
while(temp2 < llength) {
for(i = 0;i < 64;i++) {
//qt_table[qt_table_index][**(Zig_Zag)] = (int)(*(lptemp++));
qt_table[qt_table_index][*(unzig_zag+i)] = (int)(*(lptemp++));
}
qt_table_index = (*(lptemp++)) & 0x0f;
if(qt_table_index > 3) {
break;
}
temp2 += 65;
}
}
lp += llength;
break;
case M_SOF0:
llength = MAKEWORD(*(lp + 1),*lp);
jpeg_h = MAKEWORD(*(lp + 4),*(lp + 3));
jpeg_w = MAKEWORD(*(lp + 6),*(lp + 5));
comp_num = *(lp + 7);
if((comp_num != 1) && (comp_num != 3)) {
return FUNC_FORMAT_ERROR;
}
if(comp_num == 3) {
comp_index[0] = *(lp + 8);
SampRate_Y_H = (*(lp + 9)) >> 4;
SampRate_Y_V = (*(lp + 9)) & 0x0f;
YQtTable = (int *)qt_table[*(lp + 10)];
/* ShowMessage(IntToStr(YQtTable^)); */
comp_index[1] = *(lp + 11); /* component id */
SampRate_U_H = (*(lp + 12)) >> 4;
SampRate_U_V = (*(lp + 12)) & 0x0f;
UQtTable = (int *)qt_table[*(lp + 13)];
comp_index[2] = *(lp + 14); /* component id */
SampRate_V_H = (*(lp + 15)) >> 4;
SampRate_V_V = (*(lp + 15)) & 0x0f;
VQtTable = (int *)qt_table[*(lp + 16)];
} else {
comp_index[0] = *(lp + 8);
SampRate_Y_H = (*(lp + 9)) >> 4;
SampRate_Y_V = (*(lp + 9)) & 0x0f;
YQtTable = (int *)qt_table[*(lp + 10)];
comp_index[1] = *(lp + 8);
SampRate_U_H = 1;
SampRate_U_V = 1;
UQtTable = (int *)qt_table[*(lp + 10)];
comp_index[2] = *(lp + 8);
SampRate_V_H = 1;
SampRate_V_V = 1;
VQtTable = (int *)qt_table[*(lp + 10)];
}
if (comp_num == 1) {
if (SampRate_Y_H==SampRate_Y_V) {
value_type = 0;
SampRate_Y_H = 1;
SampRate_Y_V = 1;
SampRate_U_H = 0;
SampRate_U_V = 0;
SampRate_V_H = 0;
SampRate_V_V = 0;
}
} else if ((comp_num == 3) && (SampRate_U_H==SampRate_V_H) && (SampRate_U_V==SampRate_V_V)) {
if (SampRate_Y_H==(SampRate_U_H<<1)) {
if (SampRate_Y_V==(SampRate_U_V<<1)) {
value_type= 3;
} else if (SampRate_Y_V==SampRate_U_V) {
value_type = 4;
}
} else if (SampRate_Y_H==SampRate_U_H) {
if (SampRate_Y_V==(SampRate_U_V<<1)) {
value_type = 5;
} else if (SampRate_Y_V==SampRate_U_V) {
value_type = 6;
}
}
}
lp += llength;
break;
case M_DHT: /* Huffman Table(0xFF,0xC4) */
llength = MAKEWORD(*(lp + 1),*lp);
{
hf_table_index = *(lp + 2);
lp += 2;
while(hf_table_index != 0xff) {
huftab1 = (int)hf_table_index >> 4; /* huftab1=0,1 */
huftab2 = (int)hf_table_index & 0x0f; /* huftab2=0,1 */
huftabindex = huftab1 * 2 + huftab2;
lptemp = lp;
lptemp++;
ccount = 0;
for(i = 0;i < 16;i++) {
code_len_table[huftabindex][i] = (int)(*(lptemp++));
ccount = ccount + code_len_table[huftabindex][i];
}
ccount = ccount + 17;
j = 0;
for(i = 0;i < 16;i++) {
if(code_len_table[huftabindex][i] != 0)
{
k = 0;
while(k < code_len_table[huftabindex][i])
{
code_value_table[huftabindex][k + j] = (int)(*(lptemp++));
k++;
}
j = j + k;
}
}
i = 0;
while(code_len_table[huftabindex][i] == 0) {
i++;
}
for(j = 0;j < i;j++) {
huf_min_value[huftabindex][j] = 0;
huf_max_value[huftabindex][j] = 0;
}
huf_min_value[huftabindex][i] = 0;
huf_max_value[huftabindex][i] = code_len_table[huftabindex][i] - 1;
for(j = i + 1;j < 16;j++) {
huf_min_value[huftabindex][j] = (huf_max_value[huftabindex][j - 1] + 1) << 1;
huf_max_value[huftabindex][j] = huf_min_value[huftabindex][j] + code_len_table[huftabindex][j] - 1;
}
code_pos_table[huftabindex][0] = 0;
for(j = 1;j < 16;j++) {
code_pos_table[huftabindex][j] = code_len_table[huftabindex][j - 1] + code_pos_table[huftabindex][j - 1];
}
lp += ccount;
hf_table_index = *lp;
}
}
break;
case M_DRI:
llength = MAKEWORD(*(lp + 1),*lp);
restart = MAKEWORD(*(lp + 3),*(lp + 2));
lp += llength;
break;
case M_SOS:
llength = MAKEWORD(*(lp + 1),*lp);
comnum = *(lp + 2);
if(comnum != comp_num)
{
return FUNC_FORMAT_ERROR;
}
lptemp = lp + 3;
for(i = 0;i < comp_num;i++)
{
if(*lptemp == comp_index[0])
{ /* 1 byte :Component id */
YDcIndex = (*(lptemp + 1)) >> 4;
YAcIndex = ((*(lptemp + 1)) & 0x0f) + 2;
}
else
{
UVDcIndex = (*(lptemp + 1)) >> 4; /* U,V */
UVAcIndex = ((*(lptemp + 1)) & 0x0f) + 2;
}
lptemp += 2;
}
lp += llength;
finish = OK;
break;
case M_EOI:
return FUNC_FORMAT_ERROR;
break;
default:
if((id & 0xf0) != 0xd0)
{
llength = MAKEWORD(*(lp + 1),*lp);
lp += llength;
}
else
{
lp += 2;
}
break;
}
}
return FUNC_OK;
}
void InitTable(void)
{
int i,j;
sizei = 0;
sizej = 0;
jpeg_w = 0;
jpeg_h = 0;
rrun = 0;
vvalue = 0;
BitPos = 0;
CurByte = 0;
IntervalFlag = ERROR;
restart = 0;
for(i = 0;i < 3;i++)
{
for(j = 0;j < 64;j++)
{
qt_table[i][j] = 0;
}
}
comp_num = 0;
HufTabIndex = 0;
for(i = 0;i < 3;i++)
{
comp_index[i] = 0;
}
for(i = 0;i < 4;i++)
{
for(j = 0;j < 16;j++)
{
code_len_table[i][j] = 0;
code_pos_table[i][j] = 0;
huf_max_value[i][j] = 0;
huf_min_value[i][j] = 0;
}
}
for(i = 0;i < 4;i++)
{
for(j = 0;j < 256;j++)
{
code_value_table[i][j] = 0;
}
}
for(i = 0;i< 640;i++)
{
MCUBuffer[i] = 0;
QtZzMCUBuffer[i] = 0;
}
for(i = 0;i < 64;i++)
{
Y[i] = 0;
U[i] = 0;
V[i] = 0;
BlockBuffer[i] = 0;
}
ycoef = 0;
ucoef = 0;
vcoef = 0;
}
/*************************************************************************
Initialize_Fast_IDCT():Init
DecodeMCUBlock() Huffman Decode
IQtIZzMCUComponent()
GetYUV() Get Y U V
StoreBuffer() YUV to RGB
*************************************************************************/
int Decode(void)
{
int funcret;
Y_in_MCU = SampRate_Y_H * SampRate_Y_V; /* YDU YDU YDU YDU */
U_in_MCU = SampRate_U_H * SampRate_U_V; /* cRDU */
V_in_MCU = SampRate_V_H * SampRate_V_V; /* cBDU */
H_YtoU = SampRate_Y_H / SampRate_U_H;
V_YtoU = SampRate_Y_V / SampRate_U_V;
H_YtoV = SampRate_Y_H / SampRate_V_H;
V_YtoV = SampRate_Y_V / SampRate_V_V;
Initialize_Fast_IDCT();
funcret = DecodeMCUBlock();
while(funcret == FUNC_OK) { /* After Call DecodeMCUBUBlock() */
interval++; /* The Digital has been Huffman Decoded and */
if((restart != 0) && ((interval % restart) == 0)) { /* be stored in MCUBuffer(YDU,YDU,YDU,YDU */
IntervalFlag = OK; /* UDU,VDU) Every DU := 8*8 */
} else {
IntervalFlag = ERROR;
}
IQtIZzMCUComponent(0);
IQtIZzMCUComponent(1);
IQtIZzMCUComponent(2);
GetYUV(0);
GetYUV(1);
GetYUV(2);
StoreBuffer(); /* To RGB */
sizej = sizej + (UINT32)(SampRate_Y_H << 3);
if(sizej >= jpeg_w) {
sizej = 0;
sizei = sizei + (UINT32)(SampRate_Y_V << 3);
}
if ((sizej == 0) && (sizei >= jpeg_h)) {
break;
}
funcret = DecodeMCUBlock();
}
return funcret;
}
/**********************************************************************
In: QtZzMCUBuffer Out: Y[] U[] V[]
**********************************************************************/
void GetYUV(int flag)
{
int H,VV,i,j,k,hk;
int temp;
int *buf,*tempbuf,*pQtZzMCU;
switch(flag)
{
case 0:
H = SampRate_Y_H;
VV = SampRate_Y_V;
buf = Y;
pQtZzMCU = QtZzMCUBuffer;
break;
case 1:
H = SampRate_U_H;
VV = SampRate_U_V;
buf = U;
pQtZzMCU = QtZzMCUBuffer;
pQtZzMCU = pQtZzMCU + (Y_in_MCU << 6);
break;
case 2:
H = SampRate_V_H;
VV = SampRate_V_V;
buf = V;
pQtZzMCU = QtZzMCUBuffer;
pQtZzMCU = pQtZzMCU + ((Y_in_MCU + U_in_MCU) << 6);
break;
default:
H = 0;
VV = 0;
buf = NULL;
pQtZzMCU = NULL;
break;
}
for(i = 0;i < VV;i++)
{
for(j = 0;j < H;j++)
{
for(k = 0;k < 8;k++)
{
for(hk = 0;hk < 8;hk++)
{
temp = ((((i << 3) + k) * SampRate_Y_H) << 3) + (j << 3) + hk;
tempbuf = buf;
tempbuf = tempbuf + temp;
*tempbuf = (int)(*(pQtZzMCU++));
}
}
}
}
}
void StoreBuffer(void)
{
int i,j;
UINT8 *lprgb;
UINT8 R,G,B;
int yy,uu,vv,rr,gg,bb;
int TempSamp1,TempSamp2;
TempSamp1 = SampRate_Y_V << 3;
TempSamp2 = SampRate_Y_H << 3;
int *pY;
int *pU;
int *pV;
for(i = 0;i < TempSamp1;i++) {
if((sizei + i) < jpeg_h) {
lprgb = lpPtr + ( (sizei + i) * jpeg_p + (sizej << 1) );
pY=Y+i*TempSamp2;// (i << 3) * SampRate_Y_H;
pU=U+(i / V_YtoU)*TempSamp2;// << 3) * SampRate_Y_H;
pV=V+(i / V_YtoV)*TempSamp2;// << 3) * SampRate_Y_H;
for(j = 0;j < TempSamp2;j++) {
if((sizej + j) < jpeg_w) {
yy = *pY++;
uu = pU[ j/H_YtoU];
vv = pV[ j/H_YtoV];
rr = ((yy << 8) + 18 * uu + 367 * vv) >> 8;
gg = ((yy << 8) - 159 * uu - 220 * vv) >> 8;
bb = ((yy << 8) + 411 * uu - 29 * vv) >> 8;
R = (UINT8)(rr);
G = (UINT8)(gg);
B = (UINT8)(bb);
if((rr & 0xffffff00) != 0) {
if (rr > 255) {
R = 255;
} else {
if(rr < 0)
{
R = 0;
}
}
}
if((gg & 0xffffff00) != 0) {
if(gg > 255) {
G = 255;
} else {
if(gg < 0) {
G = 0;
}
}
}
if((bb & 0xffffff00) != 0) {
if(bb > 255) {
B = 255;
} else {
if(bb < 0) {
B = 0;
}
}
}
*lprgb++ = (UINT8)(B >> 3) + (UINT8)((G << 2) & 0xe0);
*lprgb++ = (UINT8)(G >> 6) + (UINT8)((R >> 1) & 0x7c);
} else {
break;
}
}
} else {
break;
}
}
}
/******************************************************************************
Huffman Decode Out:MCU MCUBuffer In:Blockbuffer[ ]
*******************************************************************************/
int DecodeMCUBlock(void)
{
int *lpMCUBuffer;
int i,j;
int funcret=0;
int tempX;
if(IntervalFlag == OK) {
lp += 2;
ycoef = 0;
ucoef = 0;
vcoef = 0;
BitPos = 0;
CurByte = 0;
}
switch(comp_num)
{ /* comp_num*/
case 3:
lpMCUBuffer = MCUBuffer;
tempX = SampRate_Y_H * SampRate_Y_V;
for(i = 0;i < tempX;i++){ /* Y */
funcret = HufBlock(YDcIndex,YAcIndex);
if(funcret != FUNC_OK)
{
printf("funcret1 = %x\n", funcret);
return funcret;
}
BlockBuffer[0] = BlockBuffer[0] + ycoef;
ycoef = BlockBuffer[0];
for(j = 0;j < 64;j++)
{
*lpMCUBuffer++ = BlockBuffer[j];
}
}
tempX = SampRate_U_H * SampRate_U_V;
for(i = 0;i < tempX;i++) { /* U */
funcret = HufBlock(UVDcIndex,UVAcIndex);
if(funcret != FUNC_OK) {
printf("funcret2 = %x\n", funcret);
return funcret;
}
BlockBuffer[0] = BlockBuffer[0] + ucoef;
ucoef = BlockBuffer[0];
for(j = 0;j < 64;j++) {
*lpMCUBuffer++ = BlockBuffer[j];
}
}
tempX = SampRate_V_H * SampRate_V_V;
for(i = 0;i < tempX;i++) { /* V */
funcret = HufBlock(UVDcIndex,UVAcIndex);
if(funcret != FUNC_OK)
{
printf("funcret3 = %x\n", funcret);
return funcret;
}
BlockBuffer[0] = BlockBuffer[0] + vcoef;
vcoef = BlockBuffer[0];
for(j = 0;j < 64;j++)
{
*lpMCUBuffer++ = BlockBuffer[j];
}
}
break;
case 1: /* Gray Picture */
lpMCUBuffer = MCUBuffer;
funcret = HufBlock(YDcIndex,YAcIndex);
if(funcret != FUNC_OK) {
return funcret;
}
BlockBuffer[0] = BlockBuffer[0] + ycoef;
ycoef = BlockBuffer[0];
for(j = 0;j < 64;j++) {
*lpMCUBuffer++ = BlockBuffer[j];
}
for(i = 0;i < 128;i++) {
*lpMCUBuffer++ = 0;
}
break;
default:
return FUNC_FORMAT_ERROR;
}
return FUNC_OK;
}
int HufBlock(UINT8 dchufindex,UINT8 achufindex)
{
int count,i;
int funcret;
count = 0;
/* dc */
HufTabIndex = dchufindex;
funcret = DecodeElement(); /* Read Byte Dc */
if(funcret != FUNC_OK) {
return funcret;
}
BlockBuffer[count++] = vvalue;
/* ac */
HufTabIndex = achufindex;
while(count < 64)
{ /* 63 Bytes AC */
funcret = DecodeElement();
if(funcret != FUNC_OK) {
return funcret;
}
if((rrun == 0) && (vvalue == 0)) {
for(i = count;i < 64;i++) {
BlockBuffer[i] = 0;
}
count = 64;
} else {
for(i = 0;i < rrun;i++) {
BlockBuffer[count++] = 0;
}
BlockBuffer[count++] = vvalue;
}
}
return FUNC_OK;
}
int DecodeElement(void)
{
int thiscode,tempcode;
UINT16 temp,valueex;
int codelen;
UINT8 hufexbyte,runsize,tempsize,sign;
UINT8 newbyte,lastbyte;
if(BitPos >= 1) {
BitPos--;
thiscode = (UINT8)CurByte >> BitPos;
CurByte = CurByte & MyAnd[BitPos];
} else {
lastbyte = ReadByte();
BitPos--; /* and[]:=0x0,0x1,0x3,0x7,0xf,0x1f,0x2f,0x3f,0x4f */
newbyte = CurByte & MyAnd[BitPos]; //
thiscode = lastbyte >> 7;
CurByte = newbyte;
}
codelen = 1;
while((thiscode < huf_min_value[HufTabIndex][codelen - 1]) ||
(code_len_table[HufTabIndex][codelen - 1] == 0) ||
(thiscode > huf_max_value[HufTabIndex][codelen - 1]))
{
if(BitPos >= 1) {
BitPos--;
tempcode = (UINT8)CurByte >> BitPos;
CurByte = CurByte & MyAnd[BitPos];
} else {
lastbyte = ReadByte();
BitPos--;
newbyte = CurByte & MyAnd[BitPos];
tempcode = (UINT8)lastbyte >> 7;
CurByte = newbyte;
}
thiscode = (thiscode << 1) + tempcode;
codelen++;
if(codelen > 16) {
return FUNC_FORMAT_ERROR;
}
} //while
temp = thiscode - huf_min_value[HufTabIndex][codelen - 1] + code_pos_table[HufTabIndex][codelen - 1];
hufexbyte = (UINT8)code_value_table[HufTabIndex][temp];
rrun = (int)(hufexbyte >> 4);
runsize = hufexbyte & 0x0f;
if(runsize == 0) {
vvalue = 0;
return FUNC_OK;
}
tempsize = runsize;
if(BitPos >= runsize) {
BitPos = BitPos - runsize;
valueex = (UINT8)CurByte >> BitPos;
CurByte = CurByte & MyAnd[BitPos];
} else {
valueex = CurByte;
tempsize = tempsize - BitPos;
while(tempsize > 8) {
lastbyte = ReadByte();
valueex = (valueex << 8) + (UINT8)lastbyte;
tempsize = tempsize - 8;
} //while
lastbyte = ReadByte();
BitPos = BitPos - tempsize;
valueex = (valueex << tempsize) + (lastbyte >> BitPos);
CurByte = lastbyte & MyAnd[BitPos];
}
sign = valueex >> (runsize - 1);
if(sign != 0) {
vvalue = valueex;
} else {
valueex = valueex ^ 0xffff;
temp = 0xffff << runsize;
vvalue = -(int)(valueex ^ temp);
}
return FUNC_OK;
}
void IQtIZzMCUComponent(int flag)
{
int H,VV,i,j;
int *pQtZzMCUBuffer,*tempbuf1;
int *pMCUBuffer,*tempbuf2;
switch(flag)
{
case 0:
H = SampRate_Y_H;
VV = SampRate_Y_V;
pMCUBuffer = MCUBuffer; /* Huffman Decoded */
pQtZzMCUBuffer = QtZzMCUBuffer;
break;
case 1:
H = SampRate_U_H;
VV = SampRate_U_V;
pMCUBuffer = MCUBuffer;
pMCUBuffer += Y_in_MCU << 6;
pQtZzMCUBuffer = QtZzMCUBuffer;
pQtZzMCUBuffer += Y_in_MCU << 6;
break;
case 2:
H = SampRate_V_H;
VV = SampRate_V_V;
pMCUBuffer = MCUBuffer;
pMCUBuffer += (Y_in_MCU + U_in_MCU) << 6;
pQtZzMCUBuffer = QtZzMCUBuffer;
pQtZzMCUBuffer += (Y_in_MCU + U_in_MCU) << 6;
break;
default:
H = 0;
pQtZzMCUBuffer = NULL;
pMCUBuffer = NULL;
VV = 0;
break;
}
for(i = 0;i < VV;i++) {
for(j = 0;j < H;j++) {
tempbuf2 = pMCUBuffer;
tempbuf2 += (i * H + j) << 6;
tempbuf1 = pQtZzMCUBuffer;
tempbuf1 += (i * H + j) << 6;
IQtIZzBlock(tempbuf2,tempbuf1,flag); /* 8*8DU */
}
}
}
void IQtIZzBlock(int *s,int *d,int flag)
{
int i,j,tag;
int *pQt,*temp1,*temp3;
int buffer2[8][8];
int *temp2;
int offset;
switch(flag)
{
case 0:
pQt = YQtTable;
/* ShowMessage(IntTostr(YQtTable^)); */
offset = 128;
break;
case 1:
pQt = UQtTable;
offset = 0;
break;
case 2:
pQt = VQtTable;
offset = 0;
break;
default:
pQt = NULL;
offset = 0;
break;
}
for(i = 0;i < 8;i++)
{
for(j = 0;j < 8;j++)
{
tag = Zig_Zag[i][j];
temp1 = s;
temp1 = temp1 + tag;
temp3 = pQt;
temp3 = temp3 + tag;
buffer2[i][j] = (int)((*temp1) * (*temp3));
}
}
Fast_IDCT(&buffer2[0][0]);
for(i = 0;i < 8;i++)
{
for(j = 0;j < 8;j++)
{
temp2 = d;
temp2 = temp2 + (i * 8 +j);
*temp2 = buffer2[i][j] + offset;
}
}
}
void Fast_IDCT(int *block)
{
int i;
for(i = 0;i < 8;i++) {
idctrow(block + 8 * i);
}
for(i = 0;i < 8;i++) {
idctcol(block + i);
}
}
UINT8 ReadByte(void)
{
UINT8 i;
i = *lp;
lp = lp + 1;
if(i == 0xff) {
lp = lp + 1;
}
BitPos = 8;
CurByte = i;
return i;
}
void Initialize_Fast_IDCT(void)
{
int i;
for(i = -512;i < 512;i++)
{
if(i < -256)
{
iclip[512 + i] = -256;
}
if(i > 255)
{
iclip[512 + i] = 255;
}
if(( i >= -256) && (i <= 255))
{
iclip[512 + i] = i;
}
}
}
void idctrow(int *blk)
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
//intcut
x1 = blk[4] << 11;
x2 = blk[6];
x3 = blk[2];
x4 = blk[1];
x5 = blk[7];
x6 = blk[5];
x7 = blk[3];
if ((x1 || x2 || x3 || x4 || x5 || x6 || x7) == 0) {
blk[1] = blk[0] << 3;
blk[2] = blk[0] << 3;
blk[3] = blk[0] << 3;
blk[4] = blk[0] << 3;
blk[5] = blk[0] << 3;
blk[6] = blk[0] << 3;
blk[7] = blk[0] << 3;
blk[0] = blk[0] << 3;
return;
}
x0 = (blk[0] << 11) + 128; /* for proper rounding in the fourth stage */
/* first stage */
x8 = W7 * (x4 + x5);
x4 = x8 + (W1 - W7) * x4;
x5 = x8 - (W1 + W7) * x5;
x8 = W3 * (x6 + x7);
x6 = x8 - (W3 - W5) * x6;
x7 = x8 - (W3 + W5) * x7;
/* second stage */
x8 = x0 + x1;
x0 = x0 - x1;
x1 = W6 * (x3 + x2);
x2 = x1 - (W2 + W6) * x2;
x3 = x1 + (W2 - W6) * x3;
x1 = x4 + x6;
x4 = x4 - x6;
x6 = x5 + x7;
x5 = x5 - x7;
/* third stage */
x7 = x8 + x3;
x8 = x8 - x3;
x3 = x0 + x2;
x0 = x0 - x2;
x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */
blk[0] = (x7 + x1) >> 8;
blk[1] = (x3 + x2) >> 8;
blk[2] = (x0 + x4) >> 8;
blk[3] = (x8 + x6) >> 8;
blk[4] = (x8 - x6) >> 8;
blk[5] = (x0 - x4) >> 8;
blk[6] = (x3 - x2) >> 8;
blk[7] = (x7 - x1) >> 8;
}
void idctcol(int * blk)
{
int x0, x1, x2, x3, x4, x5, x6, x7, x8;
int Temp;
/* intcut */
x1 = blk[8 * 4] << 8;
x2 = blk[8 * 6];
x3 = blk[8 * 2];
x4 = blk[8 * 1];
x5 = blk[8 * 7];
x6 = blk[8 * 5];
x7 = blk[8 * 3];
if ((x1 | x2 | x3 | x4 | x5 | x6 | x7) == 0)
{
Temp = (blk[8 * 0] + 32) >> 6;
blk[8 * 1] = iclip[512 + Temp];
blk[8 * 2] = iclip[512 + Temp];
blk[8 * 3] = iclip[512 + Temp];
blk[8 * 4] = iclip[512 + Temp];
blk[8 * 5] = iclip[512 + Temp];
blk[8 * 6] = iclip[512 + Temp];
blk[8 * 7] = iclip[512 + Temp];
blk[8 * 0] = iclip[512 + Temp];
return;
}
x0 = (blk[8 * 0] << 8) + 8192;
/* first stage */
x8 = W7 * (x4 + x5) + 4;
x4 = (x8 + (W1 - W7) * x4) >> 3;
x5 = (x8 - (W1 + W7) * x5) >> 3;
x8 = W3 * (x6 + x7) + 4;
x6 = (x8 -(W3 - W5) * x6) >> 3;
x7 = (x8 - (W3 + W5) * x7) >> 3;
/* second stage */
x8 = x0 + x1;
x0 = x0 - x1;
x1 = W6 * (x3 + x2) + 4;
x2 = (x1 - (W2 + W6) * x2) >> 3;
x3 = (x1 + (W2 - W6) * x3) >> 3;
x1 = x4 + x6;
x4 = x4 - x6;
x6 = x5 + x7;
x5 = x5 - x7;
/* third stage */
x7 = x8 + x3;
x8 = x8 - x3;
x3 = x0 + x2;
x0 = x0 - x2;
x2 = (181 * (x4 + x5) + 128) >> 8;
x4 = (181 * (x4 - x5) + 128) >> 8;
/* fourth stage */
Temp = (x7 + x1) >> 14;
blk[0] = iclip[512 + Temp];
Temp = (x3 + x2) >> 14;
blk[8] = iclip[512 + Temp];
Temp = (x0 + x4) >> 14;
blk[16] = iclip[512 + Temp];
Temp = (x8 + x6) >> 14;
blk[24] = iclip[512 + Temp];
Temp = (x8 - x6) >> 14;
blk[32] = iclip[512 + Temp];
Temp = (x0 - x4) >> 14;
blk[40] = iclip[512 + Temp];
Temp = (x3 - x2) >> 14;
blk[48] = iclip[512 + Temp];
Temp = (x7 - x1) >> 14;
blk[56] = iclip[512 + Temp];
}