⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jpegtobmp.cpp

📁 一个可用于多平台的旋转180度 jpg的源代码。大家可以进一步的改进。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#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 + -