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

📄 xdelta3-djw.h

📁 Linux下一个可以比较二进制文件的工具xdelta3.0u的源码。
💻 H
📖 第 1 页 / 共 4 页
字号:
  /* 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 + -