📄 jpegtobmp.cpp
字号:
#pragma aux lookKbits=\
"mov eax,[wordval]"\
"mov cl, 16"\
"sub cl, dl"\
"shr eax, cl"\
parm [dl] \
value [ax] \
modify [eax cl];
WORD WORD_hi_lo(BYTE byte_high,BYTE BYTE_low);
#pragma aux WORD_hi_lo=\
parm [ah] [al]\
value [ax] \
modify [ax];
SWORD get_svalue(BYTE k);
// k>0 always
// Takes k bits out of the BIT stream (wordval), and makes them a signed value
#pragma aux get_svalue=\
"xor ecx, ecx"\
"mov cl, al"\
"mov eax,[wordval]"\
"shl eax, cl"\
"shr eax, 16"\
"dec cl"\
"bt eax,ecx"\
"jc end_macro"\
"signed_value:inc cl"\
"mov ebx,[start_neg_pow2]"\
"add ax,word ptr [ebx+ecx*2]"\
"end_macro:"\
parm [al]\
modify [eax ebx ecx]\
value [ax];
#endif
void skipKbits(BYTE k)
{
BYTE b_high,b_low;
d_k+=k;
if (d_k>=16) { d_k-=16;
w1=w2;
// Get the next word in w2
BYTE_p(byte_pos);
if (bp!=0xFF) b_high=bp;
else {
if (buf[byte_pos]==0) byte_pos++; //skip 00
else byte_pos--; // stop byte_pos pe restart marker
b_high=0xFF;
}
BYTE_p(byte_pos);
if (bp!=0xFF) b_low=bp;
else {
if (buf[byte_pos]==0) byte_pos++; //skip 00
else byte_pos--; // stop byte_pos pe restart marker
b_low=0xFF;
}
w2=WORD_hi_lo(b_high,b_low);
}
wordval = ((DWORD)(w1)<<16) + w2;
wordval <<= d_k;
wordval >>= 16;
}
SWORD getKbits(BYTE k)
{
SWORD signed_wordvalue;
signed_wordvalue=get_svalue(k);
skipKbits(k);
return signed_wordvalue;
}
void calculate_mask()
{
BYTE k;
DWORD tmpdv;
for (k=0;k<=16;k++) { tmpdv=0x10000;mask[k]=(tmpdv>>k)-1;} //precalculated bit mask
}
void init_QT()
{
BYTE i;
for (i=0;i<=3;i++) QT[i]=(float *)malloc(sizeof(float)*64);
}
void load_quant_table(float *quant_table)
{
float scalefactor[8]={1.0f, 1.387039845f, 1.306562965f, 1.175875602f,
1.0f, 0.785694958f, 0.541196100f, 0.275899379f};
BYTE j,row,col;
// Load quantization coefficients from JPG file, scale them for DCT and reorder
// from zig-zag order
for (j=0;j<=63;j++) quant_table[j]=buf[byte_pos+zigzag[j]];
j=0;
for (row=0;row<=7;row++)
for (col=0;col<=7;col++) {
quant_table[j]*=scalefactor[row]*scalefactor[col];
j++;
}
byte_pos+=64;
}
void load_Huffman_table(Huffman_table *HT)
{
BYTE k,j;
DWORD code;
for (j=1;j<=16;j++) {
BYTE_p(byte_pos);
HT->Length[j]=bp;
}
for (k=1;k<=16;k++)
for (j=0;j<HT->Length[k];j++) {
BYTE_p(byte_pos);
HT->V[WORD_hi_lo(k,j)]=bp;
}
code=0;
for (k=1;k<=16;k++) {
HT->minor_code[k] = (WORD)code;
for (j=1;j<=HT->Length[k];j++) code++;
HT->major_code[k]=(WORD)(code-1);
code*=2;
if (HT->Length[k]==0) {
HT->minor_code[k]=0xFFFF;
HT->major_code[k]=0;
}
}
}
void process_Huffman_data_unit(BYTE DC_nr, BYTE AC_nr,SWORD *previous_DC)
{
// Process one data unit. A data unit = 64 DCT coefficients
// Data is decompressed by Huffman decoding, then the array is dezigzag-ed
// The result is a 64 DCT coefficients array: DCT_coeff
BYTE nr,k,j,EOB_found;
register WORD tmp_Hcode;
BYTE size_val,count_0;
WORD *min_code,*maj_code; // min_code[k]=minimum code of length k, maj_code[k]=similar but maximum
WORD *max_val, *min_val;
BYTE *huff_values;
SWORD DCT_tcoeff[64];
BYTE byte_temp;
// Start Huffman decoding
// First the DC coefficient decoding
min_code=HTDC[DC_nr].minor_code;
maj_code=HTDC[DC_nr].major_code;
huff_values=HTDC[DC_nr].V;
for (nr = 0; nr < 64 ; nr++) DCT_tcoeff[nr] = 0; //Initialize DCT_tcoeff
nr=0;// DC coefficient
min_val = &min_code[1]; max_val = &maj_code[1];
for (k=1;k<=16;k++) {
tmp_Hcode=lookKbits(k);
// max_val = &maj_code[k]; min_val = &min_code[k];
if ( (tmp_Hcode<=*max_val)&&(tmp_Hcode>=*min_val) ) { //Found a valid Huffman code
skipKbits(k);
size_val=huff_values[WORD_hi_lo(k,(BYTE)(tmp_Hcode-*min_val))];
if (size_val==0) DCT_tcoeff[0]=*previous_DC;
else {
DCT_tcoeff[0]=*previous_DC+getKbits(size_val);
*previous_DC=DCT_tcoeff[0];
}
break;
}
min_val++; max_val++;
}
// Second, AC coefficient decoding
min_code=HTAC[AC_nr].minor_code;
maj_code=HTAC[AC_nr].major_code;
huff_values=HTAC[AC_nr].V;
nr=1; // AC coefficient
EOB_found=0;
while ( (nr<=63)&&(!EOB_found) )
{
max_val = &maj_code[1]; min_val =&min_code[1];
for (k=1;k<=16;k++)
{
tmp_Hcode=lookKbits(k);
// max_val = &maj_code[k]; &min_val = min_code[k];
if ( (tmp_Hcode<=*max_val)&&(tmp_Hcode>=*min_val) )
{
skipKbits(k);
byte_temp=huff_values[WORD_hi_lo(k,(BYTE)(tmp_Hcode-*min_val))];
size_val=byte_temp&0xF;
count_0=byte_temp>>4;
if (size_val==0) {if (count_0==0) EOB_found=1;
else if (count_0==0xF) nr+=16; //skip 16 zeroes
}
else
{
nr+=count_0; //skip count_0 zeroes
DCT_tcoeff[nr++]=getKbits(size_val);
}
break;
}
min_val++; max_val++;
}
if (k>16) nr++; // This should not occur
}
for (j=0;j<=63;j++) DCT_coeff[j]=DCT_tcoeff[zigzag[j]]; // Et, voila ... DCT_coeff
}
void IDCT_transform(SWORD *incoeff,BYTE *outcoeff,BYTE Q_nr)
// Fast float IDCT transform
{
BYTE x;
SBYTE y;
SWORD *inptr;
BYTE *outptr;
float workspace[64];
float *wsptr;//Workspace pointer
float *quantptr; // Quantization table pointer
float dcval;
float tmp0,tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7;
float tmp10,tmp11,tmp12,tmp13;
float z5,z10,z11,z12,z13;
BYTE *range_limit=rlimit_table+128;
// Pass 1: process COLUMNS from input and store into work array.
wsptr=workspace;
inptr=incoeff;
quantptr=QT[Q_nr];
for (y=0;y<=7;y++)
{
if( (inptr[8]|inptr[16]|inptr[24]|inptr[32]|inptr[40]|inptr[48]|inptr[56])==0)
{
// AC terms all zero (in a column)
dcval=inptr[0]*quantptr[0];
wsptr[0] = dcval;
wsptr[8] = dcval;
wsptr[16] = dcval;
wsptr[24] = dcval;
wsptr[32] = dcval;
wsptr[40] = dcval;
wsptr[48] = dcval;
wsptr[56] = dcval;
inptr++;quantptr++;wsptr++;//advance pointers to next column
continue ;
}
//Even part
tmp0 = inptr[0] *quantptr[0];
tmp1 = inptr[16]*quantptr[16];
tmp2 = inptr[32]*quantptr[32];
tmp3 = inptr[48]*quantptr[48];
tmp10 = tmp0 + tmp2;// phase 3
tmp11 = tmp0 - tmp2;
tmp13 = tmp1 + tmp3;// phases 5-3
tmp12 = (tmp1 - tmp3) * 1.414213562f - tmp13; // 2*c4
tmp0 = tmp10 + tmp13;// phase 2
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
// Odd part
tmp4 = inptr[8] *quantptr[8];
tmp5 = inptr[24]*quantptr[24];
tmp6 = inptr[40]*quantptr[40];
tmp7 = inptr[56]*quantptr[56];
z13 = tmp6 + tmp5;// phase 6
z10 = tmp6 - tmp5;
z11 = tmp4 + tmp7;
z12 = tmp4 - tmp7;
tmp7 = z11 + z13;// phase 5
tmp11= (z11 - z13) * 1.414213562f; // 2*c4
z5 = (z10 + z12) * 1.847759065f; // 2*c2
tmp10 = 1.082392200f * z12 - z5; // 2*(c2-c6)
tmp12 = -2.613125930f * z10 + z5;// -2*(c2+c6)
tmp6 = tmp12 - tmp7;// phase 2
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
wsptr[0] = tmp0 + tmp7;
wsptr[56] = tmp0 - tmp7;
wsptr[8] = tmp1 + tmp6;
wsptr[48] = tmp1 - tmp6;
wsptr[16] = tmp2 + tmp5;
wsptr[40] = tmp2 - tmp5;
wsptr[32] = tmp3 + tmp4;
wsptr[24] = tmp3 - tmp4;
inptr++;
quantptr++;
wsptr++;//advance pointers to the next column
}
// Pass 2: process ROWS from work array, store into output array.
// Note that we must descale the results by a factor of 8 = 2^3
outptr=outcoeff;
wsptr=workspace;
for (x=0;x<=7;x++)
{
// Even part
tmp10 = wsptr[0] + wsptr[4];
tmp11 = wsptr[0] - wsptr[4];
tmp13 = wsptr[2] + wsptr[6];
tmp12 =(wsptr[2] - wsptr[6]) * 1.414213562f - tmp13;
tmp0 = tmp10 + tmp13;
tmp3 = tmp10 - tmp13;
tmp1 = tmp11 + tmp12;
tmp2 = tmp11 - tmp12;
// Odd part
z13 = wsptr[5] + wsptr[3];
z10 = wsptr[5] - wsptr[3];
z11 = wsptr[1] + wsptr[7];
z12 = wsptr[1] - wsptr[7];
tmp7 = z11 + z13;
tmp11= (z11 - z13) * 1.414213562f;
z5 = (z10 + z12) * 1.847759065f; // 2*c2
tmp10 = 1.082392200f * z12 - z5; // 2*(c2-c6)
tmp12 = -2.613125930f * z10 + z5; // -2*(c2+c6)
tmp6 = tmp12 - tmp7;
tmp5 = tmp11 - tmp6;
tmp4 = tmp10 + tmp5;
// Final output stage: scale down by a factor of 8
outptr[0] = range_limit[(DESCALE((int) (tmp0 + tmp7), 3)) & 1023L];
outptr[7] = range_limit[(DESCALE((int) (tmp0 - tmp7), 3)) & 1023L];
outptr[1] = range_limit[(DESCALE((int) (tmp1 + tmp6), 3)) & 1023L];
outptr[6] = range_limit[(DESCALE((int) (tmp1 - tmp6), 3)) & 1023L];
outptr[2] = range_limit[(DESCALE((int) (tmp2 + tmp5), 3)) & 1023L];
outptr[5] = range_limit[(DESCALE((int) (tmp2 - tmp5), 3)) & 1023L];
outptr[4] = range_limit[(DESCALE((int) (tmp3 + tmp4), 3)) & 1023L];
outptr[3] = range_limit[(DESCALE((int) (tmp3 - tmp4), 3)) & 1023L];
wsptr+=8;//advance pointer to the next row
outptr+=8;
}
}
void precalculate_Cr_Cb_tables()
{
WORD k;
WORD Cr_v,Cb_v;
for (k=0;k<=255;k++) Cr_tab[k]=(SWORD)((k-128.0)*1.402);
for (k=0;k<=255;k++) Cb_tab[k]=(SWORD)((k-128.0)*1.772);
for (Cr_v=0;Cr_v<=255;Cr_v++)
for (Cb_v=0;Cb_v<=255;Cb_v++)
Cr_Cb_green_tab[((WORD)(Cr_v)<<8)+Cb_v]=(int)(-0.34414*(Cb_v-128.0)-0.71414*(Cr_v-128.0));
}
void convert_8x8_YCbCr_to_RGB(BYTE *Y, BYTE *Cb, BYTE *Cr, DWORD im_loc, DWORD X_image_bytes, BYTE *im_buffer)
// Functia (ca optimizare) poate fi apelata si fara parametrii Y,Cb,Cr
// Stim ca va fi apelata doar in cazul 1x1
{
DWORD x,y;
BYTE im_nr;
BYTE *Y_val = Y, *Cb_val = Cb, *Cr_val = Cr;
BYTE *ibuffer = im_buffer + im_loc;
for (y=0;y<8;y++)
{
im_nr=0;
for (x=0;x<8;x++)
{
ibuffer[im_nr++] = rlimit_table[*Y_val + Cb_tab[*Cb_val]]; //B
ibuffer[im_nr++] = rlimit_table[*Y_val + Cr_Cb_green_tab[WORD_hi_lo(*Cr_val,*Cb_val)]]; //G
ibuffer[im_nr++] = rlimit_table[*Y_val + Cr_tab[*Cr_val]]; // R
/*
// Monochrome display
im_buffer[im_nr++] = *Y_val;
im_buffer[im_nr++] = *Y_val;
im_buffer[im_nr++] = *Y_val;
*/
Y_val++; Cb_val++; Cr_val++; im_nr++;
}
ibuffer+=X_image_bytes;
}
}
void convert_8x8_YCbCr_to_RGB_tab(BYTE *Y, BYTE *Cb, BYTE *Cr, BYTE *tab, DWORD im_loc, DWORD X_image_bytes, BYTE *im_buffer)
// Functia (ca optimizare) poate fi apelata si fara parametrii Cb,Cr
{
DWORD x,y;
BYTE nr, im_nr;
BYTE Y_val,Cb_val,Cr_val;
BYTE *ibuffer = im_buffer + im_loc;
nr=0;
for (y=0;y<8;y++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -