1127 lines
24 KiB
C
Executable File
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];
|
|
|
|
}
|
|
|
|
|