Simple16 字符压缩
#define S16_NUMSIZE 16 #define S16_BITSSIZE 28 #define Simple16_Mask 0x7FFFFFFF extern int S16_NUM[]; extern int S16_NUMOFF[]; extern int S16_BITS[16][28]; class Simple16 { public: static int* Compress(int * pnIn, int nLen, int * pnLenOut); static void Decompress(int * pnIn, int nLen, sgi::vector<unsigned int>& outVec); static int* Decompress(int * pnIn, int nLen, int * pnLenOut); private: static int S16CompresShort(int out[], int outOffset, short in[], int inOffset, int n); static int S16Compress(int out[], int outOffset, int in[], int inOffset, int n); static int ReadBitsForS16(int in[], int inIntOffset, int inWithIntOffset, int bits); static int S16Decompress(int out[], int outOffset, int in[], int inOffset, int n); static int S16Decompress(sgi::vector<unsigned int>& outVec, int outOffset, int in[], int inOffset, int n); static int S16DecompressShort(short out[], int outOffset, int in[], int inOffset, int n); static int* CompressShort(short * pnIn, int nLen, int * pnLenOut); static short* DecompressShort(int * pnIn, int nLen, int * pnLenOut); };
int S16_NUM[] = { 28, 21, 21, 21, 14, 9, 8, 7, 6, 6, 5, 5, 4, 3, 2, 1 }; int S16_NUMOFF[] = { 15, 14, 13, 12, 10, 8, 7, 6, 5, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; int S16_BITS[16][28] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0 }, { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 4, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 3, 4, 4, 4, 4, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 5, 5, 5, 5, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 4, 4, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 6, 6, 6, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 5, 5, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 10, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; int Simple16::S16CompresShort(int out[], int outOffset, short in[], int inOffset, int n) { int numIdx = 0, j = 0, num = 0, bits = 0; for (numIdx = 0; (numIdx < S16_NUMSIZE); numIdx++) { out[outOffset] = numIdx << S16_BITSSIZE; num = (S16_NUM[numIdx] < n) ? S16_NUM[numIdx] : n; for (j = 0, bits = 0; (j < num) && in[inOffset + j] < (1 << S16_BITS[numIdx][j]);) { out[outOffset] |= (in[inOffset + j] << bits); bits += S16_BITS[numIdx][j]; j++; } if (j == num) { return num; } } return -1; } /** * Compress an integer array using Simple16 * * @param out the compressed output * @param outOffset the offset of the output in the number of integers * @param in the integer input array * @param inOffset the offset of the input in the number of integers * @param n the number of elements to be compressed * @return the number of compressed integers */ int Simple16::S16Compress(int out[], int outOffset, int in[], int inOffset, int n ) { int numIdx = 0, j = 0, num = 0, bits = 0; int mi = 1; unsigned int id = 0u; for (j = 0, bits = 0; j < n; j++) { id = in[inOffset + j]; mi = 1; if (id == 0) { bits++; } else { if ((id >> 16) == 0) { mi = mi + 16; id = id << 16; } if ((id >> 24) == 0) { mi = mi + 8; id = id << 8; } if ((id >> 28) == 0) { mi = mi + 4; id = id << 4; } if ((id >> 30) == 0) { mi = mi + 2; id = id << 2; } bits += (32 - mi + (id >> 31)); } if (bits > S16_BITSSIZE) { break; } } numIdx = S16_NUMOFF[j - 1]; for (; (numIdx < S16_NUMSIZE); numIdx++) { out[outOffset] = numIdx << S16_BITSSIZE; num = (S16_NUM[numIdx] < n) ? S16_NUM[numIdx] : n; for (j = 0, bits = 0; (j < num) && in[inOffset + j] < (1 << S16_BITS[numIdx][j]);) { out[outOffset] |= (in[inOffset + j] << bits); bits += S16_BITS[numIdx][j]; j++; } if (j == num) { return num; } } return -1; } /** * Read a certain number of bits of a integer on the input array * @param in the input array * @param inIntOffset the start offset in ints in the input array * @param inWithIntOffset the start offset within a int in the input array * @param bits the number of bits to be read * @return the bits bits of the input */ int Simple16::ReadBitsForS16(int in[], int inIntOffset, int inWithIntOffset, int bits) { // 正整数不需要考虑 补0 的问题 int nVal = (in[inIntOffset] >> inWithIntOffset); if (nVal < 0) nVal &= 0x7FFFFFFF; return nVal & ((0xffffffff >> (32 - bits)) & 0x7FFFFFFF); } /** * Decompress an integer array using Simple16 * * @param out the decompressed output * @param outOffset the offset of the output in the number of integers * @param in the compressed input array * @param inOffset the offset of the input in the number of integers * @param n the number of elements to be compressed * @return the number of processed integers */ int Simple16::S16Decompress(int out[], int outOffset, int in[], int inOffset, int n) { int numIdx, j = 0, bits = 0; int num; numIdx = (in[inOffset] >> S16_BITSSIZE) & (Simple16_Mask >> (S16_BITSSIZE - 1)); num = S16_NUM[numIdx] < n ? S16_NUM[numIdx] : n; for (j = 0, bits = 0; j < num; j++) { out[outOffset + j] = ReadBitsForS16(in, inOffset, bits, S16_BITS[numIdx][j]); bits += S16_BITS[numIdx][j]; } return num; } int Simple16::S16Decompress(sgi::vector<unsigned int>& outVec, int outOffset, int in[], int inOffset, int n) { int numIdx, j = 0, bits = 0; int num; numIdx = (in[inOffset] >> S16_BITSSIZE) & (Simple16_Mask >> (S16_BITSSIZE - 1)); num = S16_NUM[numIdx] < n ? S16_NUM[numIdx] : n; for (j = 0, bits = 0; j < num; j++) { outVec[outOffset + j] = ReadBitsForS16(in, inOffset, bits, S16_BITS[numIdx][j]); bits += S16_BITS[numIdx][j]; } return num; } int Simple16::S16DecompressShort(short out[], int outOffset, int in[], int inOffset, int n) { int numIdx, j = 0, bits = 0; int num; numIdx = (in[inOffset] >> S16_BITSSIZE) & (Simple16_Mask >> (S16_BITSSIZE - 1)); num = S16_NUM[numIdx] < n ? S16_NUM[numIdx] : n; for (j = 0, bits = 0; j < num; j++) { out[outOffset + j] = ReadBitsForS16(in, inOffset, bits, S16_BITS[numIdx][j]); bits += S16_BITS[numIdx][j]; } return num; } int* Simple16::Decompress(int * pnIn, int nLen, int * pnLenOut) { int * pnRes = NULL; *pnLenOut = 0; if (NULL == pnIn || nLen <= 0) return pnRes; { int nNum = 0; int nNumLeft = nLen; int nOutOffset = 0; int nInOffset = 0; int nLenTemp = sizeof(int) * nLen; //int * pnResTemp = NULL; pnRes = (int*)malloc(nLenTemp); //memset(pnRes, 0, nLenTemp); for (nNumLeft = nLen; nNumLeft > 0; nNumLeft -= nNum) { nNum = S16Decompress(pnRes, nOutOffset, pnIn, nInOffset, nNumLeft); nOutOffset += nNum; nInOffset++; } *pnLenOut = nInOffset; } return pnRes; } void Simple16::Decompress(int * pnIn, int nLen, sgi::vector<unsigned int>& outVec) { if (NULL == pnIn || nLen <= 0) return; { int nNum = 0; int nNumLeft = nLen; int nInOffset = 0; int nOutOffset = 0; //outVec.clear(); outVec.resize(nLen); for (nNumLeft = nLen; nNumLeft > 0; nNumLeft -= nNum) { nNum = S16Decompress(outVec, nOutOffset, pnIn, nInOffset, nNumLeft); nOutOffset += nNum; nInOffset++; } } } int* Simple16::Compress(int * pnIn, int nLen, int * pnLenOut) { int * pnRes = NULL; *pnLenOut = 0; if (NULL == pnIn || nLen <= 0) return pnRes; { int nNum = 0; int nNumLeft = nLen; int nOutOffset = 0; int nInOffset = 0; int nLenTemp = sizeof(int)* nLen; // int * pnResTemp = NULL; pnRes = (int*)malloc(nLenTemp); //memset(pnRes, 0, nLenTemp); for (nNumLeft = nLen; nNumLeft > 0; nNumLeft -= nNum) { nNum = S16Compress(pnRes, nOutOffset, pnIn, nInOffset, nNumLeft); nOutOffset++; nInOffset += nNum; } *pnLenOut = nOutOffset; // nLenTemp = sizeof(int)* nOutOffset; // pnResTemp = (int*)malloc(nLenTemp); // memset(pnResTemp, 0, nLenTemp); // // memcpy(pnResTemp, pnRes, nLenTemp); // free(pnRes); // pnRes = pnResTemp; return pnRes; } return pnRes; } int* Simple16::CompressShort(short * pnIn, int nLen, int * pnLenOut) { int * pnRes = NULL; *pnLenOut = 0; if (NULL == pnIn || nLen <= 0) return pnRes; { int nNum = 0; int nNumLeft = nLen; int nOutOffset = 0; int nInOffset = 0; int nLenTemp = sizeof(int)* nLen; int * pnResTemp = NULL; pnRes = (int*)malloc(nLenTemp); memset(pnRes, 0, nLenTemp); for (nNumLeft = nLen; nNumLeft > 0; nNumLeft -= nNum) { nNum = S16CompresShort(pnRes, nOutOffset, pnIn, nInOffset, nNumLeft); nOutOffset++; nInOffset += nNum; } *pnLenOut = nOutOffset; nLenTemp = sizeof(int)* nOutOffset; pnResTemp = (int*)malloc(nLenTemp); memset(pnResTemp, 0, nLenTemp); memcpy(pnResTemp, pnRes, nLenTemp); free(pnRes); pnRes = pnResTemp; } return pnRes; } short* Simple16::DecompressShort(int * pnIn, int nLen, int * pnLenOut) { short * pnRes = NULL; *pnLenOut = 0; if (NULL == pnIn || nLen <= 0) return pnRes; { int nNum = 0; int nNumLeft = nLen; int nOutOffset = 0; int nInOffset = 0; int nLenTemp = sizeof(short)* nLen; //int * pnResTemp = NULL; pnRes = (short*)malloc(nLenTemp); memset(pnRes, 0, nLenTemp); for (nNumLeft = nLen; nNumLeft > 0; nNumLeft -= nNum) //while ( nInOffset < nLen) { nNum = S16DecompressShort(pnRes, nOutOffset, pnIn, nInOffset, nNumLeft); nOutOffset += nNum; nInOffset++; } *pnLenOut = nInOffset; //nLenTemp = sizeof(short)* nOutOffset; //pnResTemp = MM_MALLOC(nLenTemp); //MEMSET(pnResTemp, 0, nLenTemp); //MEMCPY(pnResTemp, pnRes, nLenTemp); //MM_FREEIF(pnRes); //pnRes = pnResTemp; } return pnRes; }