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;
}

 

posted on 2017-09-15 14:54  kenny.wmh  阅读(408)  评论(1编辑  收藏  举报

导航