#include <iostream> #include <fstream> #include <string> #include <algorithm> //BMP数据加解压 using namespace std; #define USE_ACCURATE_ROUNDING #define RIGHT_SHIFT(x, shft) ((x) >> (shft)) #ifdef USE_ACCURATE_ROUNDING #define ONE ((int) 1) #define DESCALE(x, n) RIGHT_SHIFT((x) + (ONE << ((n) - 1)), n) #else #define DESCALE(x, n) RIGHT_SHIFT(x, n) #endif #define CONST_BITS 13 #define PASS1_BITS 2 #define FIX_0_298631336 ((int) 2446) /* FIX(0.298631336) */ #define FIX_0_390180644 ((int) 3196) /* FIX(0.390180644) */ #define FIX_0_541196100 ((int) 4433) /* FIX(0.541196100) */ #define FIX_0_765366865 ((int) 6270) /* FIX(0.765366865) */ #define FIX_0_899976223 ((int) 7373) /* FIX(0.899976223) */ #define FIX_1_175875602 ((int) 9633) /* FIX(1.175875602) */ #define FIX_1_501321110 ((int) 12299) /* FIX(1.501321110) */ #define FIX_1_847759065 ((int) 15137) /* FIX(1.847759065) */ #define FIX_1_961570560 ((int) 16069) /* FIX(1.961570560) */ #define FIX_2_053119869 ((int) 16819) /* FIX(2.053119869) */ #define FIX_2_562915447 ((int) 20995) /* FIX(2.562915447) */ #define FIX_3_072711026 ((int) 25172) /* FIX(3.072711026) */ #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) */ /* private data */ static int iclip[1024]; /* clipping table */ static int *iclp; /* two dimensional inverse discrete cosine transform */ // fidct_init() MUST BE CALLED BEOFRE THE FIRST CALL TO THIS FUNCTION! typedef unsigned char BYTE; struct JPEGSENDDATA { //huffman编码后的y,u,v各表的数据长度 int yHufLen, uHufLen, vHufLen; //原BMP图的高row,宽col,像素BYTE数 int row, col, pixel; //huffman编码后的数据,格式为 huffman后的y,u,v表 //后再分别接y,u,v表的huffman树 BYTE *m_data; //m_data数据的总长度 int dataLen; //huffman解压后y,u,v的长度,作为解 Z编码 输入的数据 int yZcodeLen, uZcodeLen, vZcodeLen; //离散余弦变换后的y,u,v各表的第一个数据的大小,用于DPM编码 int m_yTableFirstByte,m_uTableFirstByte,m_vTableFirstByte; int crc32; //int hufftreeCrc32_y; //int hufftreeCrc32_u; //int hufftreeCrc32_v; }; struct HUFFTREE { int weight; short lchild, rchild, parent; bool in_tree; //lchild->weight < rchild->weight }; class JPEG {//模拟JPEG加解压BMP数据 public: //TO JPEG //data : 输入的BMP内存中的图像部分的数据 //row BMP图片高,col BMP图片宽,pixel像素BYTE数 //注:不释放data的数据,调用者外面自己释放data JPEG(BYTE *data, int row, int col, int pixel); //TO BMP //注:内部不释放data的数据,调用者外面自己释放data JPEG(JPEGSENDDATA *data); ~JPEG(); void PrintY(); void PrintU(); void PrintV(); void PrintData(); //返回解缩后的BMP内容BYTE的数据 BYTE * ReturnData(); //返回压缩后的JPEG头格式的数据 JPEGSENDDATA *ReturnSendData(); private: //临时调试 inline void DispatchDCT(); inline void DispatchTDCT(); //BMP->JPEG inline bool DispatchDCT2(); //JPEG->BMP inline bool DispatchTDCT2(); //反离散余弦变换 inline void fidct_init(); inline void fidct(int * block); inline void TDCT(int *lpBuf); //离散余弦变换 inline void fdct(int *block); inline void fast_fdct(int *block); inline void DCT(int *lpBuf); //量化 inline void Quantize(); //反量化 inline void TQuantize(); //RGB->YUV inline bool RGBDataToYuv(); //YUV->RGB inline bool YuvDataToRGB(); //Z编码 inline bool Zcode(int *&lpBuf, const int &bufSize, int &zcodeLen); //解Z编码 inline bool TZcode(int *&lpBuf, const int &bufSize, int &zcodeLen); //HUFFMAN压缩 inline bool HuffmanCompress(); //解HUFFMAN压缩 inline bool HuffmanDesCompress(); //临时调试 inline void NotHaveHuffman(); inline void InitJpegData(); inline void AjustGB(); private: BYTE *m_data; int *m_y, *m_u, *m_v; int m_yTableFirstByte,m_uTableFirstByte,m_vTableFirstByte; int m_pixel, m_col, m_row; int m_ySize, m_uSize, m_vSize; int m_yZcodeLen, m_uZcodeLen, m_vZcodeLen; JPEGSENDDATA *m_send_data; }; class HUFFMAN {//采用数组树结构 typedef int HUFFDATATYPE_EN; typedef unsigned char HUFFDATATYPE_DES; typedef unsigned char BYTE; public: HUFFMAN(HUFFDATATYPE_EN *arry, int size); HUFFMAN(HUFFDATATYPE_DES *arry, int size, HUFFDATATYPE_DES *hufftr, int hufLen); //HUFFMAN压缩 bool HuffCode(BYTE *&ret, int &ret_pos); //解HUFFMAN压缩 bool HuffDesCode(HUFFDATATYPE_EN *&ret); //返回HUFFMAN树 bool ReturnHuffTree(HUFFTREE * &hufftr); //计算和显示HUFFMAN树,用于验证 void CounTreeCrc(int &ret); void PrintSendTree(); ~HUFFMAN(); private: //获取最小点对 inline void MakeMinPair(const short &end); //建树 inline bool MakeHuffTree(); private: //数组树的结构 HUFFTREE m_freq[512]; HUFFDATATYPE_EN *m_arry; HUFFDATATYPE_DES *m_outarry; int m_arryLen, m_AfterhufLen; short m_min_a, m_min_b; //std::string m_str[256]; short m_root; int m_freqCodeLen[256]; bool *m_freqCode[256]; };
#include "JPEG.h" #include "crc32.h" #include <assert.h> std::ofstream fwhrsenderr("C:\\WhrSendErr.TXT"); std::ofstream fwhrrecverr("C:\\WhrRecvErr.TXT"); std::ofstream ftreeSend("C:\\sendTree.TXT"); //A Mod B=A-(A div B) * B #define MOD(x, n) (x - ((x >> n) << n)) JPEG::JPEG(BYTE *data, int row, int col, int pixel) { assert(data != NULL && row > 0 && col > 0 && pixel > 0); m_pixel = pixel, m_row = row, m_col = col; m_data = data; m_send_data = NULL; } JPEG::JPEG(JPEGSENDDATA *data) { assert(data != NULL); m_pixel = data->pixel, m_row = data->row, m_col = data->col; m_send_data = data; m_yTableFirstByte = data->m_yTableFirstByte; m_uTableFirstByte = data->m_uTableFirstByte; m_vTableFirstByte = data->m_vTableFirstByte; m_data = NULL; m_y = m_u = m_v = NULL; m_ySize = m_uSize = m_vSize = 0; m_yZcodeLen = m_uZcodeLen = m_vZcodeLen = 0; } JPEG::~JPEG() { if (m_y != NULL) delete [] m_y; if (m_u != NULL) delete [] m_u; if (m_v != NULL) delete [] m_v; } bool JPEG::RGBDataToYuv() { //示例: //RGB数据1....1 2....2 (1行8个1和8个2,共8行) // ............... // ............... // 1....1 2....2 //分割后为1...........................1 2..................2(连续64个1和连续64个2) //yr 8 * 8 int yc = m_col + MOD(m_col, 3); int yr = m_row + MOD(m_row, 3); m_ySize = yc * yr; //r, c扩展 int row = (m_row + MOD(m_row, 4)); int col = (m_col + MOD(m_col, 4)); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; m_uSize = m_ySize;//uc * ur; int vc = uc = yc, vr = ur = yr; m_vSize = m_uSize; //m_y = new BYTE[m_ySize]; //m_u = new BYTE[m_uSize]; //m_v = new BYTE[m_vSize]; m_y = new int[m_ySize]; m_u = new int[m_uSize]; m_v = new int[m_vSize]; assert(m_y != NULL || m_u != NULL || m_v != NULL); //memset(m_y, 0, m_ySize); //memset(m_u, 0, m_uSize); //memset(m_v, 0, m_vSize ); memset(m_y, 0, m_ySize<<2); memset(m_u, 0, m_uSize<<2); memset(m_v, 0, m_vSize<<2); //y方向级数增加y % 8 == 0递增 int yBlock = yc << 3; int yBase = 0; int uBase = 0; int uBlock = yBlock >> 1; int pos = 0; for (int i = 0; i < m_row; ++i) { yBase = (i >> 3) * yBlock; uBase = (i >> 4) * uBlock; int yTiBase = MOD((i << 3), 6); int uTiBase = MOD(((i >> 1) << 3), 6); for (int j = 0; j < m_col; ++j, pos++) { //(j / 8) * 64 //int R = (int)m_data[pos++]; //int G = (int)m_data[pos++]; //int B = (int)m_data[pos]; int B = (int)m_data[pos++]; int G = (int)m_data[pos++]; int R = (int)m_data[pos++]; //int y = ((66*R+129*G+25*B+128)>>8)+16; /* if (y < 0) y = 0; else if (y > 255) y = 255;*/ int t = yBase + ((j >> 3)<<6) + MOD(j, 3) + yTiBase; m_y[t] = ((66*R+129*G+25*B+128)>>8)+16;///*(BYTE)*/y; //if (MOD(i, 1) == 0 && MOD(j, 1) == 0) //{ //(j / 16)*64 //int t = uBase + ((j >> 4)<<6) + MOD((j >> 1), 3) + uTiBase; //int u = ((-38*R-74*G+112*B+128)>>8)+128; /* if (u < 0) u = 0; else if (u > 255) u = 255;*/ //int v = ((112*R-94*G-18*B+128)>>8)+128; /* if (v < 0) v = 0; else if (v > 255) v = 255;*/ m_u[t] = ((-38*R-74*G+112*B+128)>>8)+128;///*(BYTE)*/u; m_v[t] = ((112*R-94*G-18*B+128)>>8)+128;///*(BYTE)*/v; //} } } return true; } bool JPEG::YuvDataToRGB() { //yr 8 * 8 int yc = m_col + MOD(m_col, 3); int yr = m_row + MOD(m_row, 3); //r, c扩展 int row = (m_row + MOD(m_row, 4)); int col = (m_col + MOD(m_col, 4)); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; int vc = uc = yc, vr = ur = yr; int size = m_row * m_col * m_pixel; if (m_data != NULL) delete [] m_data; m_data = NULL; m_data = new BYTE[size]; assert(m_data != NULL); memset(m_data, 0, size); //y方向级数增加y % 8 == 0递增 int pos = 0; int yBlock = yc << 3; int yBase = 0; int uBase = 0; int uBlock = yBlock >> 1; int R = 0,G = 0,B = 0, Y = 0, U = 0, V = 0; for (int i = 0; i < m_row; ++i) { // yBase = (i >> 3) * yBlock; uBase = (i >> 4) * uBlock; int yTiBase = MOD((i << 3), 6); int uTiBase = MOD(((i >> 1) << 3), 6); for (int j = 0; j < m_col; ++j, pos++) { //(j / 8) * 64 int t = yBase + ((j >> 3)<<6) + MOD(j, 3) + yTiBase; Y = (int)(m_y[t] - 16); //if (MOD(i, 1) == 0 && MOD(j, 1) == 0) //{ //(j / 16)*64 //int t = uBase + ((j >> 4)<<6) + MOD((j >> 1), 3) + uTiBase; U = (int)(m_u[t] - 128); V = (int)(m_v[t] - 128); //} Y *= 298; //m_data[pos++] = (BYTE)((Y+409*V+128)>>8);//R //m_data[pos++] = (BYTE)((Y-100*U-208*V+128)>>8);//G //m_data[pos] = (BYTE)((Y+516*U+128)>>8);//B R = ((Y+409*V+128)>>8); G = ((Y-100*U-208*V+128)>>8); B = ((Y+516*U+128)>>8); if (R < 0) R = 0; else if (R > 255) R = 255; if (G < 0) G = 0; else if (G > 255) G = 255; if (B < 0) B = 0; else if (B > 255) B = 255; m_data[pos++] = (BYTE)B;//B m_data[pos++] = (BYTE)G;//G m_data[pos++] =(BYTE)R; //R } } return true; } void JPEG::PrintY() { //yr 8 * 8 int yc = m_col + m_col % 8; int yr = m_row + m_row % 8; cout << "Y is :\n"; for (int i = 0; i < yr * yc; ++i) { if (i % 64 == 0) cout << endl; cout << int(m_y[i]) << "\t"; } cout << endl; } void JPEG::PrintU() { //r, c扩展 int row = (m_row + m_row % 16); int col = (m_col + m_col % 16); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; int vc = uc, vr = ur; cout << "U is :\n"; for (int i = 0; i < ur * uc; ++i) { if (i % 64 == 0) cout << endl; cout << int(m_u[i]) << "\t"; } cout << endl; } void JPEG::PrintV() { //r, c扩展 int row = (m_row + m_row % 16); int col = (m_col + m_col % 16); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; cout << "U is :\n"; for (int i = 0; i < ur * uc; ++i) { if (i % 64 == 0) cout << endl; cout << int(m_v[i]) << "\t"; } cout << endl; } void JPEG::PrintData() { cout << "Data is :\n"; for (int i = 0; i < m_row; ++i) { cout << endl; for (int j = 0; j < m_col * m_pixel; ++j) { cout << int(m_data[i * m_col * m_pixel + j]) << "\t"; } } cout << "\n"; } void JPEG::DCT(int *lpBuf) {//8 * 8离散余弦变换 int tp0, tp1, tp2, tp3, tp4, tp5, tp6, tp7; int tp10, tp11, tp12, tp13; int z1, z2, z3, z4, z5, z6; //对行运算 int *dataptr = lpBuf; for (int i = 0; i < 8; ++i) { tp0 = dataptr[0] + dataptr[7]; tp7 = dataptr[0] - dataptr[7]; tp1 = dataptr[1] + dataptr[6]; tp6 = dataptr[1] - dataptr[6]; tp2 = dataptr[2] + dataptr[5]; tp5 = dataptr[2] - dataptr[5]; tp3 = dataptr[3] + dataptr[4]; tp4 = dataptr[3] - dataptr[4]; tp10 = tp0 + tp3; tp11 = tp1 + tp2; tp12 = tp1 - tp2; tp13 = tp0 - tp3; dataptr[0] = tp10 + tp11; dataptr[4] = (dataptr[0] >> 1) - tp11; //dataptr[4] = (dataptr[0] / 2) - tp11; /* 3 / 8 = 1 / 4 + 1 / 8 */ dataptr[6] = tp12 - (tp13 >> 2) - (tp13 >> 3); //dataptr[6] = tp12 - tp13 * 3 / 8; dataptr[2] = (dataptr[6] >> 2) + (dataptr[6] >> 3) + tp13; //dataptr[2] = dataptr[6] * 3 / 8 + tp13; z2 = tp6 + (tp5 >> 2) + (tp5 >> 3); z1 = tp5 - (z2 >> 1) - (z2 >> 3); //z2 = tp6 + (tp5 * 3 / 8); //z1 = tp5 - (z2 * 5 / 8); z3 = tp4 + z1; z4 = tp4 - z1; z5 = z2 - tp7; z6 = z2 + tp7; dataptr[7] = z3 - (z6 >> 3); //dataptr[7] = z3 - (z6 / 8); dataptr[5] = z4 + z5 - (z5 >> 3);/* 7/8 = 1 - 1/8 */ //dataptr[5] = z4 + z5 * 7 / 8; dataptr[3] = (dataptr[5] >> 1) - z5; //dataptr[3] = (dataptr[5] / 2) - z5; //dataptr[1] = (z3 >> 3) - z6; dataptr[1] = z6; //dataptr指向下一行 dataptr += 8; } //对列运算 dataptr = lpBuf; for (int i = 0; i < 8; ++i) { tp0 = dataptr[0] + dataptr[56]; tp7 = dataptr[0] - dataptr[56]; tp1 = dataptr[8] + dataptr[48]; tp6 = dataptr[8] - dataptr[48]; tp2 = dataptr[16] + dataptr[40]; tp5 = dataptr[16] - dataptr[40]; tp3 = dataptr[24] + dataptr[32]; tp4 = dataptr[24] - dataptr[32]; tp10 = tp0 + tp3; tp11 = tp1 + tp2; tp12 = tp1 - tp2; tp13 = tp0 - tp3; dataptr[0] = tp10 + tp11; dataptr[32] = (dataptr[0] >> 1) - tp11; //dataptr[32] = (dataptr[0] / 2) - tp11; /* 3 / 8 = 1 / 4 + 1 / 8 */ dataptr[48] = tp12 - (tp13 >> 2) - (tp13 >> 3); //dataptr[48] = tp12 - (tp13 * 3 / 8); dataptr[16] = (dataptr[48] >> 2) + (dataptr[48] >> 3) + tp13; //dataptr[16] = (dataptr[48] * 3 / 8) + tp13; z2 = tp6 + (tp5 >> 2) + (tp5 >> 3); z1 = tp5 - (z2 >> 1) - (z2 >> 3); //z2 = tp6 + (tp5 * 3 / 8); //z1 = tp5 - (z2 * 5 / 8); z3 = tp4 + z1; z4 = tp4 - z1; z5 = z2 - tp7; z6 = z2 + tp7; dataptr[56] = z3 - (z6 >> 3); //dataptr[56] = z3 - (z6 / 8); dataptr[40] = z4 + z5 - (z5 >> 3);/* 7/8 = 1 - 1/8 */ //dataptr[40] = z4 + z5 * 7 / 8;/* 7/8 = 1 - 1/8 */ dataptr[24] = (dataptr[40] >> 1) - z5; //dataptr[24] = (dataptr[40] / 2) - z5; //dataptr[8] = (z3 >> 3) - z6; dataptr[8] = z6; //dataptr指向下一行 dataptr++; } } void JPEG::TDCT(int *lpBuf) {//8 * 8离散反余弦变换 int t0, t1, t2, t3, t4, t5, t6, t7; int t10, t11, t12, t13; int z1, z2, z3, z4, z5; //列变换 30次加减法,20次移位 int * dataptr = lpBuf; for (int i = 0; i < 8; ++i) { t10 = (dataptr[0] >> 1) + dataptr[32]; t11 = dataptr[0] - t10; t13 = dataptr[16] - (dataptr[48] >> 2) - (dataptr[48] >> 3); t12 = dataptr[48] + (t13 >> 2) + (t13 >> 3); t1 = ((t11 + t12) >> 1); t2 = t11 - t1; t0 = ((t10 + t13) >> 1); t3 = t10 - t0; z3 = dataptr[56] + (dataptr[8] >> 3); z5 = (dataptr[40] >> 1) - dataptr[24]; z4 = dataptr[40] + z5 - (z5 >> 3); z2 = ((z5 + dataptr[8]) >> 1); t7 = dataptr[8] - z2; t4 = ((z3 + z4) >> 1); z1 = z3 - t4; t5 = z1 + (z2 >> 1) + (z2 >> 3); t6 = z2 - (t5 >> 2) - (t5 >> 3); dataptr[0] = ((t0 + t7) >> 1); dataptr[56]= t0 - dataptr[0]; dataptr[8] = ((t1 + t6) >> 1); dataptr[48]= t1 - dataptr[8]; dataptr[16]= ((t2 + t5) >> 1); dataptr[40]= t2 - dataptr[16]; dataptr[24]= ((t3 + t4) >> 1); dataptr[32]= t3 - dataptr[24]; dataptr++; } //行变换 dataptr = lpBuf; for (int i = 0; i < 8; ++i) { t10 = (dataptr[0] >> 1) + dataptr[4]; t11 = dataptr[0] - t10; t13 = dataptr[2] - (dataptr[6] >> 2) - (dataptr[6] >> 3); t12 = dataptr[6] + (t13 >> 2) + (t13 >> 3); t1 = ((t11 + t12) >> 1); t2 = t11 - t1; t0 = ((t10 + t13) >> 1); t3 = t10 - t0; z3 = dataptr[7] + (dataptr[1] >> 3); z5 = (dataptr[5] >> 1) - dataptr[3]; z4 = dataptr[5] + z5 - (z5 >> 3); z2 = ((z5 + dataptr[1]) >> 1); t7 = dataptr[1] - z2; t4 = ((z3 + z4) >> 1); z1 = z3 - t4; t5 = z1 + (z2 >> 1) + (z2 >> 3); t6 = z2 - (t5 >> 2) - (t5 >> 3); dataptr[0] = ((t0 + t7) >> 1); dataptr[7]= t0 - dataptr[0]; dataptr[1] = ((t1 + t6) >> 1); dataptr[6]= t1 - dataptr[1]; dataptr[2]= ((t2 + t5) >> 1); dataptr[5]= t2 - dataptr[2]; dataptr[3]= ((t3 + t4) >> 1); dataptr[4]= t3 - dataptr[3]; dataptr += 8; } } void JPEG::DispatchDCT() { JPEG::RGBDataToYuv(); int i = 0; for (; i < m_uSize; i += 64) { DCT(m_y + i); DCT(m_u + i); DCT(m_v + i); } for (;i < m_ySize; i+=64) DCT(m_y + i); JPEG::Quantize(); JPEG::Zcode(m_y, m_ySize, m_yZcodeLen); JPEG::Zcode(m_u, m_uSize, m_uZcodeLen); JPEG::Zcode(m_v, m_vSize, m_vZcodeLen); JPEG::HuffmanCompress(); } void JPEG::DispatchTDCT() { JPEG::HuffmanDesCompress(); JPEG::TZcode(m_y, m_ySize, m_yZcodeLen); JPEG::TZcode(m_u, m_uSize, m_uZcodeLen); JPEG::TZcode(m_v, m_vSize, m_vZcodeLen); JPEG::TQuantize(); int i = 0; fidct_init(); for (; i < m_uSize; i += 64) { TDCT(m_y + i); TDCT(m_u + i); TDCT(m_v + i); } for (;i < m_ySize; i+=64) TDCT(m_y + i); JPEG::YuvDataToRGB(); } bool JPEG::DispatchDCT2() { JPEG::RGBDataToYuv(); //取消与外面数据关联 m_data = NULL; int i = 0; for (; i < m_uSize; i += 64) { fdct(m_y + i); fdct(m_u + i); fdct(m_v + i); //JPEG::fast_fdct(m_y + i); //JPEG::fast_fdct(m_u + i); //JPEG::fast_fdct(m_v + i); } for (;i < m_ySize; i+=64) fdct(m_y + i); //JPEG::fast_fdct(m_y + i); //{ // std::ofstream couty("C:\\outyz.txt"); // for (int j = 0; j < m_ySize; ++j) // couty << m_y[j] << " "; // std::ofstream coutu("C:\\outuz.txt"); // for (int j = 0; j < m_uSize; ++j) // coutu << m_u[j] << " "; // std::ofstream coutv("C:\\outvz.txt"); // for (int j = 0; j < m_vSize; ++j) // coutv << m_v[j] << " "; //} JPEG::Quantize(); //{ // std::ofstream couty("C:\\see_who_in_Zcode.txt"); // couty << "Y IN"; //} //CRC32 cr32; if (!JPEG::Zcode(m_y, m_ySize, m_yZcodeLen))/* goto _ERR;*/ { /*std::ofstream couty("C:\\see_who_in_Zcode.txt"); couty << "u IN";*/ fwhrsenderr << "Zcode in YYYY\t"; goto _ERR; } if (!JPEG::Zcode(m_u, m_uSize, m_uZcodeLen))// goto _ERR; { //std::ofstream couty("C:\\see_who_in_Zcode.txt"); //couty << "v IN"; fwhrsenderr << "Zcode in UUUU\t"; goto _ERR; } if (!JPEG::Zcode(m_v, m_vSize, m_vZcodeLen)) //goto _ERR; { fwhrsenderr << "Zcode in VVVV\t"; goto _ERR; } //{ // std::ofstream couty("C:\\outy.txt"); // for (int j = 0; j < m_yZcodeLen; ++j) // couty << m_y[j] << " "; // std::ofstream coutu("C:\\outu.txt"); // for (int j = 0; j < m_uZcodeLen; ++j) // coutu << m_u[j] << " "; // std::ofstream coutv("C:\\outv.txt"); // for (int j = 0; j < m_vZcodeLen; ++j) // coutv << m_v[j] << " "; //} //{ // m_yZcodeLen = m_ySize; // m_uZcodeLen = m_uSize; // m_vZcodeLen = m_vSize; // JPEG::NotHaveHuffman(); //} if (!JPEG::HuffmanCompress())/* goto _ERR;*/ { fwhrsenderr << "HuffmanCompress\t"; goto _ERR; } // //m_send_data->crc32 = cr32.GetCRC32(m_send_data->m_data, m_send_data->dataLen); int crc32 = 0; for (int i = 0; i < m_send_data->dataLen; ++i) { crc32 += m_send_data->m_data[i]; if (crc32 > 23456 || crc32 < -23456) crc32 = crc32 % 23456; } m_send_data->crc32 = crc32; /* std::ofstream ct("C:\\out_t.txt"); for (int j = 0; j < 64 * 5; ++j) ct << m_y[j] << "\t";*/ //std::ofstream ct("C:\\out_t.txt"); //for (int k = 0; k < m_yZcodeLen; ++k) // if (m_y[k] >= 128 || m_y[k] < -128) // /*MessageBoxA(NULL, "catch", "catch", MB_OK);*/ // ct << "catch" << "\t"; //for (int k = 0; k < m_uZcodeLen; ++k) // if (m_u[k] >= 128 || m_u[k] < -128) // //MessageBoxA(NULL, "catch", "catch", MB_OK); // ct << "catch" << "\t"; //// ct << m_u[k]; //for (int k = 0; k < m_vZcodeLen; ++k) // if (m_v[k] >= 128 || m_v[k] < -128) // //MessageBoxA(NULL, "catch", "catch", MB_OK); // ct << "catch" << "\t"; // ct << m_v[k]; return true; _ERR: if (m_y != NULL) delete [] m_y; m_y = NULL; if (m_u != NULL) delete [] m_u; m_u = NULL; if (m_v != NULL) delete [] m_v; m_v = NULL; return false; } bool JPEG::DispatchTDCT2() { //std::ofstream ct("C:\\out2_t.txt"); //for (int j = 0; j < 64 * 5; ++j) // ct << m_y[j] << "\t"; //CRC32 cr32; //int crc32 = cr32.GetCRC32(m_send_data->m_data, m_send_data->dataLen); int crc32 = 0; int huflen = sizeof(HUFFTREE)*512*3; if ((m_send_data->uHufLen+m_send_data->yHufLen+m_send_data->vHufLen+huflen) != m_send_data->dataLen) { fwhrrecverr << "datalen err\n"; return false; } for (int i = 0; i < m_send_data->dataLen; ++i) { crc32 += m_send_data->m_data[i]; if (crc32 > 23456 || crc32 < -23456) crc32 = crc32 % 23456; } if (crc32 != m_send_data->crc32) { fwhrrecverr << "\ncrc32 err\n"; return false; } //return false; //JPEG::InitJpegData(); if (!JPEG::HuffmanDesCompress()) //goto _ERR; { fwhrrecverr << "HuffmanDesCompress\t"; goto _ERR; } //{ // std::ofstream cty("C:\\out2y_t.txt"); // for (int j = 0; j < m_yZcodeLen; ++j) // cty << m_y[j] << " "; // std::ofstream ctu("C:\\out2u_t.txt"); // for (int j = 0; j < m_uZcodeLen; ++j) // ctu << m_u[j] << " "; // std::ofstream ctv("C:\\out2v_t.txt"); // for (int j = 0; j < m_vZcodeLen; ++j) // ctv << m_v[j] << " "; //} //{ // std::ofstream couty("C:\\see_who_in_Zcode.txt"); // couty << "Y IN"; //} if (!JPEG::TZcode(m_y, m_ySize, m_yZcodeLen))// goto _ERR; { fwhrrecverr << "Tzcode YYY\t"; goto _ERR; } //{ // std::ofstream couty("C:\\see_who_in_Zcode.txt"); // couty << "u IN"; //} if (!JPEG::TZcode(m_u, m_uSize, m_uZcodeLen)) //goto _ERR; { fwhrrecverr << "Tzcode UUU\t"; goto _ERR; } //{ // std::ofstream couty("C:\\see_who_in_Zcode.txt"); // couty << "v IN"; //} if (!JPEG::TZcode(m_v, m_vSize, m_vZcodeLen)) //goto _ERR; { fwhrrecverr << "Tzcode VVV\t"; goto _ERR; } JPEG::TQuantize(); //{ // std::ofstream cty("C:\\out2yz_t.txt"); // for (int j = 0; j < m_ySize; ++j) // cty << m_y[j] << " "; // std::ofstream ctu("C:\\out2uz_t.txt"); // for (int j = 0; j < m_uSize; ++j) // ctu << m_u[j] << " "; // std::ofstream ctv("C:\\out2vz_t.txt"); // for (int j = 0; j < m_vSize; ++j) // ctv << m_v[j] << " "; //} int i = 0; fidct_init(); for (; i < m_uSize; i += 64) { fidct(m_y + i); fidct(m_u + i); fidct(m_v + i); //ctv << i << "\t"; } for (;i < m_ySize; i+=64) fidct(m_y + i); JPEG::YuvDataToRGB(); //JPEG::AjustGB(); return true; _ERR: if (m_y != NULL) delete [] m_y; m_y = NULL; if (m_u != NULL) delete [] m_u; m_u = NULL; if (m_v != NULL) delete [] m_v; m_v = NULL; return false; } void JPEG::fidct(int * block) { static int *blk; static long i; static long X0, X1, X2, X3, X4, X5, X6, X7, X8; for (i = 0; i < 8; i++) /* idct rows */ { blk = block + (i << 3); if (!((X1 = blk[4] << 11) | (X2 = blk[6]) | (X3 = blk[2]) | (X4 = blk[1]) | (X5 = blk[7]) | (X6 = blk[5]) | (X7 = blk[3]))) { blk[0] = blk[1] = blk[2] = blk[3] = blk[4] = blk[5] = blk[6] = blk[7] = blk[0] << 3; continue; } 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 -= X1; X1 = W6 * (X3 + X2); X2 = X1 - (W2 + W6) * X2; X3 = X1 + (W2 - W6) * X3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; /* third stage */ X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181 * (X4 + X5) + 128) >> 8; X4 = (181 * (X4 - X5) + 128) >> 8; /* fourth stage */ blk[0] = (int) ((X7 + X1) >> 8); blk[1] = (int) ((X3 + X2) >> 8); blk[2] = (int) ((X0 + X4) >> 8); blk[3] = (int) ((X8 + X6) >> 8); blk[4] = (int) ((X8 - X6) >> 8); blk[5] = (int) ((X0 - X4) >> 8); blk[6] = (int) ((X3 - X2) >> 8); blk[7] = (int) ((X7 - X1) >> 8); } /* end for ( i = 0; i < 8; ++i ) IDCT-rows */ for (i = 0; i < 8; i++) /* idct columns */ { blk = block + i; /* shortcut */ if (! ((X1 = (blk[32] << 8)) | (X2 = blk[48]) | (X3 = blk[16]) | (X4 = blk[8]) | (X5 = blk[56]) | (X6 = blk[40]) | (X7 = blk[24]))) { blk[0] = blk[8] = blk[16] = blk[24] = blk[32] = blk[40] = blk[48] = blk[56] = iclp[(blk[0] + 32) >> 6]; continue; } X0 = (blk[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 -= X1; X1 = W6 * (X3 + X2) + 4; X2 = (X1 - (W2 + W6) * X2) >> 3; X3 = (X1 + (W2 - W6) * X3) >> 3; X1 = X4 + X6; X4 -= X6; X6 = X5 + X7; X5 -= X7; /* third stage */ X7 = X8 + X3; X8 -= X3; X3 = X0 + X2; X0 -= X2; X2 = (181 * (X4 + X5) + 128) >> 8; X4 = (181 * (X4 - X5) + 128) >> 8; /* fourth stage */ blk[0] = iclp[(X7 + X1) >> 14]; blk[8] = iclp[(X3 + X2) >> 14]; blk[16] = iclp[(X0 + X4) >> 14]; blk[24] = iclp[(X8 + X6) >> 14]; blk[32] = iclp[(X8 - X6) >> 14]; blk[40] = iclp[(X0 - X4) >> 14]; blk[48] = iclp[(X3 - X2) >> 14]; blk[56] = iclp[(X7 - X1) >> 14]; } } void JPEG::fidct_init() { int i; iclp = iclip + 512; for (i = -512; i < 512; i++) iclp[i] = (i < -256) ? -256 : ((i > 255) ? 255 : i); } void JPEG::fdct(int *block) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; int z1, z2, z3, z4, z5; int *blkptr; int *dataptr; int data[64]; int i; /* Pass 1: process rows. */ /* Note results are scaled up by sqrt(8) compared to a true DCT; */ /* furthermore, we scale the results by 2**PASS1_BITS. */ dataptr = data; blkptr = block; for (i = 0; i < 8; i++) { tmp0 = (int)(blkptr[0] + blkptr[7]); tmp7 = (int)(blkptr[0] - blkptr[7]); tmp1 = (int)(blkptr[1] + blkptr[6]); tmp6 = (int)(blkptr[1] - blkptr[6]); tmp2 = (int)(blkptr[2] + blkptr[5]); tmp5 = (int)(blkptr[2] - blkptr[5]); tmp3 = (int)(blkptr[3] + blkptr[4]); tmp4 = (int)(blkptr[3] - blkptr[4]); tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = (tmp10 + tmp11) << PASS1_BITS; dataptr[4] = (tmp10 - tmp11) << PASS1_BITS; z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[2] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS - PASS1_BITS); dataptr[6] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS - PASS1_BITS); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[7] = DESCALE(tmp4 + z1 + z3, CONST_BITS - PASS1_BITS); dataptr[5] = DESCALE(tmp5 + z2 + z4, CONST_BITS - PASS1_BITS); dataptr[3] = DESCALE(tmp6 + z2 + z3, CONST_BITS - PASS1_BITS); dataptr[1] = DESCALE(tmp7 + z1 + z4, CONST_BITS - PASS1_BITS); dataptr += 8; /* advance pointer to next row */ blkptr += 8; } /* Pass 2: process columns. * We remove the PASS1_BITS scaling, but leave the results scaled up * by an overall factor of 8. */ dataptr = data; for (i = 0; i < 8; i++) { tmp0 = dataptr[0] + dataptr[56]; tmp7 = dataptr[0] - dataptr[56]; tmp1 = dataptr[8] + dataptr[48]; tmp6 = dataptr[8] - dataptr[48]; tmp2 = dataptr[16] + dataptr[40]; tmp5 = dataptr[16] - dataptr[40]; tmp3 = dataptr[24] + dataptr[32]; tmp4 = dataptr[24] - dataptr[32]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = DESCALE(tmp10 + tmp11, PASS1_BITS); dataptr[32] = DESCALE(tmp10 - tmp11, PASS1_BITS); z1 = (tmp12 + tmp13) * FIX_0_541196100; dataptr[16] = DESCALE(z1 + tmp13 * FIX_0_765366865, CONST_BITS + PASS1_BITS); dataptr[48] = DESCALE(z1 + tmp12 * (-FIX_1_847759065), CONST_BITS + PASS1_BITS); z1 = tmp4 + tmp7; z2 = tmp5 + tmp6; z3 = tmp4 + tmp6; z4 = tmp5 + tmp7; z5 = (z3 + z4) * FIX_1_175875602; /* sqrt(2) * c3 */ tmp4 *= FIX_0_298631336; /* sqrt(2) * (-c1+c3+c5-c7) */ tmp5 *= FIX_2_053119869; /* sqrt(2) * ( c1+c3-c5+c7) */ tmp6 *= FIX_3_072711026; /* sqrt(2) * ( c1+c3+c5-c7) */ tmp7 *= FIX_1_501321110; /* sqrt(2) * ( c1+c3-c5-c7) */ z1 *= -FIX_0_899976223; /* sqrt(2) * (c7-c3) */ z2 *= -FIX_2_562915447; /* sqrt(2) * (-c1-c3) */ z3 *= -FIX_1_961570560; /* sqrt(2) * (-c3-c5) */ z4 *= -FIX_0_390180644; /* sqrt(2) * (c5-c3) */ z3 += z5; z4 += z5; dataptr[56] = DESCALE(tmp4 + z1 + z3, CONST_BITS + PASS1_BITS); dataptr[40] = DESCALE(tmp5 + z2 + z4, CONST_BITS + PASS1_BITS); dataptr[24] = DESCALE(tmp6 + z2 + z3, CONST_BITS + PASS1_BITS); dataptr[8] = DESCALE(tmp7 + z1 + z4, CONST_BITS + PASS1_BITS); dataptr++; /* advance pointer to next column */ } /* descale */ for (i = 0; i < 64; i++) block[i] = (int)DESCALE(data[i], 3); } void JPEG::Quantize() { const int std_y_qt[64] = { 16,11,10,16,24,40,51,61, 12,12,14,19,26,58,60,55, 14,13,26,24,40,57,69,56, 14,17,22,29,51,87,80,62, 18,22,37,56,68,109,103,77, 24,35,55,64,81,104,113,92, 49,64,78,87,103,121,120,101, 72,92,95,98,112,100,103,99 }; const int std_cr_qt[64] = { 17,18,24,47,99,99,99,99, 18,21,26,66,99,99,99,99, 24,26,56,99,99,99,99,99, 47,66,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99 }; int i = 0; int t = 0; m_yTableFirstByte = m_y[0]; m_uTableFirstByte = m_u[0]; m_vTableFirstByte = m_v[0]; for (; i < m_uSize; ++i) { t = MOD(i, 6); if (t != 0) { m_y[i] /= std_y_qt[t]; m_u[i] /= std_cr_qt[t]; m_v[i] /= std_cr_qt[t]; } else { m_y[i] -= m_yTableFirstByte; m_y[i] = m_y[i] >> 4; m_u[i] -= m_uTableFirstByte; m_u[i] = m_u[i] >> 4; m_v[i] -= m_vTableFirstByte; m_v[i] = m_v[i] >> 4; } } for (; i < m_ySize; ++i) { t = MOD(i, 6); if (t != 0) m_y[i] /= std_y_qt[t]; else { m_y[i] -= m_yTableFirstByte; m_y[i] = m_y[i] >> 4; } } //std::ofstream cout("C:\\out.txt"); //for (int j = 0; j < 64 * 5; ++j) // cout << m_y[j] << "\t"; } void JPEG::TQuantize() { const int std_y_qt[64] = { 16,11,10,16,24,40,51,61, 12,12,14,19,26,58,60,55, 14,13,26,24,40,57,69,56, 14,17,22,29,51,87,80,62, 18,22,37,56,68,109,103,77, 24,35,55,64,81,104,113,92, 49,64,78,87,103,121,120,101, 72,92,95,98,112,100,103,99 }; const int std_cr_qt[64] = { 17,18,24,47,99,99,99,99, 18,21,26,66,99,99,99,99, 24,26,56,99,99,99,99,99, 47,66,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99, 99,99,99,99,99,99,99,99 }; int i = 0; int t = 0; for (; i < m_uSize; ++i) { t = MOD(i, 6); if (t != 0) { m_y[i] *= std_y_qt[t]; m_u[i] *= std_cr_qt[t]; m_v[i] *= std_cr_qt[t]; } else { m_y[i] = m_y[i] << 4; m_y[i] += m_yTableFirstByte; m_u[i] = m_u[i] << 4; m_u[i] += m_uTableFirstByte; m_v[i] = m_v[i] << 4; m_v[i] += m_vTableFirstByte; } } for (; i < m_ySize; ++i) { t = MOD(i, 6); if (t != 0) m_y[i] *= std_y_qt[t]; else { m_y[i] = m_y[i] << 4; m_y[i] += m_yTableFirstByte; } } } //bool JPEG::Zcode(int *lpBuf, const int &bufSize, int &zcodeLen) //{//lpBuf 取m_y, m_u, m_v; bufSize 取 m_ySize, m_uSize, m_vSize; // //zcodeLen 取 m_yZcodeLen, m_uZcodeLen, m_vZcodelen // if (lpBuf == NULL) return false; // if (bufSize <= 64) return true; // const int pos[64] = { // 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 // }; // // zcodeLen = 0; // int temp[64*2]; // int i = 0; ////////////////// //// 单独处理头64字节数据 // for (int zero = 0; i < 64; ++i) // { // if (lpBuf[pos[i]] != 0) //|| zero == 15) // {//Z编码到行程编码 // if (zero < 0 || zero > 63) return false; // temp[zcodeLen++] = zero; // temp[zcodeLen++] = lpBuf[pos[i]]; // zero = 0; // } // else zero++; // } // //写入结束符 // temp[zcodeLen++] = 0; // temp[zcodeLen++] = 0; // memcpy(lpBuf, temp, (zcodeLen*sizeof(int))); ////////////////////// // for (; i < bufSize; i += 64) // { // for (int j = 0, zero = 0; j < 64; ++j) // { // if (lpBuf[pos[j]+i] != 0)// || zero == 15) // {//Z编码到行程编码 // if (zero < 0 || zero > 63) return false; // lpBuf[zcodeLen++] = zero; // lpBuf[zcodeLen++] = lpBuf[pos[j]+i]; // //if (zcodeLen >= bufSize) return; // zero = 0; // } // else zero++; // } // //写入结束符 // lpBuf[zcodeLen++] = 0; // lpBuf[zcodeLen++] = 0; // } // //zcodeLen--; // return true; //} // //bool JPEG::TZcode(int *&lpBuf, const int &bufSize, int &zcodeLen) //{//lpBuf 取m_y, m_u, m_v; bufSize 取 m_ySize, m_uSize, m_vSize; // //zcodeLen 取 m_yZcodeLen, m_uZcodeLen, m_vZcodelen // if(lpBuf == NULL || bufSize <= 0 || zcodeLen <= 0) // return false; // const int pos[64] = { // 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 *outBuf = new int[bufSize]; // if (outBuf == NULL) return false; // memset(outBuf, 0, bufSize*sizeof(int)); // int zcodepos = 0; // for (int i = 0; i < bufSize && zcodepos < zcodeLen; i += 64) // { // for (int curpos = 0; zcodepos < zcodeLen; zcodepos += 2, ++curpos) // { // //1个64字节块结束 // if (lpBuf[zcodepos] == 0 && lpBuf[zcodepos+1] == 0) // { zcodepos += 2; break;} // curpos += lpBuf[zcodepos]; // if(curpos < 0 || curpos > 63) // { // fwhrrecverr << "curpos < 0 || curpos > 63\t"; // delete [] outBuf; // outBuf = NULL; // return false; // } // outBuf[ i + pos[curpos] ] = lpBuf[zcodepos + 1]; // }//for_curpos // }//for_i // delete [] lpBuf; // lpBuf = outBuf; // outBuf = NULL; // return true; //} // bool JPEG::Zcode(int *&lpBuf, const int &bufSize, int &zcodeLen) {//lpBuf 取m_y, m_u, m_v; bufSize 取 m_ySize, m_uSize, m_vSize; //zcodeLen 取 m_yZcodeLen, m_uZcodeLen, m_vZcodelen if (lpBuf == NULL || bufSize <= 0) return false; const int pos[64] = { 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 tpLen = bufSize * 2; int *outBuf = new int[tpLen]; if (outBuf == NULL) return false; zcodeLen = 0; int temp[64*64]; int i = 0; //////////////// // 单独处理头64字节数据 for (int zero = 0; i < 64; ++i) { if (lpBuf[pos[i]] != 0) //|| zero == 15) {//Z编码到行程编码 if (zero < 0 || zero > 63) return false; temp[zcodeLen++] = zero; temp[zcodeLen++] = lpBuf[pos[i]]; zero = 0; } else zero++; } //写入结束符 temp[zcodeLen++] = 0; temp[zcodeLen++] = 0; if (zcodeLen+2 >= tpLen) { tpLen = zcodeLen + 4096; int *tpret = new int[tpLen]; memcpy(tpret, temp, (zcodeLen*sizeof(int))); delete [] outBuf; outBuf = tpret; tpret = NULL; } else memcpy(outBuf, temp, (zcodeLen*sizeof(int))); //////////////////// for (; i < bufSize; i += 64) { for (int j = 0, zero = 0; j < 64 && (i + j < bufSize); ++j) { if (lpBuf[pos[j]+i] != 0)// || zero == 15) {//Z编码到行程编码 if (zero < 0 || zero > 63) { delete [] outBuf; outBuf = NULL; return false; } outBuf[zcodeLen++] = zero; outBuf[zcodeLen++] = lpBuf[pos[j]+i]; if (zcodeLen+2 >= tpLen) { tpLen = zcodeLen + 4096; int *tpret = new int[tpLen]; memcpy(tpret, outBuf, zcodeLen * sizeof(int)); delete [] outBuf; outBuf = tpret; tpret = NULL; } //if (zcodeLen >= bufSize) return; zero = 0; } else zero++; } //写入结束符 outBuf[zcodeLen++] = 0; outBuf[zcodeLen++] = 0; } //zcodeLen--; delete [] lpBuf; lpBuf = outBuf; outBuf = NULL; return true; } bool JPEG::TZcode(int *&lpBuf, const int &bufSize, int &zcodeLen) {//lpBuf 取m_y, m_u, m_v; bufSize 取 m_ySize, m_uSize, m_vSize; //zcodeLen 取 m_yZcodeLen, m_uZcodeLen, m_vZcodelen if(lpBuf == NULL || bufSize <= 0 || zcodeLen <= 0) return false; const int pos[64] = { 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 *outBuf = new int[bufSize]; if (outBuf == NULL) return false; memset(outBuf, 0, bufSize*sizeof(int)); int zcodepos = 0; for (int i = 0; i < bufSize && zcodepos < zcodeLen; i += 64) { for (int curpos = 0; zcodepos < zcodeLen; zcodepos += 2, ++curpos) { //1个64字节块结束 if (lpBuf[zcodepos] == 0 && lpBuf[zcodepos+1] == 0) { zcodepos += 2; break;} curpos += lpBuf[zcodepos]; if(curpos < 0 || curpos > 63) { fwhrrecverr << "curpos < 0 || curpos > 63\t" << "pos = " << zcodeLen << "\t"; delete [] outBuf; outBuf = NULL; return false; } outBuf[ i + pos[curpos] ] = lpBuf[zcodepos + 1]; }//for_curpos }//for_i delete [] lpBuf; lpBuf = outBuf; outBuf = NULL; return true; } JPEGSENDDATA * JPEG::ReturnSendData() { //JPEG::DispatchDCT(); if (!JPEG::DispatchDCT2()) { fwhrsenderr << "JPEG::DispatchDCT2()\t"; return NULL; } return m_send_data; } BYTE * JPEG::ReturnData() { //JPEG::DispatchTDCT(); if (!JPEG::DispatchTDCT2()) /*return NULL;*/ { fwhrrecverr << "JPEG::DispatchTDCT2()\t"; return NULL; } return m_data; } bool JPEG::HuffmanCompress() { int ty = m_yZcodeLen, tu = m_uZcodeLen, tv = m_vZcodeLen; //int crctree_y,crctree_u,crctree_v; BYTE *rety = NULL;BYTE *retu = NULL;BYTE *retv = NULL; int huflen = 0, data_len = 0, freqstart = 0; HUFFTREE * treey = NULL,* treeu = NULL,* treev = NULL; HUFFMAN hufy(m_y, m_yZcodeLen); HUFFMAN hufu(m_u, m_uZcodeLen); HUFFMAN hufv(m_v, m_vZcodeLen); if (!hufy.HuffCode(rety, m_yZcodeLen)) { fwhrsenderr << "!hufy.HuffCode(rety, m_yZcodeLen)\t"; goto _ERR; } //hufy.CounTreeCrc(crctree_y); //for (int j = 0; j < 64 * 5; ++j) // cout << (int)rety[j] << "\t"; if (!hufu.HuffCode(retu, m_uZcodeLen)) { fwhrsenderr << "!hufu.HuffCode(retu, m_uZcodeLen)\t"; goto _ERR; } //hufu.CounTreeCrc(crctree_u); if (!hufv.HuffCode(retv, m_vZcodeLen)) { fwhrsenderr << "!hufv.HuffCode(retv, m_vZcodeLen)\t"; goto _ERR; } //if (m_data != NULL) delete [] m_data; //hufv.CounTreeCrc(crctree_v); huflen = sizeof(HUFFTREE)*512; data_len = m_yZcodeLen + m_uZcodeLen + m_vZcodeLen + huflen+huflen+huflen; m_data = new BYTE[data_len]; if (m_data == NULL) { fwhrsenderr << "m_data == NULL\t"; goto _ERR; } memcpy(m_data, rety, m_yZcodeLen); delete [] rety; rety = NULL; memcpy(m_data + m_yZcodeLen, retu, m_uZcodeLen); delete [] retu; retu = NULL; memcpy(m_data + m_yZcodeLen + m_uZcodeLen, retv, m_vZcodeLen); delete [] retv; retv = NULL; freqstart = m_yZcodeLen + m_uZcodeLen + m_vZcodeLen; if (!hufy.ReturnHuffTree(treey)) { fwhrsenderr << "!hufy.ReturnHuffTree(treey)\t"; goto _ERR; } memcpy(m_data + freqstart, treey, huflen); delete [] treey;treey=NULL; if (!hufu.ReturnHuffTree(treeu)) { fwhrsenderr << "!hufy.ReturnHuffTree(treey)\t"; goto _ERR; } memcpy(m_data + freqstart + huflen, treeu, huflen); delete [] treeu;treeu=NULL; if (!hufv.ReturnHuffTree(treev)) { fwhrsenderr << "!hufy.ReturnHuffTree(treey)\t"; goto _ERR; } memcpy(m_data + freqstart + huflen + huflen, treev, huflen); delete [] treev;treev=NULL; m_send_data = new JPEGSENDDATA; if (m_send_data == NULL) { fwhrsenderr << "m_send_data == NULL\t"; goto _ERR; } m_send_data->col = m_col; m_send_data->dataLen = data_len; m_send_data->m_data = m_data; m_send_data->m_yTableFirstByte = m_yTableFirstByte; m_send_data->m_uTableFirstByte = m_uTableFirstByte; m_send_data->m_vTableFirstByte = m_vTableFirstByte; m_data = NULL; m_send_data->pixel = m_pixel; m_send_data->row = m_row; m_send_data->uHufLen = m_uZcodeLen; m_send_data->vHufLen = m_vZcodeLen; m_send_data->yHufLen = m_yZcodeLen; m_send_data->yZcodeLen = ty; m_send_data->uZcodeLen = tu; m_send_data->vZcodeLen = tv; //m_send_data->hufftreeCrc32_y = crctree_y; //m_send_data->hufftreeCrc32_u = crctree_u; //m_send_data->hufftreeCrc32_v = crctree_v; return true; _ERR: if (rety != NULL) delete [] rety; rety = NULL; if (retu != NULL) delete [] retu; retu = NULL; if (retv != NULL) delete [] retv; retv = NULL; if (m_data != NULL) delete [] m_data; m_data = NULL; if (m_send_data != NULL) delete m_send_data; m_send_data = NULL; if (treey != NULL)delete [] treey;treey=NULL; if (treeu != NULL)delete [] treeu;treeu=NULL; if (treev != NULL)delete [] treev;treev=NULL; return false; } bool JPEG::HuffmanDesCompress() { //if (m_send_data->m_data != NULL) delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //if (m_send_data != NULL) delete [] m_send_data; //m_send_data = NULL; //return false; /* std::ofstream cout("C:\\out2.txt"); for (int j = 0; j < 64 * 5; ++j) cout << m_y[j] << "\t";*/ if (m_send_data == NULL) { fwhrrecverr << "m_send_data == NULL\t"; return false; } if (m_send_data->m_data == NULL) { //delete m_send_data; //m_send_data = NULL; fwhrrecverr << "m_send_data->m_data == NULL\t"; return false; } //yr 8 * 8 int yc = m_col + MOD(m_col, 3); int yr = m_row + MOD(m_row, 3); //r, c扩展 int row = (m_row + MOD(m_row, 4)); int col = (m_col + MOD(m_col, 4)); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; uc = yc, ur = yr; int freqstart = m_send_data->yHufLen + m_send_data->uHufLen + m_send_data->vHufLen; int hufftreeLen = sizeof(HUFFTREE)<<9; BYTE *y = (BYTE *)m_send_data->m_data ; if (y == NULL || m_send_data->m_data == NULL) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "y == NULL || m_send_data->m_data == NULL\t"; return false; } //for (int j = 0; j < 64 * 5; ++j) // /*ct << (int)y[j] << "\t";*/ // int kk = (int)y[j]; HUFFMAN hufy(y, m_send_data->yZcodeLen+1, (BYTE *)m_send_data->m_data+ freqstart, m_send_data->yHufLen); //int crctree = 0; //hufy.CounTreeCrc(crctree); //if (crctree != m_send_data->hufftreeCrc32_y) //{ // hufy.PrintSendTree(); //} if (!hufy.HuffDesCode(m_y)) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "(!hufy.HuffDesCode(m_y)\t"; return false; } //////////////////////////////////////////////////////////////////////////////////////// y = (BYTE *)m_send_data->m_data + m_send_data->yHufLen; if (y == NULL ||(m_send_data->m_data+ freqstart+hufftreeLen) == NULL) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "y == NULL ||(m_send_data->m_data+ freqstart+hufftreeLen) == NULL\t"; return false; } HUFFMAN hufu(y, m_send_data->uZcodeLen+1, (BYTE *)m_send_data->m_data+ freqstart+hufftreeLen, m_send_data->uHufLen); //crctree = 0; //hufu.CounTreeCrc(crctree); //if (crctree != m_send_data->hufftreeCrc32_u) //{ // hufu.PrintSendTree(); //} if (!hufu.HuffDesCode(m_u)) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "!hufu.HuffDesCode(m_u)\t"; return false; } //////////////////////////////////////////////////////////////////////////////////////// y = (BYTE *)m_send_data->m_data + m_send_data->yHufLen + m_send_data->uHufLen; if (y == NULL || (m_send_data->m_data+ freqstart+hufftreeLen+hufftreeLen) == NULL) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "y == NULL || (m_send_data->m_data+ freqstart+hufftreeLen+hufftreeLen) == NULL\t"; return false; } HUFFMAN hufv(y, m_send_data->vZcodeLen+1, (BYTE *)m_send_data->m_data+ freqstart+hufftreeLen+hufftreeLen, m_send_data->vHufLen); //crctree = 0; //hufv.CounTreeCrc(crctree); //if (crctree != m_send_data->hufftreeCrc32_v) //{ // hufv.PrintSendTree(); //} if (!hufv.HuffDesCode(m_v)) { //delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //delete [] m_send_data; //m_send_data = NULL; fwhrrecverr << "!hufv.HuffDesCode(m_v)\t"; return false; } ///////////////////////////////////////////////////// //{ // std::ofstream ct("C:\\out2y_t.txt"); // for (int j = 0; j < m_send_data->yZcodeLen; ++j) // ct << m_y[j] << " "; // std::ofstream ct("C:\\out2u_t.txt"); // for (int j = 0; j < m_send_data->uZcodeLen; ++j) // ct << m_u[j] << " "; // std::ofstream ct("C:\\out2v_t.txt"); // for (int j = 0; j < m_send_data->vZcodeLen; ++j) // ct << m_v[j] << " "; //} m_ySize = yc * yr; m_uSize = uc * ur; m_vSize = m_uSize; m_yZcodeLen = m_send_data->yZcodeLen; m_uZcodeLen = m_send_data->uZcodeLen; m_vZcodeLen = m_send_data->vZcodeLen; //if (m_send_data->m_data != NULL) delete [] m_send_data->m_data; //m_send_data->m_data = NULL; //if (m_send_data != NULL) delete [] m_send_data; //m_send_data = NULL; return true; } void JPEG::fast_fdct(int *block) { const int DCTSIZE = 8; int tmp0, tmp1, tmp2, tmp3, tmp4,tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12,tmp13; int z1, z2, z3, z4, z5, z11,z13; int *dataptr; int ctr; dataptr = block; for (ctr = DCTSIZE-1; ctr>= 0; ctr--) { tmp0 = dataptr[0] + dataptr[7]; tmp7 = dataptr[0] - dataptr[7]; tmp1 = dataptr[1] + dataptr[6]; tmp6 = dataptr[1] - dataptr[6]; tmp2 = dataptr[2] + dataptr[5]; tmp5 = dataptr[2] - dataptr[5]; tmp3 = dataptr[3] + dataptr[4]; tmp4 = dataptr[3] - dataptr[4]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[0] = tmp10 + tmp11; dataptr[4] = tmp10 - tmp11; z1 = int((tmp12 + tmp13) * (0.707106781)); dataptr[2] = tmp13 + z1; dataptr[6] = tmp13 - z1; tmp10 = tmp4 + tmp5; tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; z5 = int((tmp10 - tmp12) * (0.382683433)); z2 = int((0.541196100) * tmp10 + z5); z4 = int((1.306562965) * tmp12 + z5); z3 = int(tmp11 * (0.707106781)); z11 = tmp7 +z3; z13 = tmp7 - z3; dataptr[5] = z13 + z2; dataptr[3] = z13 - z2; dataptr[1] = z11 + z4; dataptr[7] = z11 - z4; dataptr +=DCTSIZE; } dataptr = block; for (ctr = DCTSIZE-1; ctr>= 0; ctr--) { tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7]; tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7]; tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6]; tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6]; tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5]; tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5]; tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4]; tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4]; tmp10 = tmp0 + tmp3; tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; dataptr[DCTSIZE*0] = tmp10 + tmp11; dataptr[DCTSIZE*4] = tmp10 - tmp11; z1 = int((tmp12 + tmp13) * ( 0.707106781)); dataptr[DCTSIZE*2] = tmp13 + z1; dataptr[DCTSIZE*6] = tmp13 - z1; tmp10 = tmp4 + tmp5; tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; z5 = int((tmp10 - tmp12) * ( 0.382683433)); z2 = int(( 0.541196100) * tmp10 + z5); z4 = int(( 1.306562965) * tmp12 + z5); z3 = int(tmp11 * ( 0.707106781)); z11 = tmp7 +z3; z13 = tmp7 - z3; dataptr[DCTSIZE*5] = z13 + z2; dataptr[DCTSIZE*3] = z13 - z2; dataptr[DCTSIZE*1] = z11 + z4; dataptr[DCTSIZE*7] = z11 - z4; dataptr++; } } void JPEG::NotHaveHuffman() { m_send_data = new JPEGSENDDATA; assert(m_send_data != NULL); m_send_data->dataLen = m_yZcodeLen+m_uZcodeLen+m_vZcodeLen; m_send_data->m_data = new BYTE[m_send_data->dataLen]; assert(m_send_data->m_data != NULL); int pos = 0; for (int i = 0; i < m_yZcodeLen; ++i) m_send_data->m_data[pos++]=BYTE(m_y[i]); for (int i = 0; i < m_uZcodeLen; ++i) m_send_data->m_data[pos++]=BYTE(m_u[i]); for (int i = 0; i < m_vZcodeLen; ++i) m_send_data->m_data[pos++]=BYTE(m_v[i]); m_send_data->pixel = m_pixel; m_send_data->row = m_row; m_send_data->col = m_col; m_send_data->yZcodeLen = m_yZcodeLen; m_send_data->uZcodeLen = m_uZcodeLen; m_send_data->vZcodeLen = m_vZcodeLen; m_send_data->yHufLen = m_yZcodeLen; m_send_data->uHufLen = m_uZcodeLen; m_send_data->vHufLen = m_vZcodeLen; m_send_data->m_yTableFirstByte = m_yTableFirstByte; m_send_data->m_uTableFirstByte = m_uTableFirstByte; m_send_data->m_vTableFirstByte = m_vTableFirstByte; } void JPEG::InitJpegData() { //m_col = m_send_data->col; //m_row = m_send_data->row; //m_pixel = m_send_data->pixel; m_yZcodeLen = m_send_data->yZcodeLen; m_uZcodeLen = m_send_data->uZcodeLen; m_vZcodeLen = m_send_data->vZcodeLen; //m_yTableFirstByte = m_send_data->m_yTableFirstByte; //m_uTableFirstByte = m_send_data->m_uTableFirstByte; //m_vTableFirstByte = m_send_data->m_vTableFirstByte; //yr 8 * 8 int yc = m_col + MOD(m_col, 3); int yr = m_row + MOD(m_row, 3); //r, c扩展 int row = (m_row + MOD(m_row, 4)); int col = (m_col + MOD(m_col, 4)); //u, v 16 * 16 int uc = col >> 1; int ur = row >> 1; uc = yc, ur = yr; m_ySize = yc * yr; m_uSize = uc * ur; m_vSize = m_uSize; m_y = new int[m_yZcodeLen]; assert(m_y != NULL); m_u = new int[m_uZcodeLen]; assert(m_u != NULL); m_v = new int[m_vZcodeLen]; assert(m_v != NULL); int pos = 0; for (int i = 0; i < m_yZcodeLen; ++i) m_y[i] = int(char(m_send_data->m_data[pos++])); for (int i = 0; i < m_uZcodeLen; ++i) m_u[i] = int(char(m_send_data->m_data[pos++])); for (int i = 0; i < m_vZcodeLen; ++i) m_v[i] = int(char(m_send_data->m_data[pos++])); delete [] m_send_data->m_data; m_send_data->m_data = NULL; delete m_send_data; m_send_data = NULL; } void JPEG::AjustGB() { int lb = 0, lg = 0, rb = 0, rg = 0; //for (int i = 4; i < m_col-4; i += 4) // if (MOD(i,1) == 0) // {//bgra // lb = m_data[i-4]; // lg = m_data[i-3]; // rb = m_data[i+4]; // rg = m_data[i+5]; // m_data[i+1] // m_data[i] = ((lb + rb)>>1);//b // m_data[i+1] = ((lg + rg)>>1); // } //对列整理 int startpos = 0, colByte = ((m_col*m_pixel)<<1); for (int i = 0; i < m_row; i += 2) { for (int j = 4; j< colByte-4; j += 4) { lb = m_data[j + startpos-4]; lg = m_data[j + startpos-3]; rb = m_data[j + startpos+4]; rg = m_data[j + startpos+5]; m_data[j + startpos] = ((lb + rb)>>1);//b m_data[j + startpos+1] = ((lg + rg)>>1);//r }//for_j startpos += colByte; }//for_i //行列整理 //startpos = m_col*m_pixel, colByte = ((m_col*m_pixel)<<1); //int upb = 0, upg = 0, downb = 0, downg = 0, one_col_byte = startpos; //for (int i = 0; i < m_row-2; i += 2) //{ // for (int j = 0; j< one_col_byte; j += 4) // { // upb = m_data[startpos + j - one_col_byte]; // downb = m_data[startpos + j + one_col_byte]; // upg = m_data[startpos + j + 1- one_col_byte]; // downg = m_data[startpos + j + 1 + one_col_byte]; // m_data[startpos + j] = ((upb+downb)<<1); // m_data[startpos + j + 1] = ((upg+downg)<<1); // }//for_j // startpos += colByte; //}//for_i } ///////////////////////////////////////// class of HUFFMAN //////////////////////////////////////////////////////////////////// HUFFMAN::HUFFMAN(HUFFDATATYPE_EN *arry, int size) {//arry要加压的数据,size加压数据的大小 assert(arry != NULL && size > 0); m_arry = arry; m_arryLen = size; m_root = 0; //memset(m_freqCode, NULL, (sizeof(bool)<<8)); const int initChild = 520; for (short i = 0; i < 512; ++i) { m_freq[i].in_tree = false; m_freq[i].lchild = initChild; m_freq[i].parent = 0; m_freq[i].rchild = initChild; m_freq[i].weight = 0; } for (short i = 0; i < 256; ++i) { m_freqCode[i] = NULL; m_freqCodeLen[i] = 0; } } HUFFMAN::HUFFMAN(HUFFDATATYPE_DES *arry, int size, HUFFDATATYPE_DES *hufftr, int hufLen) {//m_arryLen = size 是解压后的文件的长度,arry是要解压的程序,hufftr是加压时的huffman树 //root是huffman树的根,hufLen数据HUFFMAN压缩后的长度 assert(arry != NULL && size > 0 && hufftr != NULL && hufLen > 0); m_outarry = arry; m_arryLen = size; m_AfterhufLen = hufLen; for (short i = 0; i < 256; ++i) m_freqCode[i] = NULL; memcpy((BYTE*)m_freq, hufftr, (sizeof(HUFFTREE)<<9)); for (short i = 0; i < 512; ++i) if (m_freq[i].parent == 0 && m_freq[i].weight > 0/* && m_freq[i].in_tree*/) m_root = i; } HUFFMAN::~HUFFMAN() { for (int i = 0; i < 256; ++i) if (m_freqCode[i] != NULL) { delete [] m_freqCode[i]; m_freqCode[i] = NULL; } } bool HUFFMAN::MakeHuffTree() { for (int i = 0; i < m_arryLen; ++i) m_freq[ BYTE(m_arry[i]) ].weight++; short end = 256; for (short i = 0; i < 256; ++i, end++) { HUFFMAN::MakeMinPair(end); if (m_min_a == -1 || m_min_b == -1) break; m_freq[m_min_a].parent = m_freq[m_min_b].parent = end; m_freq[end].weight = m_freq[m_min_a].weight + m_freq[m_min_b].weight; if (m_freq[m_min_a].weight > m_freq[m_min_b].weight) { short tp_min = m_min_a; m_min_a = m_min_b; m_min_b = tp_min; } m_freq[end].lchild = m_min_a ; m_freq[end].rchild =m_min_b; m_freq[m_min_a].in_tree = m_freq[m_min_b].in_tree = true; } for (short i = 0; i < 256; ++i) { std::string str; short t = i; bool bIn = false; while (m_freq[t].parent != 0) { bIn = true; short tp = t; t = m_freq[t].parent; //左0 右 1 if (m_freq[t].lchild == tp) str += '0'; else str += '1'; } //reverse(m_str[i], m_str[i] + m_str[i].size()); if (bIn) { m_freqCodeLen[i] = (int)str.size(); m_freqCode[i] = new bool[m_freqCodeLen[i]]; for (int j = 0; j < m_freqCodeLen[i]; ++j) if (str[m_freqCodeLen[i]-1-j] == '0') m_freqCode[i][j] = false; else m_freqCode[i][j] = true; } }//for_i return true; } void HUFFMAN::MakeMinPair(const short &end) { m_min_a = -1, m_min_b = -1; int wei_a = 2147483647, wei_b = 2147483647; for (short i = 0; i < end; ++i) { if (!m_freq[i].in_tree && m_freq[i].weight > 0) {//a first, b next if (wei_a > m_freq[i].weight) { wei_b = wei_a; m_min_b = m_min_a; wei_a = m_freq[i].weight; m_min_a = i; } else if (wei_b > m_freq[i].weight) { wei_b = m_freq[i].weight; m_min_b = i; } }//if_m_freq }//for_i } //std::ofstream cout_in_htree("C:\\in_htree.txt"); //std::ofstream cout_in_data("C:\\in_data.txt"); bool HUFFMAN::HuffCode(BYTE *&ret, int &ret_pos) { if (!HUFFMAN::MakeHuffTree()) return false; //{ // // for (int j = 0; j < 256; ++j) // { // cout_in_htree << j << "is :" << m_str[j] << "\n"; // cout_in_data << m_arry[j] << "\t"; // } // cout_in_htree << "\n\n\n\n\n\n\n=============================\n\n\n==========================\n\n\n\n"; // cout_in_data<< "\n\n\n\n\n\n\n=============================\n\n\n==========================\n\n\n\n"; //} unsigned char bit1[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };//置1 unsigned char bit0[8] = { 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0xFE };//置0 ret = new BYTE[m_arryLen]; if (ret == NULL) return false; ret_pos = 0; int k = 0, strpos = 0; BYTE c; int allocSize = m_arryLen; for (int i = 0; i < m_arryLen; ++i) { c = BYTE(m_arry[i]); for (strpos = 0; strpos < m_freqCodeLen[c]; strpos++) { if (m_freqCode[c][strpos]) ret[ret_pos] |= bit1[k++]; else ret[ret_pos] &= bit0[k++]; if (k == 8) { k = 0; ret_pos++; if (ret_pos >= allocSize) { allocSize = ret_pos + 4096; BYTE *retp = new BYTE[allocSize]; if (retp == NULL) { delete [] ret; ret = NULL; return false; } memcpy(retp, ret, sizeof(BYTE) * ret_pos); delete [] ret; ret = retp; retp = NULL; } } }//while_k }//for_i if (k > 0) ret_pos++; return true; } //std::ofstream cout_hufftree("C:\\out_huftree.txt"); bool HUFFMAN::HuffDesCode(HUFFDATATYPE_EN *&ret) { //HUFFMAN::MakeHuffTree(); //{ // for (short i = 0; i < 256; ++i) // { // short t = i; // while (m_freq[t].parent != 0) // { // short tp = t; // t = m_freq[t].parent; // //左0 右 1 // if (m_freq[t].lchild == tp) m_str[i] += '0'; // else m_str[i] += '1'; // } // //reverse(m_str[i], m_str[i] + m_str[i].size()); // int len = m_str[i].size(); // int halt_len = len >> 1; // len--; // for (int j = 0; j < halt_len; ++j) // { // char c = m_str[i][j]; // m_str[i][j] = m_str[i][len-j]; // m_str[i][len-j] = c; // } // }//for_i // for (int j = 0; j < 256; ++j) // cout_hufftree << j << "is :" << m_str[j] << "\n"; // cout_hufftree << "\n\n\n\n\n\n\n=============================\n\n\n==========================\n\n\n\n"; //} unsigned char bit1[8] = { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };//置1 ret = new HUFFDATATYPE_EN[m_arryLen]; if (ret == NULL) return false; //try //{ int pos = 0, k = 0; for (int i = 0; i < m_arryLen; ++i) { unsigned short t = m_root; while (true) { //测试位是否为0,左0 右 1 //test = /*unsigned char(*/m_outarry[pos]/*)*/ & bit1[k++]; //if (test == 0) t = m_freq[t].lchild; //else t = m_freq[t].rchild; if ((m_outarry[pos] & bit1[k]) == bit1[k]) t = m_freq[t].rchild; else t = m_freq[t].lchild; k++; if (k == 8) { k = 0; pos++; if (pos > m_AfterhufLen) { return true; if (ret != NULL) delete [] ret; ret = NULL; return false; } } if (t < 256) break;//叶子是小于256的,打在叶子上就是结果了 } ret[i] = HUFFDATATYPE_EN(char(t)); }//for_i return true; //} //catch (...) //{ // if (ret != NULL) delete [] ret; // ret = NULL; // return false; //} //std::ofstream ct("C:\\out2_t.txt"); //for (int j = 0; j < 64 * 5; ++j) // ct << ret[j] << "\t"; } bool HUFFMAN::ReturnHuffTree(HUFFTREE * &hufftr) {//返回huffman的树和根 if (hufftr != NULL) delete [] hufftr; hufftr = new HUFFTREE[512]; if (hufftr == NULL) return false; memcpy(hufftr, m_freq, sizeof(HUFFTREE) * 512); return true; } void HUFFMAN::PrintSendTree() { for (int i = 0; i < 256; ++i) { ftreeSend << "i=" << i << "\tw=" << m_freq[i].weight << "\tpar=" << m_freq[i].weight <<"\tlch=" << m_freq[i].lchild << "\trch=" << m_freq[i].rchild << "\tin_tree="; if (m_freq[i].in_tree) ftreeSend << "true\n"; else ftreeSend << "false\n"; } } //void HUFFMAN::PrintSendTree() //{ // for (int i = 0; i < 256; ++i) // { // ftreeSend << "i=" << i << "\tw=" << m_freq[i].weight << "\tpar=" // << m_freq[i].weight <<"\tlch=" << m_freq[i].lchild << "\trch=" << m_freq[i].rchild // << "\tin_tree="; // if (m_freq[i].in_tree) ftreeSend << "true\n"; // else ftreeSend << "false\n"; // } //} void HUFFMAN::CounTreeCrc(int &ret) { ret = 0; for (int i = 0; i < 256; ++i) { ret = m_freq[i].weight+m_freq[i].lchild+m_freq[i].rchild+m_freq[i].parent; if (m_freq[i].in_tree) ++ret; if (ret > 200000 || ret < -200000) ret %= 200000; } }
使用 输入 32位BMP数据部分,使用 GetBitmapBits ;获得BMP数据部分 struct BITMAPDATA {//BMP格式数据消息头 WORD bitCount;//单位像素包含BYTE数 DWORD bitWid, bitHei;//图片以像素为单位的宽和高 }; BITMAPDATA lp; BYTE *lpBitmapData = NULL; //函数见下面 GetBmpBits(lp.bitCount, lp.bitWid, lp.bitHei, lpBitmapData); JPEG jpeg(lpBitmapData, lp.bitHei, lp.bitWid, lp.bitCount); JPEGSENDDATA *sendJpeg = jpeg.ReturnSendData();//压缩后的数据保存于sendJpeg bool GetBmpBits(WORD &pixelBytes, DWORD &width, DWORD &height, BYTE *&lpMemBitmapBits) {////获取当前屏幕为BMP数据返回 //采样 BITMAP bm; HBITMAP hBit = GetScreenToHBitmap(); //OpenClipboard(NULL); //EmptyClipboard(); //SetClipboardData(CF_BITMAP, hBit); //CloseClipboard(); GetObjectW(hBit, sizeof(bm), (LPSTR)&bm); //DWORD dwBitCount = 32; //32位图 pixelBytes = bm.bmBitsPixel / 8; DWORD bmpWidth = (bm.bmWidth * bm.bmBitsPixel + bm.bmBitsPixel - 1) / bm.bmBitsPixel; DWORD dwBitmapSize = bmpWidth * bm.bmHeight * pixelBytes; width = bm.bmWidth; height= bm.bmHeight; if (dwBitmapSize <= 0 || pixelBytes <= 0 || bmpWidth <= 0) return false; lpMemBitmapBits = new BYTE[dwBitmapSize]; if (lpMemBitmapBits == NULL) return false; GetBitmapBits(hBit, dwBitmapSize, lpMemBitmapBits); BYTE *tp = new BYTE[dwBitmapSize]; DWORD bits = bmpWidth * pixelBytes; //数据倒置,BMP数据特点 for (LONG i = 0, j = bm.bmHeight - 1; i < bm.bmHeight; ++i, --j) { memcpy((tp + i * bits), (lpMemBitmapBits + j * bits), bits); } delete [] lpMemBitmapBits; lpMemBitmapBits = tp; /////////////////////////////////////////////// //std::ofstream file3("c:\\out1.txt");// //for (int i = 0; i < width * 8; ++i) //{ // file3 << int(lpMemBitmapBits[i]) << " "; // if (i %width == 0) file3 << "\r\n"; //} ////////////////////////////////////////////// tp = NULL; DeleteObject(hBit); return true; } 解压: JPEG jpeg(recvJpeg); //将JPEG格式的数据转换为BMP数据格式 BYTE *bitmapdata = jpeg.ReturnData();
简单说明
压缩步骤:
1 颜色转换(采样ARGB->YUV采用1:1:1比例)
2 DCT变换(快速离散余弦变换)
3 量化 (采用JPEG标准量化表)
4 Z编码
5 使用DPCM对直流系数(DC)进行编码(只是对第一个8*8子块首位作偏差)
6 AC 使用RLE编码
7 标准HUFFMAN 编码,进一步压缩
颜色转换
原RGB数据(注:1为 1,1,1结构, 2 为 2,2,2结构):
11111111 22222222
11111111 22222222
11111111 22222222
11111111 22222222
11111111 22222222
11111111 22222222
11111111 22222222
11111111 22222222
分割后(注:1为 1,2 为 2):
Y,U,V数组表都为:
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 22222222 22222222 22222222 22222222 22222222 22222222 22222222 22222222 22222222
参考:
http://www.ibm.com/developerworks/cn/linux/l-cn-jpeg
http://fengyezufeng.blog.163.com/blog/static/96771294200961722445725