?? decode.c
字號:
/*
*********************************************************************
* File name: decode.c
* Version: 5.0(release v1.0) Date: Jan 12, 2006
* Author: xiezm Email: xiezm@wxintech.cn
* Company: Wuxi Intech co., ltd.
*
* Project: Jpeg Decoder for Trio
*********************************************************************
*/
#define DECODE_GLOBALS
#include "cf6_chess.h"
#include "djpg.h"
#include "bitstream.h"
#define DC 0
#define AC 1
//#define INT_P362 362
//#define INT_P473 473
//#define INT_P277 277
//#define INT_M669 (-669)
const int natural_order[DCT_SIZE2] =
{
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
};
int errorHuffman=0;
void decode_initial(void)
{
int i;
decode_bitstream_initial();
for(i=0;i<MAX_COMPS;i++)
{
PreDC[i] = 0;
}
for(i=1;i<16;i++)
{
shift_std[i] = 1<<(i-1);
shift_offset[i] = (((-1) << i) + 1);
}
#if 0
for(i=0;i<32;i++)
{
cellingR_tab[i] = 0;
cellingG_tab[i] = 0;
cellingB_tab[i] = 0;
}
for(i=0;i<64;i++)
{
cellingR_tab[i+32] = ((i>>1)<<11);
cellingG_tab[i+32] = (i<<5);
cellingB_tab[i+32] = (i>>1);
}
for(i=0;i<32;i++)
{
cellingR_tab[i+96] = 0x00F800;
cellingG_tab[i+96] = 0x0007E0;
cellingB_tab[i+96] = 0x00001F;
}
cellingR = &cellingR_tab[32];
cellingG = &cellingG_tab[32];
cellingB = &cellingB_tab[32];
#else
for(i=0;i<128;i++)
{
cellingR_tab1[i] = 0;
cellingG_tab1[i] = 0;
cellingB_tab1[i] = 0;
}
for(i=0;i<256;i++)
{
cellingR_tab1[i+128] = ((i>>3)<<11);
cellingG_tab1[i+128] = ((i>>2)<<5);
cellingB_tab1[i+128] = (i>>3);
}
for(i=0;i<128;i++)
{
cellingR_tab1[i+384] = 0x00F800;
cellingG_tab1[i+384] = 0x0007E0;
cellingB_tab1[i+384] = 0x00001F;
}
cellingR = &cellingR_tab1[128];
cellingG = &cellingG_tab1[128];
cellingB = &cellingB_tab1[128];
#endif
restart_marker = 0;
INT_P454 = 454;
INT_M88 = -88;
INT_M183 = -183;
INT_P359 = 359;
INT_P362 = 362;
INT_P473 = 473;
INT_P277 = 277;
INT_M669 = -669;
}
unsigned int de_huffman_cal()
{
int l = 9;
int code;
code = get_bits(l);
while (code > htbl->maxcode[l])
{
code <<= 1;
code |= get_bits(1);
l++;
}
if (l > 16)
{
errorHuffman = 15;
return 0;//error(15);
l = 16; /* fake the result */
}
return (htbl->symbol[(unsigned int) (code + htbl->valoffset[l])]);
}
#if 1 //yover_optimize_0822
unsigned int de_huffman(void)
{
unsigned int peek, nb;
peek = peek_byte();
if ((nb = htbl->look_nbits[peek]) != 0)
{
drop_bits(nb);
return(htbl->look_sym[peek]);
}
return de_huffman_cal();
}
#else
#define de_huffman(dhfm) \
{ \
unsigned int peek, nb; \
peek = peek_byte(); \
if ((nb = htbl->look_nbits[peek]) != 0) \
{ \
drop_bits(nb); \
dhfm = (htbl->look_sym[peek]); \
} \
else \
dhfm = de_huffman_cal(); \
}
#endif
void restart_decode(void)
{
drop_bits(bits_left%8); //sync
if((0x00ff!=get_bits(8)) || ((get_bits(8) - RST0) != restart_marker))
{
error(17);
}
restart_marker++;
restart_marker %= 8;
PreDC[0] = 0;
PreDC[1] = 0;
PreDC[2] = 0;
}
void fast_IDCT(int rec_idx);
int decode_data_unit(int comp, int rec_idx)
{
unsigned int bits;
unsigned int RS;
unsigned int SSSS;
unsigned int RRRR;
unsigned int K;
int Diff;
int iRet = 0;
int chess_storage(YMEM) *qtbl;
int *inptr;
int *wsptr;
int *outptr;
int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
int tmp10, tmp11, tmp12, tmp13;
int z5, z10, z11, z12, z13;
/* decode DC */
//cal Diff
htbl = &dc_huff_tbl[Tdi[comp]];
//yover_optimize_0822, de_huffman(bits);
bits = de_huffman();//yover_optimize_0822,
if(errorHuffman==15)
{
return 15;
}
if(bits)
{
Diff = get_bits(bits);
Diff = (Diff < shift_std[bits] ? (Diff + shift_offset[bits]) : Diff);
}
else
{
Diff = 0;
}
ZZ[0] = (PreDC[comp] += Diff);
/* decode ACs */
htbl = &ac_huff_tbl[Tai[comp]];
for(K=1;K<DCT_SIZE2;K++)
{
ZZ[K] = 0; //can use memset
}
K=1;
do{
int ac_tmp;
//yover_optimize_0822, de_huffman(RS);
RS = de_huffman();//yover_optimize_0822,
if(errorHuffman==15)
{
return 15;
}
SSSS = RS & 0x0f;
RRRR = RS >> 4;
if(SSSS)
{
K += RRRR;
//Decode_zz[k]
ac_tmp = get_bits(SSSS);
ZZ[K] = (ac_tmp < shift_std[SSSS] ? ac_tmp + shift_offset[SSSS] : ac_tmp);
}
else
{
if(15 == RRRR)
{
K += 16;
continue;
}
else
{
K=64;
break;
}
}
K++;
}while(K < 64);/*while(64 == K);*/
if(64 != K)
{
error(16);
}
//de-quantiz
qtbl = (int chess_storage(YMEM) *)quant_tbl[Tqi[comp]];
inptr = reconstruc_buffer[rec_idx];
for(K=0;K<DCT_SIZE2;K++)
{
inptr[natural_order[K]] = (ZZ[K] * qtbl[K]) >> 10;
}
wsptr = ZZ;
for(K=DCT_SIZE; K>0; K--)
{
tmp0 = inptr[0];
tmp4 = inptr[8];
tmp1 = inptr[16];
tmp5 = inptr[24];
tmp2 = inptr[32];
tmp6 = inptr[40];
tmp3 = inptr[48];
tmp7 = inptr[56];
tmp10 = tmp0 + tmp2;
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3;
tmp12 = ((INT_P362*(tmp1 - tmp3))>>8) - tmp13;
tmp0 = tmp10 + tmp13;
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
z13 = tmp6 + tmp5;
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13;
tmp11 = (INT_P362*(z11 - z13))>>8;
z5 = ((z10 + z12)*INT_P473);
tmp10 = ((INT_P277*z12 - z5)>>8);
tmp12 = ((INT_M669*z10 + z5)>>8);
tmp6 = tmp12 - tmp7;
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
wsptr[0] = (tmp0 + tmp7);
wsptr[8] = (tmp1 + tmp6);
wsptr[16] = (tmp2 + tmp5);
wsptr[24] = (tmp3 - tmp4);
wsptr[32] = (tmp3 + tmp4);
wsptr[40] = (tmp2 - tmp5);
wsptr[48] = (tmp1 - tmp6);
wsptr[56] = (tmp0 - tmp7);
inptr++;
wsptr++;
}
/* pass 2 */
wsptr = ZZ;
outptr = reconstruc_buffer[rec_idx];
for(K=DCT_SIZE; K>0; K--)
{
tmp10 = (wsptr[0] + wsptr[4]);
tmp11 = (wsptr[0] - wsptr[4]);
tmp13 = (wsptr[2] + wsptr[6]);
tmp12 = ((INT_P362*(wsptr[2] - wsptr[6]))>>8) - tmp13;
tmp0 = tmp10 + tmp13;
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
z13 = wsptr[5] + wsptr[3];
z10 = wsptr[5] - wsptr[3];
z11 = wsptr[1] + wsptr[7];
z12 = wsptr[1] - wsptr[7];
tmp7 = z11 + z13;
tmp11 = (INT_P362*(z11 - z13))>>8;
z5 = (z10 + z12)*INT_P473;
tmp10 = ((INT_P277*z12 - z5)>>8);
tmp12 = ((INT_M669*z10 + z5)>>8);
tmp6 = tmp12 - tmp7;
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
*outptr++ = ((tmp0 + tmp7)>>5);
*outptr++ = ((tmp1 + tmp6)>>5);
*outptr++ = ((tmp2 + tmp5)>>5);
*outptr++ = ((tmp3 - tmp4)>>5);
*outptr++ = ((tmp3 + tmp4)>>5);
*outptr++ = ((tmp2 - tmp5)>>5);
*outptr++ = ((tmp1 - tmp6)>>5);
*outptr++ = ((tmp0 - tmp7)>>5);
wsptr += DCT_SIZE;
}
return iRet;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -