📄 xdelta3-djw.h
字号:
/* Compute min, max. */ for (i = 1; i <= abs_max; i += 1) { if (nr_clen[i]) { break; } } min_clen = i; for (i = abs_max; i != 0; i -= 1) { if (nr_clen[i]) { break; } } max_clen = i; /* Fill the BASE, LIMIT table. */ tmp_base[min_clen] = 0; base[min_clen] = 0; limit[min_clen] = nr_clen[min_clen] - 1; for (i = min_clen + 1; i <= max_clen; i += 1) { usize_t last_limit = ((limit[i-1] + 1) << 1); tmp_base[i] = tmp_base[i-1] + nr_clen[i-1]; limit[i] = last_limit + nr_clen[i] - 1; base[i] = last_limit - tmp_base[i]; } /* Fill the inorder array, canonically ordered codes. */ ci = clen; for (i = 0; i < asize; i += 1) { if ((l = *ci++) != 0) { inorder[tmp_base[l]++] = i; } } *min_clenp = min_clen; *max_clenp = max_clen;}static inline intdjw_decode_symbol (xd3_stream *stream, bit_state *bstate, const uint8_t **input, const uint8_t *input_end, const uint8_t *inorder, const usize_t *base, const usize_t *limit, usize_t min_clen, usize_t max_clen, usize_t *sym, usize_t max_sym){ usize_t code = 0; usize_t bits = 0; /* OPT: Supposedly a small lookup table improves speed here... */ /* Code outline is similar to xd3_decode_bits... */ if (bstate->cur_mask == 0x100) { goto next_byte; } for (;;) { do { if (bits == max_clen) { goto corrupt; } bits += 1; code = (code << 1); if (bstate->cur_byte & bstate->cur_mask) { code |= 1; } bstate->cur_mask <<= 1; if (bits >= min_clen && code <= limit[bits]) { goto done; } } while (bstate->cur_mask != 0x100); next_byte: if (*input == input_end) { stream->msg = "secondary decoder end of input"; return XD3_INTERNAL; } bstate->cur_byte = *(*input)++; bstate->cur_mask = 1; } done: if (base[bits] <= code) { usize_t offset = code - base[bits]; if (offset <= max_sym) { IF_DEBUG2 (DP(RINT "(j) %u ", code)); *sym = inorder[offset]; return 0; } } corrupt: stream->msg = "secondary decoder invalid code"; return XD3_INTERNAL;}static intdjw_decode_clclen (xd3_stream *stream, bit_state *bstate, const uint8_t **input, const uint8_t *input_end, uint8_t *cl_inorder, usize_t *cl_base, usize_t *cl_limit, usize_t *cl_minlen, usize_t *cl_maxlen, uint8_t *cl_mtf){ int ret; uint8_t cl_clen[DJW_TOTAL_CODES]; usize_t num_codes, value; int i; /* How many extra code lengths to encode. */ if ((ret = xd3_decode_bits (stream, bstate, input, input_end, DJW_EXTRA_CODE_BITS, & num_codes))) { return ret; } num_codes += DJW_EXTRA_12OFFSET; /* Read num_codes. */ for (i = 0; i < num_codes; i += 1) { if ((ret = xd3_decode_bits (stream, bstate, input, input_end, DJW_CLCLEN_BITS, & value))) { return ret; } cl_clen[i] = value; } /* Set the rest to zero. */ for (; i < DJW_TOTAL_CODES; i += 1) { cl_clen[i] = 0; } /* No need to check for in-range clen values, because: */ XD3_ASSERT (1 << DJW_CLCLEN_BITS == DJW_MAX_CLCLEN + 1); /* Build the code-length decoder. */ djw_build_decoder (stream, DJW_TOTAL_CODES, DJW_MAX_CLCLEN, cl_clen, cl_inorder, cl_base, cl_limit, cl_minlen, cl_maxlen); /* Initialize the MTF state. */ djw_init_clen_mtf_1_2 (cl_mtf); return 0;}static inline intdjw_decode_1_2 (xd3_stream *stream, bit_state *bstate, const uint8_t **input, const uint8_t *input_end, const uint8_t *inorder, const usize_t *base, const usize_t *limit, const usize_t *minlen, const usize_t *maxlen, uint8_t *mtfvals, usize_t elts, usize_t skip_offset, uint8_t *values){ usize_t n = 0, rep = 0, mtf = 0, s = 0; int ret; while (n < elts) { /* Special case inside generic code: CLEN only: If not the first group, * we already know the zero frequencies. */ if (skip_offset != 0 && n >= skip_offset && values[n-skip_offset] == 0) { values[n++] = 0; continue; } /* Repeat last symbol. */ if (rep != 0) { values[n++] = mtfvals[0]; rep -= 1; continue; } /* Symbol following last repeat code. */ if (mtf != 0) { usize_t sym = djw_update_mtf (mtfvals, mtf); values[n++] = sym; mtf = 0; continue; } /* Decode next symbol/repeat code. */ if ((ret = djw_decode_symbol (stream, bstate, input, input_end, inorder, base, limit, *minlen, *maxlen, & mtf, DJW_TOTAL_CODES))) { return ret; } if (mtf <= RUN_1) { /* Repetition. */ rep = ((mtf + 1) << s); mtf = 0; s += 1; } else { /* Remove the RUN_1 MTF offset. */ mtf -= 1; s = 0; } } /* If (rep != 0) there were too many codes received. */ if (rep != 0) { stream->msg = "secondary decoder invalid repeat code"; return XD3_INTERNAL; } return 0;}static inline intdjw_decode_prefix (xd3_stream *stream, bit_state *bstate, const uint8_t **input, const uint8_t *input_end, const uint8_t *cl_inorder, const usize_t *cl_base, const usize_t *cl_limit, const usize_t *cl_minlen, const usize_t *cl_maxlen, uint8_t *cl_mtf, usize_t groups, uint8_t *clen){ return djw_decode_1_2 (stream, bstate, input, input_end, cl_inorder, cl_base, cl_limit, cl_minlen, cl_maxlen, cl_mtf, ALPHABET_SIZE * groups, ALPHABET_SIZE, clen);}static intxd3_decode_huff (xd3_stream *stream, djw_stream *h, const uint8_t **input_pos, const uint8_t *const input_end, uint8_t **output_pos, const uint8_t *const output_end){ const uint8_t *input = *input_pos; uint8_t *output = *output_pos; bit_state bstate = BIT_STATE_DECODE_INIT; uint8_t *sel_group = NULL; usize_t groups, gp; usize_t output_bytes = (output_end - output); usize_t sector_size; usize_t sectors; int ret; /* Invalid input. */ if (output_bytes == 0) { stream->msg = "secondary decoder invalid input"; return XD3_INTERNAL; } /* Decode: number of groups */ if ((ret = xd3_decode_bits (stream, & bstate, & input, input_end, DJW_GROUP_BITS, & groups))) { goto fail; } groups += 1; if (groups > 1) { /* Decode: group size */ if ((ret = xd3_decode_bits (stream, & bstate, & input, input_end, DJW_SECTORSZ_BITS, & sector_size))) { goto fail; } sector_size = (sector_size + 1) * DJW_SECTORSZ_MULT; } else { /* Default for groups == 1 */ sector_size = output_bytes; } sectors = 1 + (output_bytes - 1) / sector_size; /* TODO: In the case of groups==1, lots of extra stack space gets used here. * Could dynamically allocate this memory, which would help with excess * parameter passing, too. Passing too many parameters in this file, * simplify it! */ /* Outer scope: per-group symbol decoder tables. */ { uint8_t inorder[DJW_MAX_GROUPS][ALPHABET_SIZE]; usize_t base [DJW_MAX_GROUPS][DJW_TOTAL_CODES]; usize_t limit [DJW_MAX_GROUPS][DJW_TOTAL_CODES]; usize_t minlen [DJW_MAX_GROUPS]; usize_t maxlen [DJW_MAX_GROUPS]; /* Nested scope: code length decoder tables. */ { uint8_t clen [DJW_MAX_GROUPS][ALPHABET_SIZE]; uint8_t cl_inorder[DJW_TOTAL_CODES]; usize_t cl_base [DJW_MAX_CLCLEN+2]; usize_t cl_limit [DJW_MAX_CLCLEN+2]; uint8_t cl_mtf [DJW_TOTAL_CODES]; usize_t cl_minlen; usize_t cl_maxlen; /* Compute the code length decoder. */ if ((ret = djw_decode_clclen (stream, & bstate, & input, input_end, cl_inorder, cl_base, cl_limit, & cl_minlen, & cl_maxlen, cl_mtf))) { goto fail; } /* Now decode each group decoder. */ if ((ret = djw_decode_prefix (stream, & bstate, & input, input_end, cl_inorder, cl_base, cl_limit, & cl_minlen, & cl_maxlen, cl_mtf, groups, clen[0]))) { goto fail; } /* Prepare the actual decoding tables. */ for (gp = 0; gp < groups; gp += 1) { djw_build_decoder (stream, ALPHABET_SIZE, DJW_MAX_CODELEN, clen[gp], inorder[gp], base[gp], limit[gp], & minlen[gp], & maxlen[gp]); } } /* Decode: selector clens. */ { uint8_t sel_inorder[DJW_MAX_GROUPS+2]; usize_t sel_base [DJW_MAX_GBCLEN+2]; usize_t sel_limit [DJW_MAX_GBCLEN+2]; uint8_t sel_mtf [DJW_MAX_GROUPS+2]; usize_t sel_minlen; usize_t sel_maxlen; /* Setup group selection. */ if (groups > 1) { uint8_t sel_clen[DJW_MAX_GROUPS+1]; for (gp = 0; gp < groups+1; gp += 1) { usize_t value; if ((ret = xd3_decode_bits (stream, & bstate, & input, input_end, DJW_GBCLEN_BITS, & value))) { goto fail; } sel_clen[gp] = value; sel_mtf[gp] = gp; } if ((sel_group = xd3_alloc (stream, sectors, 1)) == NULL) { ret = ENOMEM; goto fail; } djw_build_decoder (stream, groups+1, DJW_MAX_GBCLEN, sel_clen, sel_inorder, sel_base, sel_limit, & sel_minlen, & sel_maxlen); if ((ret = djw_decode_1_2 (stream, & bstate, & input, input_end, sel_inorder, sel_base, sel_limit, & sel_minlen, & sel_maxlen, sel_mtf, sectors, 0, sel_group))) { goto fail; } } /* Now decode each sector. */ { /* Initialize for (groups==1) case. */ uint8_t *gp_inorder = inorder[0]; usize_t *gp_base = base[0]; usize_t *gp_limit = limit[0]; usize_t gp_minlen = minlen[0]; usize_t gp_maxlen = maxlen[0]; usize_t c; for (c = 0; c < sectors; c += 1) { usize_t n; if (groups >= 2) { gp = sel_group[c]; XD3_ASSERT (gp < groups); gp_inorder = inorder[gp]; gp_base = base[gp]; gp_limit = limit[gp]; gp_minlen = minlen[gp]; gp_maxlen = maxlen[gp]; } XD3_ASSERT (output_end - output > 0); /* Decode next sector. */ n = min (sector_size, (usize_t) (output_end - output)); do { usize_t sym; if ((ret = djw_decode_symbol (stream, & bstate, & input, input_end, gp_inorder, gp_base, gp_limit, gp_minlen, gp_maxlen, & sym, ALPHABET_SIZE))) { goto fail; } *output++ = sym; } while (--n); } } } } IF_REGRESSION (if ((ret = xd3_test_clean_bits (stream, & bstate))) { goto fail; }); XD3_ASSERT (ret == 0); fail: xd3_free (stream, sel_group); (*input_pos) = input; (*output_pos) = output; return ret;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -