行程码压缩算法

来源:互联网 发布:奶茶店市场调查数据 编辑:程序博客网 时间:2024/05/16 01:37

行程码压缩算法原理参考以下链接

http://www.cnblogs.com/hwl1023/p/5129696.html


以下为具体实现:

1、原始RLE方法

给出的数据序列为:A-A-A-A-A-B-B-C-D

未压缩前:A-A-A-A-A-B-B-C-D

(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44)

压缩后:5-A-2-B-1-C-1-D

(0x05-0x41-0x02-0x42-0x01-0x43-0x01-0x44)

/* Compress inBuf to outBuf * Input: *  inSize:  input buf size *  inBuf:  input buf, need compress *  outSize: output buf size, reality outSize <= 2*inSize, but suggest outSize = 2*inSize * Output: *  outBuf: compressed buf address * Return: *  0:  Err, input para fault *  1:  Err, outSize < reality compressed buf size *  >= 2: Succ, reality used compressed buf size * * List: A-A-A-A-A-B-B-C-D * Before: A-A-A-A-A-B-B-C-D * (0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44) * Compressed: 5-A-2-B-1-C-1-D * (0x05-0x41-0x02-0x42-0x01-0x43-0x01-0x44)*/#define RLE_MAX_NUM    0xFFint RLE_Compress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf){int i=0, j=0;    int rptNum = 0;    if(inSize<=0 || outSize<=0) return 0;    if(!inBuf || !outBuf) return 0;rptNum = 1;    for(i=0; i outSize-2) goto done;outBuf[j++] = rptNum;outBuf[j++] = inBuf[i];rptNum = 1;        }else{            if(rptNum == RLE_MAX_NUM){                if(j > outSize-2) goto done;                outBuf[j++] = RLE_MAX_NUM;                outBuf[j++] = inBuf[i];                rptNum = 0;            }            rptNum++;                    }    }    if(rptNum > 0){if(j > outSize-2) goto done;outBuf[j++] = rptNum;        outBuf[j++] = inBuf[i++];}done:    printf("RLE_Compress: inSize=%d, inLen=%d, outSize=%d, cmpSize=%d\n",           inSize, i, outSize, j);    if(i != inSize)        return 1;    else        return j;}/* uncompress data * Input: *  inSize      compressed data size *  inBuf       compressed data buf *  outSize     uncompress data buf size * Output: *  outBuf      uncompress data buf address *  inLen       reality use'd compressed data size * Return: *  <=  0       failure *  >   0       success, reality uncompress data size*/int RLE_UnCompress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf, int *inLen){    int i=0, j=0;int len, sign;    if(inSize <= 0 || outSize <= 0) return -1;    if(!inBuf || !outBuf) return -1;    *inLen = 0;    for(i=0; i 0){            if(len+j > outSize){break;}            memset(outBuf+j, sign, len);            j += len;        }else{                break;        }    }    *inLen = i;    printf("RLE_UnCompress: inSize=%d inLen=%d, outSize=%d unCmpSize=%d\n", inSize, i, outSize, j);    return j;}int RLE_test(){int size1, size2;    unsigned char src[]={0x0, 0x13, 0x65, 0x95, 0x65, 0x49, 0x55, 0x65, 0x96,                         0x59, 0x5a, 0x65, 0x59, 0x55, 0xa6, 0x65};//    unsigned char src[] = {'a', 'b', 'c', 'd', 'e', 'f'};    unsigned char cmpBuf[1024];    unsigned char uncmpBuf[1024];    size1 = RLE_Compress(sizeof(src), src, 1024, cmpBuf);printf("size1=%d\n", size1);int len;    size2 = RLE_UnCompress(size1, cmpBuf, 1024, uncmpBuf, &len);    printf("size2=%d\n", size2);printf("-----------------src--------------------\n");for(int i=0; i

2、RLE改进一

下面是RLE改进一的形象举例说明:给出的数据序列为:A-A-A-A-A-B-B-C-D

未压缩前:A-A-A-A-A-B-B-C-D

(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44)

压缩后:5-A-2-B-C-D

(0xC5-0x41-0xC2-0x42-0x43-0x44)

/* Compress inBuf to outBuf * Input: *  inSize:  input buf size *  inBuf:  input buf, need compress *  outSize: output buf size, reality outSize <= 2*inSize, but suggest outSize = 2*inSize * Output: *  outBuf: compressed buf address * Return: *  0:  Err, input para fault *  1:  Err, outSize < reality compressed buf size *  >= 2: Succ, reality used compressed buf size * * List: A-A-A-A-A-B-B-C-D * Before: A-A-A-A-A-B-B-C-D * (0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44) * Compressed: 5-A-2-B-C-D * (0xC5-0x41-0xC2-0x42-0x43-0x44)*/#define RLE_ADV1_MAX_NUM    0x3F#define REL_ADV1_MARK       0xC0int RLE_ADV1_Compress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf){    int i=0, j=0;    int rptNum = 0;    if(inSize<=0 || outSize<=0) return 0;    if(!inBuf || !outBuf) return 0;    rptNum = 1;    for(i=0; i 1){                if(j > outSize - 2) goto done;                outBuf[j++] = rptNum | REL_ADV1_MARK;                outBuf[j++] = inBuf[i];                rptNum = 1;            }else{                if(inBuf[i] >= REL_ADV1_MARK){                    if(j > outSize - 2) goto done;                    outBuf[j++] = 1 | REL_ADV1_MARK;                    outBuf[j++] = inBuf[i];                }else{                    if(j > outSize) goto done;                    outBuf[j++] = inBuf[i];                }            }        }else{            if(rptNum == RLE_ADV1_MAX_NUM){                if(j > outSize-2) goto done;                outBuf[j++] = RLE_ADV1_MAX_NUM | REL_ADV1_MARK;                outBuf[j++] = inBuf[i];                rptNum = 0;            }            rptNum++;        }    }    if(rptNum > 0){        if(inBuf[i] >= REL_ADV1_MARK){            if(j > outSize - 2) goto done;            outBuf[j++] = 1 | REL_ADV1_MARK;            outBuf[j++] = inBuf[i++];        }else{            if(j > outSize) goto done;            outBuf[j++] = inBuf[i++];        }    }done:    printf("RLE_ADV1_Compress: inSize=%d, inLen=%d, outSize=%d, cmpSize=%d\n",           inSize, i, outSize, j);    if(i != inSize)        return 1;    else        return j;}/* uncompress data * Input: *  inSize      compressed data size *  inBuf       compressed data buf *  outSize     uncompress data buf size * Output: *  outBuf      uncompress data buf address *  inLen       reality use'd compressed data size * Return: *  <=  0       failure *  >   0       success, reality uncompress data size*/int RLE_ADV1_UnCompress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf, int *inLen){    int i=0, j=0;    int len;    if(inSize <= 0 || outSize <= 0) return -1;    if(!inBuf || !outBuf) return -1;    *inLen = 0;    for(i=0; i REL_ADV1_MARK){//            len = inBuf[i] & RLE_ADV1_MAX_NUM;            len = inBuf[i] & ~REL_ADV1_MARK;            if(len+j > outSize){                break;            }            memset(outBuf+j, inBuf[i+1], len);            j += len;            i++;        }else{            if(j >= outSize){                break;            }            outBuf[j++] = inBuf[i];        }    }    if(i == inSize - 1 && inBuf[i] < REL_ADV1_MARK){        if(j < outSize){            outBuf[j++] = inBuf[i++];        }    }    *inLen = i;    printf("RLE_ADV1_UnCompress: inSize=%d inLen=%d, outSize=%d unCmpSize=%d\n", inSize, i, outSize, j);    return j;}int RLE_ADV1_test(){    int size1, size2;    unsigned char src[]={'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd',                         'e', 'e', 'e', 'e', 'e', 'f', 'g', 'h', 0xc0, 0xcf};//    unsigned char src[] = {'a', 'b', 'c', 'd', 'e', 'f'};    unsigned char cmpBuf[1024];    unsigned char uncmpBuf[1024];    size1 = RLE_ADV1_Compress(sizeof(src), src, 1024, cmpBuf);    int len;    size2 = RLE_ADV1_UnCompress(size1, cmpBuf, 1024, uncmpBuf, &len);    printf("-----------------src--------------------\n");    for(int i=0; i

3、RLE改进二

下面是该RLE改进二的形象举例说明:给出的数据序列为:A-A-A-A-A-B-B-C-D

未压缩前:A-A-A-A-A-B-B-C-D

(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44)

压缩后:5-A-4-B-B-C-D

/* Compress inBuf to outBuf * Input: *  inSize:  input buf size *  inBuf:  input buf, need compress *  outSize: output buf size, reality outSize <= 2*inSize, but suggest outSize = 2*inSize * Output: *  outBuf: compressed buf address * Return: *  0:  Err, input para fault *  1:  Err, outSize < reality compressed buf size *  >= 2: Succ, reality used compressed buf size * * List: A-A-A-A-A-B-B-C-D * Before: A-A-A-A-A-B-B-C-D *(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44) * Compressed: 5-A-4-B-B-C-D * (0x85-0x41-0x84-0x42-0x42-0x43-0x44)*/#define RLE_ADV2_MAX_NUM    0x7F#define REL_ADV2_MARK       0x80int RLE_ADV2_Compress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf){    int i=0, j=0;    int rptNum = 0;    int isRpt = 0;    if(inSize<=0 || outSize<=0) return 0;    if(!inBuf || !outBuf) return 0;    rptNum = 1;    isRpt = 1;    for(i=0; i 2){                if(j > outSize - 2) goto done;                outBuf[j++] = rptNum | REL_ADV2_MARK;                outBuf[j++] = inBuf[i];                rptNum = 0;            }else{                if(rptNum == RLE_ADV2_MAX_NUM){                    if(j > outSize - rptNum - 1) goto done;                    outBuf[j++] = rptNum;                    memcpy(outBuf+j, inBuf+i-rptNum+1, rptNum);                    j += rptNum;                    rptNum = 0;                }            }            rptNum++;            isRpt = 0;        }else{            if(!isRpt && rptNum > 1){                rptNum--;                if(j > outSize - rptNum - 1) goto done;                outBuf[j++] = rptNum;                memcpy(outBuf+j, inBuf+i-rptNum, rptNum);                j += rptNum;                rptNum = 1;            }            if(rptNum == RLE_ADV2_MAX_NUM){                if(j > outSize-2) goto done;                outBuf[j++] = rptNum | REL_ADV2_MARK;                outBuf[j++] = inBuf[i];                rptNum = 0;            }            rptNum++;            isRpt = 1;        }    }    if(isRpt && rptNum > 2){        if(j > outSize - 2) goto done;        outBuf[j++] = rptNum | REL_ADV2_MARK;        outBuf[j++] = inBuf[i];    }else {        if(j > outSize - rptNum - 1) goto done;        outBuf[j++] = rptNum;        memcpy(outBuf+j, inBuf+i-rptNum+1, rptNum);        j += rptNum;    }    i++;done:    printf("RLE_ADV2_Compress: inSize=%d, inLen=%d, outSize=%d, cmpSize=%d\n",           inSize, i, outSize, j);    if(i != inSize)        return 1;    else        return j;}/* uncompress data * Input: *  inSize      compressed data size *  inBuf       compressed data buf *  outSize     uncompress data buf size * Output: *  outBuf      uncompress data buf address *  inLen       reality use'd compressed data size * Return: *  <=  0       failure *  >   0       success, reality uncompress data size*/int RLE_ADV2_UnCompress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf, int *inLen){    int i=0, j=0;    int len;    if(inSize <= 0 || outSize <= 0) return -1;    if(!inBuf || !outBuf) return -1;    *inLen = 0;    while(i REL_ADV2_MARK){//            len = inBuf[i] & RLE_ADV2_MAX_NUM;            len = inBuf[i] & (~REL_ADV2_MARK);            if(len+j > outSize){                break;            }            memset(outBuf+j, inBuf[i+1], len);            j += len;            i += 2;        }else{            len = inBuf[i];            if(i + 1 + len > inSize){                break;            }            memcpy(outBuf+j, inBuf+i+1, len);            j += len;            i += (len + 1);        }    }    *inLen = i;    printf("RLE_ADV2_UnCompress: inSize=%d inLen=%d, outSize=%d unCmpSize=%d\n", inSize, i, outSize, j);    return j;}int RLE_ADV2_test(){    int size1, size2;    unsigned char src[]={'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd',                         'e', 'e', 'e', 'e', 'e', 'f', 'g', 'h', 0xc0, 0xcf};//    unsigned char src[] = {'a', 'b', 'c', 'd', 'e', 'f'};    unsigned char cmpBuf[1024];    unsigned char uncmpBuf[1024];    size1 = RLE_ADV2_Compress(sizeof(src), src, 1024, cmpBuf);    int len;    size2 = RLE_ADV2_UnCompress(size1, cmpBuf, 1024, uncmpBuf, &len);    printf("-----------------src--------------------\n");    for(int i=0; i

4、RLE改进三

/* Compress inBuf to outBuf * Input: *  inSize:  input buf size *  inBuf:  input buf, need compress *  outSize: output buf size, reality outSize <= 2*inSize, but suggest outSize = 2*inSize * Output: *  outBuf: compressed buf address * Return: *  0:  Err, input para fault *  1:  Err, outSize < reality compressed buf size *  >= 2: Succ, reality used compressed buf size * * List: A-A-A-A-A-B-B-C-D * Before: A-A-A-A-A-B-B-C-D *(0x41-0x41-0x41-0x41-0x41-0x42-0x42-0x43-0x44) * Compressed: 5-A-2-B-2-C-D * (0x85-0x41-0x82-0x42-0x82-0x43-0x44)*/#define RLE_ADV3_MAX_NUM    0x7F#define REL_ADV3_MARK       0x80int RLE_ADV3_Compress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf){    int i=0, j=0;    int rptNum = 0;    int isRpt = 0;    if(inSize<=0 || outSize<=0) return 0;    if(!inBuf || !outBuf) return 0;    rptNum = 1;    isRpt = 0;    for(i=0; i outSize - 2) goto done;                if(rptNum == RLE_ADV3_MAX_NUM && j > outSize -3) goto done;                outBuf[j++] = rptNum | REL_ADV3_MARK;                if(rptNum == RLE_ADV3_MAX_NUM) outBuf[j++] = REL_ADV3_MARK;                outBuf[j++] = inBuf[i];                rptNum = 0;                isRpt = 0;            }else{                if(rptNum == RLE_ADV3_MAX_NUM){                    if(j > outSize - rptNum - 1) goto done;                    outBuf[j++] = rptNum;                    memcpy(outBuf+j, inBuf+i-rptNum+1, rptNum);                    j += rptNum;                    rptNum = 0;                }            }            rptNum++;        }else{            if(!isRpt){                if(rptNum > 1){                    rptNum--;                    if(j > outSize - rptNum - 1) goto done;                    outBuf[j++] = rptNum;                    memcpy(outBuf+j, inBuf+i-rptNum, rptNum);                    j += rptNum;                }                rptNum = 1;                isRpt = 1;            }            if(rptNum == RLE_ADV3_MAX_NUM){                if(j > outSize-1) goto done;                outBuf[j++] = RLE_ADV3_MAX_NUM | REL_ADV3_MARK;                rptNum = 0;            }            rptNum++;        }    }    if(isRpt){        if(j > outSize - 2) goto done;        if(rptNum == RLE_ADV3_MAX_NUM && j > outSize -3) goto done;        outBuf[j++] = rptNum | REL_ADV3_MARK;        if(rptNum == RLE_ADV3_MAX_NUM) outBuf[j++] = REL_ADV3_MARK;        outBuf[j++] = inBuf[i];    }else {        if(j > outSize - rptNum - 1) goto done;        outBuf[j++] = rptNum;        memcpy(outBuf+j, inBuf+i-rptNum+1, rptNum);        j += rptNum;    }    i++;done:    printf("RLE_ADV3_Compress: inSize=%d, inLen=%d, outSize=%d, cmpSize=%d\n",           inSize, i, outSize, j);    if(i != inSize)        return 1;    else        return j;}/* uncompress data * Input: *  inSize      compressed data size *  inBuf       compressed data buf *  outSize     uncompress data buf size * Output: *  outBuf      uncompress data buf address *  inLen       reality use'd compressed data size * Return: *  <=  0       failure *  >   0       success, reality uncompress data size*/int RLE_ADV3_UnCompress(int inSize, unsigned char *inBuf, int outSize, unsigned char *outBuf, int *inLen){    int i=0, j=0;    int len, sum=0;    if(inSize <= 0 || outSize <= 0) return -1;    if(!inBuf || !outBuf) return -1;    *inLen = 0;    while(i= REL_ADV3_MARK){//            len = inBuf[i] & RLE_ADV3_MAX_NUM;            len = inBuf[i] & (~REL_ADV3_MARK);            sum += len;            if(len == RLE_ADV3_MAX_NUM){                i++;                continue;            }            if(sum+j > outSize){                break;            }            memset(outBuf+j, inBuf[i+1], sum);            j += sum;            i += 2;            sum = 0;        }else{            len = inBuf[i];            if(i + 1 + len > inSize){                break;            }            memcpy(outBuf+j, inBuf+i+1, len);            j += len;            i += (len + 1);        }    }    *inLen = i;    printf("RLE_ADV3_UnCompress: inSize=%d inLen=%d, outSize=%d unCmpSize=%d\n", inSize, i, outSize, j);    return j;}int RLE_ADV3_test(){    int size1, size2;    unsigned char src[]={'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b', 'b', 'c', 'd',                         'e', 'e', 'e', 'e', 'e', 'f', 'g', 'h', 0xc0, 0xcf};//    unsigned char src[] = {'a', 'b', 'c', 'd', 'e', 'f'};    unsigned char cmpBuf[1024];    unsigned char uncmpBuf[1024];    size1 = RLE_ADV3_Compress(sizeof(src), src, 1024, cmpBuf);    cout << "size1=" << size1 << endl;    int len;    size2 = RLE_ADV3_UnCompress(size1, cmpBuf, 1024, uncmpBuf, &len);    cout << "size2=" << size2 << endl;    printf("-----------------src--------------------\n");    for(int i=0; i

原创粉丝点击