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

📄 decode.c

📁 Arithmetic coding source code. A very good software for arithmetic coding.
💻 C
字号:
/*** Symbol 0 is used for EOF.**** Format of compressed file:**** blocks of header + canonical coded data until n == 0 in the header**      ** Where header = **      LOG2_MAX_SYMBOL bits is number of distinct symbols (last block == 0)**      LOG2_L          bits is maximum codeword length**      next is a reverse list of n unary codes coding L-l_i for each symbol**      next is interp coded list of symbols that appear in the block**** ASSUMES: cw_lens[i] < MAX_SYMBOL for all i*/#include "mytypes.h"#include "code.h"#include "bitio.h"#include "interp.h"    /* Canonical coding arrays (flogged from encode.c) */extern ulong lj_base[];extern ulong min_code[];extern ulong offset[];ulong *lut[LUT_SIZE];       /* canonical decode array */uint max_cw_len;uint min_cw_len;            /* used to start the linear search if lut==NULL */    /* prototypes */int read_header(FILE *in_file, uint mapping[], uint cw_lens[]);void build_lut(void);void decode(FILE *in_file, uint mapping[]);extern void build_canonical_arrays(uint cw_lens[], uint);int peak_lens_memory;/*** Read compressed stdin, output symbols to stdout*/voiddo_decoding(FILE *in_file) {    ulong magic;    if (START_INPUT(in_file) == EOF) return;      /* empty input file */    magic = INPUT_ULONG(in_file, sizeof(ulong)*8);    if (magic != MAGIC) {        fprintf(stderr,"Input file was not compressed with shuff.\n");        return;    }    uint *mapping;    /* ordinal sym -> real sym */    uint cw_lens[L+1];    allocate(mapping, uint, MAX_SYMBOL);    SHOW_MEM(L, ulong) /* min_code */    SHOW_MEM(L, ulong) /* lj_base */    SHOW_MEM(L, ulong) /* offset */    SHOW_MEM(L+1, uint) /* cw_lens */    SHOW_MEM(MAX_SYMBOL, uint) /* mapping */    peak_lens_memory = 0;    while (read_header(in_file, mapping, cw_lens) != 0) {        build_lut();        decode(in_file, mapping);    }    SHOW_MEM(peak_lens_memory, int) /* mapping */} /* do_decoding() *//*** Read decode header, converting unary coded codeword lens into mapping** using distribution sort with cw_lens[]**** (1) Read n ** (2) Read max cw length.** (3) Read unary list of max_cw_len - l_i into lens.** (4) Interp decode list of symbols into syms.** (5) Build cw_lens[]** (6) Build mapping[]*/intread_header(FILE *in_file, uint mapping[], uint cw_lens[]) {    int i, n;    int *lens, *p;    n = INPUT_ULONG(in_file, LOG2_MAX_SYMBOL);//fprintf(stderr,"n: %10u\n",n);    if (n == 0) return 0;      /* last block */    allocate(lens, int, n+1);    if (n+1 > peak_lens_memory)         peak_lens_memory = n+1;        max_cw_len = INPUT_ULONG(in_file, LOG2_L);//fprintf(stderr,"max_cw_len: %5u\n",max_cw_len);    for(i = 0 ; i <= (int)max_cw_len ; i++)        cw_lens[i] = 0;    for (p = lens ; p < lens + n ; p++) {        *p = max_cw_len - INPUT_UNARY_CODE(in_file);        cw_lens[*p]++;    }    for(min_cw_len = 0 ; cw_lens[min_cw_len] == 0 ; min_cw_len++);//{uint i;//fprintf(stderr,"cw_lens : \n");//for(i=min_cw_len;i<=max_cw_len;i++)//fprintf(stderr,"%2d) %u\n",i, cw_lens[i]);//fprintf(stderr,"\n");//}    build_canonical_arrays(cw_lens, max_cw_len);    interp_decode(in_file, mapping, n);    for( i = 1 ; i <= (int)max_cw_len; i++)        cw_lens[i] += cw_lens[i-1];         for (p = lens + n - 1 ; p >= lens ; p--)        *p = cw_lens[*p - 1]++;    uint t, from, S;    int  start = 0;    lens[n] = 1;            // sentinel    while (start < n) {        from = start;        S    = mapping[start];        while (lens[from] >= 0) {            i = lens[from];            lens[from] = -1;            t = mapping[i] ; mapping[i] = S ; S = t;            from = i;        }        while (lens[start] == -1) start++; // find next start (if any)    }//{int i;//fprintf(stderr,"mapping\n");//for(i = 0 ; i < n; i++)//fprintf(stderr,"%8u %8u\n",i, mapping[i]);//fprintf(stderr,"\n");//}    free(lens);    return !0;}voidbuild_lut() {    uint max, min;                // range of left justified "i"    int i,j = max_cw_len - 1;  // pointer into lj    for(i = 0; i < LUT_SIZE ; i++) {        min = i << ((sizeof(ulong) << 3) - LUT_BITS);        max = min | MAX_IT;        while ( (j >=0 ) && (max > lj_base[j])) j--;            // we know max is in range of lj[j], so check min        if (min >= lj_base[j+1])            lut[i] = lj_base + j + 1;        else            lut[i] = NULL; //-(j+1);    }//{int i;//for(i = 0 ; i < (1 << LUT_BITS) ; i++)//if (lut[i] == NULL)//fprintf(stderr, "lut[%2x] NULL\n",i);//else//fprintf(stderr, "lut[%2x] %lu\n",i,lut[i]-lj_base);//for(i = 240 ; i < LUT_SIZE ; i++)//if (lut[i] == NULL)//fprintf(stderr, "lut[%2x] NULL\n",i);//else//fprintf(stderr, "lut[%2x] %lu\n",i,lut[i]-lj_base);//fflush(stderr);//}}/* build_lut() *//*** Decode canonical codes until we get symbol EOF_SYMBOL*/voiddecode(FILE *in_file, uint mapping[]) {    #define BUFF_LENGTH 4096    ulong buffer[BUFF_LENGTH];    ulong *buff = buffer;    ulong code        = 0;    ulong bits_needed = sizeof(ulong) << 3;    ulong currcode;    ulong currlen     = sizeof(ulong) << 3;    ulong *lj;    ulong *start_linear_search = lj_base + MAX(LUT_BITS, min_cw_len) - 1;    for(;;) {        code |= INPUT_ULONG(in_file, bits_needed);        lj = lut[code >> ((sizeof(ulong)<<3) - LUT_BITS)];        if (lj == NULL)            for(lj = start_linear_search ; code < *lj ; lj++);        currlen = lj - lj_base + 1;            // calculate symbol number        currcode = code >> ((sizeof(ulong) << 3) - currlen);        currcode -= min_code[currlen-1];        currcode += offset[currlen-1];//fprintf(stderr, "code %lx ",code);fflush(stderr);//fprintf(stderr, "currlen %lu sym # %lu -> %lu\n",currlen, currcode,mapping[currcode]);fflush(stderr);        if (mapping[currcode] == EOF_SYMBOL)    break;        if (buff == buffer + BUFF_LENGTH) {            fwrite(buffer,sizeof(ulong),BUFF_LENGTH,stdout);            buff = buffer;        }            // subtract the one added in encoding        *buff = mapping[currcode] - 1;         buff++;        code <<= currlen;        bits_needed = currlen;    }    if (buff == buffer + BUFF_LENGTH) {        fwrite(buffer,sizeof(ulong),BUFF_LENGTH,stdout);        buff = buffer;    }    fwrite(buffer,sizeof(ulong),buff - buffer,stdout);} /* decode() */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -