mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
Revert "(xdelta3) Slim down on dependency"
This reverts commit d7d659147c15394f72c3e53953bfb4291bd8c982.
This commit is contained in:
parent
910db94e9f
commit
91f3611fdd
105
deps/xdelta3/xdelta3-decode.h
vendored
105
deps/xdelta3/xdelta3-decode.h
vendored
@ -162,6 +162,9 @@ xd3_decode_allocate (xd3_stream *stream,
|
||||
uint8_t **buf_ptr,
|
||||
usize_t *buf_alloc)
|
||||
{
|
||||
IF_DEBUG2 (DP(RINT "[xd3_decode_allocate] size %"W"u alloc %"W"u\n",
|
||||
size, *buf_alloc));
|
||||
|
||||
if (*buf_ptr != NULL && *buf_alloc < size)
|
||||
{
|
||||
xd3_free (stream, *buf_ptr);
|
||||
@ -187,6 +190,9 @@ xd3_decode_section (xd3_stream *stream,
|
||||
xd3_decode_state nstate,
|
||||
int copy)
|
||||
{
|
||||
XD3_ASSERT (section->pos <= section->size);
|
||||
XD3_ASSERT (stream->dec_state != nstate);
|
||||
|
||||
if (section->pos < section->size)
|
||||
{
|
||||
usize_t sect_take;
|
||||
@ -201,6 +207,8 @@ xd3_decode_section (xd3_stream *stream,
|
||||
/* No allocation/copy needed */
|
||||
section->buf = stream->next_in;
|
||||
sect_take = section->size;
|
||||
IF_DEBUG1 (DP(RINT "[xd3_decode_section] zerocopy %"W"u @ %"W"u avail %"W"u\n",
|
||||
sect_take, section->pos, stream->avail_in));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -217,11 +225,17 @@ xd3_decode_section (xd3_stream *stream,
|
||||
section->size,
|
||||
& section->copied1,
|
||||
& section->alloc1)))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
section->buf = section->copied1;
|
||||
}
|
||||
|
||||
IF_DEBUG2 (DP(RINT "[xd3_decode_section] take %"W"u @ %"W"u [need %"W"u] avail %"W"u\n",
|
||||
sect_take, section->pos, sect_need, stream->avail_in));
|
||||
XD3_ASSERT (section->pos + sect_take <= section->alloc1);
|
||||
|
||||
memcpy (section->copied1 + section->pos,
|
||||
stream->next_in,
|
||||
sect_take);
|
||||
@ -236,10 +250,14 @@ xd3_decode_section (xd3_stream *stream,
|
||||
|
||||
if (section->pos < section->size)
|
||||
{
|
||||
IF_DEBUG1 (DP(RINT "[xd3_decode_section] further input required %"W"u\n",
|
||||
section->size - section->pos));
|
||||
stream->msg = "further input required";
|
||||
return XD3_INPUT;
|
||||
}
|
||||
|
||||
XD3_ASSERT (section->pos == section->size);
|
||||
|
||||
stream->dec_state = nstate;
|
||||
section->buf_max = section->buf + section->size;
|
||||
section->pos = 0;
|
||||
@ -269,13 +287,27 @@ xd3_decode_parse_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
/* For copy instructions, read address. */
|
||||
if (inst->type >= XD3_CPY)
|
||||
{
|
||||
IF_DEBUG2 ({
|
||||
static int cnt = 0;
|
||||
XPR(NT "DECODE:%u: COPY at %"Q"u (winoffset %"W"u) "
|
||||
"size %"W"u winaddr %"W"u\n",
|
||||
cnt++,
|
||||
stream->total_out + (stream->dec_position -
|
||||
stream->dec_cpylen),
|
||||
(stream->dec_position - stream->dec_cpylen),
|
||||
inst->size,
|
||||
inst->addr);
|
||||
});
|
||||
|
||||
if ((ret = xd3_decode_address (stream,
|
||||
stream->dec_position,
|
||||
inst->type - XD3_CPY,
|
||||
& stream->addr_sect.buf,
|
||||
stream->addr_sect.buf_max,
|
||||
& inst->addr)))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Cannot copy an address before it is filled-in. */
|
||||
if (inst->addr >= stream->dec_position)
|
||||
@ -293,6 +325,30 @@ xd3_decode_parse_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
return XD3_INVALID_INPUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IF_DEBUG2 ({
|
||||
if (inst->type == XD3_ADD)
|
||||
{
|
||||
static int cnt;
|
||||
XPR(NT "DECODE:%d: ADD at %"Q"u (winoffset %"W"u) size %"W"u\n",
|
||||
cnt++,
|
||||
(stream->total_out + stream->dec_position - stream->dec_cpylen),
|
||||
stream->dec_position - stream->dec_cpylen,
|
||||
inst->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
static int cnt;
|
||||
XD3_ASSERT (inst->type == XD3_RUN);
|
||||
XPR(NT "DECODE:%d: RUN at %"Q"u (winoffset %"W"u) size %"W"u\n",
|
||||
cnt++,
|
||||
stream->total_out + stream->dec_position - stream->dec_cpylen,
|
||||
stream->dec_position - stream->dec_cpylen,
|
||||
inst->size);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Check: The instruction will not overflow the output buffer. */
|
||||
if (stream->dec_position + inst->size > stream->dec_maxpos)
|
||||
@ -360,6 +416,8 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
return XD3_INVALID_INPUT;
|
||||
}
|
||||
|
||||
XD3_ASSERT (inst->type != XD3_NOOP);
|
||||
|
||||
switch (inst->type)
|
||||
{
|
||||
case XD3_RUN:
|
||||
@ -449,6 +507,7 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
int ret;
|
||||
|
||||
xd3_blksize_add (&block, &blkoff, source, inst->addr);
|
||||
XD3_ASSERT (blkoff < blksize);
|
||||
|
||||
if ((ret = xd3_getblk (stream, block)))
|
||||
{
|
||||
@ -468,10 +527,18 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
if ((source->onblk != blksize) &&
|
||||
(blkoff + take > source->onblk))
|
||||
{
|
||||
IF_DEBUG1 (XPR(NT "[srcfile] short at blkno %"Q"u onblk "
|
||||
"%"W"u blksize %"W"u blkoff %"W"u take %"W"u\n",
|
||||
block,
|
||||
source->onblk,
|
||||
blksize,
|
||||
blkoff,
|
||||
take));
|
||||
stream->msg = "source file too short";
|
||||
return XD3_INVALID_INPUT;
|
||||
}
|
||||
|
||||
XD3_ASSERT (blkoff != blksize);
|
||||
|
||||
/* Check if we have enough data on this block to
|
||||
* finish the instruction. */
|
||||
@ -485,6 +552,9 @@ xd3_decode_output_halfinst (xd3_stream *stream, xd3_hinst *inst)
|
||||
take = blksize - blkoff;
|
||||
inst->size -= take;
|
||||
inst->addr += take;
|
||||
|
||||
/* because (blkoff + take > blksize), above */
|
||||
XD3_ASSERT (inst->size != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -592,6 +662,9 @@ xd3_decode_sections (xd3_stream *stream)
|
||||
}
|
||||
need += stream->data_sect.size;
|
||||
|
||||
/* The window may be entirely processed. */
|
||||
XD3_ASSERT (stream->dec_winbytes <= need);
|
||||
|
||||
/* Compute how much more input is needed. */
|
||||
more = (need - stream->dec_winbytes);
|
||||
|
||||
@ -636,6 +709,8 @@ xd3_decode_sections (xd3_stream *stream)
|
||||
DEC_EMIT, copy))) { return ret; }
|
||||
}
|
||||
|
||||
XD3_ASSERT (stream->dec_winbytes == need);
|
||||
|
||||
if ((ret = xd3_decode_secondary_sections (stream))) { return ret; }
|
||||
|
||||
if (stream->flags & XD3_SKIP_EMIT)
|
||||
@ -656,6 +731,19 @@ xd3_decode_emit (xd3_stream *stream)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Produce output: originally structured to allow reentrant code
|
||||
* that fills as much of the output buffer as possible, but VCDIFF
|
||||
* semantics allows to copy from anywhere from the target window, so
|
||||
* instead allocate a sufficiently sized buffer after the target
|
||||
* window length is decoded.
|
||||
*
|
||||
* This code still needs to be reentrant to allow XD3_GETSRCBLK to
|
||||
* return control. This is handled by setting the
|
||||
* stream->dec_currentN instruction types to XD3_NOOP after they
|
||||
* have been processed. */
|
||||
XD3_ASSERT (! (stream->flags & XD3_SKIP_EMIT));
|
||||
XD3_ASSERT (stream->dec_tgtlen <= stream->space_out);
|
||||
|
||||
while (stream->inst_sect.buf != stream->inst_sect.buf_max ||
|
||||
stream->dec_current1.type != XD3_NOOP ||
|
||||
stream->dec_current2.type != XD3_NOOP)
|
||||
@ -685,6 +773,8 @@ xd3_decode_emit (xd3_stream *stream)
|
||||
|
||||
if (stream->avail_out != stream->dec_tgtlen)
|
||||
{
|
||||
IF_DEBUG2 (DP(RINT "AVAIL_OUT(%"W"u) != DEC_TGTLEN(%"W"u)\n",
|
||||
stream->avail_out, stream->dec_tgtlen));
|
||||
stream->msg = "wrong window length";
|
||||
return XD3_INVALID_INPUT;
|
||||
}
|
||||
@ -919,6 +1009,9 @@ xd3_decode_input (xd3_stream *stream)
|
||||
if ((ret = xd3_decode_init_window (stream))) { return ret; }
|
||||
|
||||
stream->dec_state = DEC_CPYLEN;
|
||||
|
||||
IF_DEBUG2 (DP(RINT "--------- TARGET WINDOW %"Q"u -----------\n",
|
||||
stream->current_window));
|
||||
}
|
||||
|
||||
case DEC_CPYLEN:
|
||||
@ -1072,6 +1165,16 @@ xd3_decode_input (xd3_stream *stream)
|
||||
xd3_blksize_div(stream->dec_cpyoff, src,
|
||||
&src->cpyoff_blocks,
|
||||
&src->cpyoff_blkoff);
|
||||
|
||||
IF_DEBUG2(DP(RINT
|
||||
"[decode_cpyoff] %"Q"u "
|
||||
"cpyblkno %"Q"u "
|
||||
"cpyblkoff %"W"u "
|
||||
"blksize %"W"u\n",
|
||||
stream->dec_cpyoff,
|
||||
src->cpyoff_blocks,
|
||||
src->cpyoff_blkoff,
|
||||
src->blksize));
|
||||
}
|
||||
|
||||
/* xd3_decode_emit returns XD3_OUTPUT on every success. */
|
||||
@ -1116,4 +1219,4 @@ xd3_decode_input (xd3_stream *stream)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _XDELTA3_DECODE_H_*/
|
||||
#endif /* _XDELTA3_DECODE_H_*/
|
145
deps/xdelta3/xdelta3-djw.h
vendored
145
deps/xdelta3/xdelta3-djw.h
vendored
@ -305,6 +305,21 @@ heap_extract (usize_t *heap, const djw_heapen *ents, usize_t heap_last)
|
||||
return (djw_heapen*) & ents[smallest];
|
||||
}
|
||||
|
||||
#if XD3_DEBUG
|
||||
static void
|
||||
heap_check (usize_t *heap, djw_heapen *ents, usize_t heap_last)
|
||||
{
|
||||
usize_t i;
|
||||
for (i = 1; i <= heap_last; i += 1)
|
||||
{
|
||||
/* Heap property: child not less than parent */
|
||||
XD3_ASSERT (! heap_less (& ents[heap[i]], & ents[heap[i/2]]));
|
||||
|
||||
IF_DEBUG2 (DP(RINT "heap[%"W"u] = %u\n", i, ents[heap[i]].freq));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************/
|
||||
/* MTF, 1/2 */
|
||||
/*********************************************************************/
|
||||
@ -380,9 +395,15 @@ djw_build_prefix (const djw_weight *freq, uint8_t *clen, usize_t asize, usize_t
|
||||
usize_t total_bits;
|
||||
usize_t i;
|
||||
|
||||
IF_DEBUG (usize_t first_bits = 0);
|
||||
|
||||
/* Insert real symbol frequences. */
|
||||
for (i = 0; i < asize; i += 1)
|
||||
{
|
||||
ents[i+1].freq = freq[i];
|
||||
IF_DEBUG2 (DP(RINT "ents[%"W"i] = freq[%"W"u] = %d\n",
|
||||
i+1, i, freq[i]));
|
||||
}
|
||||
|
||||
again:
|
||||
|
||||
@ -410,6 +431,11 @@ djw_build_prefix (const djw_weight *freq, uint8_t *clen, usize_t asize, usize_t
|
||||
}
|
||||
}
|
||||
|
||||
IF_DEBUG (heap_check (heap, ents, heap_last));
|
||||
|
||||
/* Must be at least one symbol, or else we can't get here. */
|
||||
XD3_ASSERT (heap_last != 0);
|
||||
|
||||
/* If there is only one symbol, fake a second to prevent zero-length
|
||||
* codes. */
|
||||
if (heap_last == 1)
|
||||
@ -435,6 +461,8 @@ djw_build_prefix (const djw_weight *freq, uint8_t *clen, usize_t asize, usize_t
|
||||
heap_insert (heap, ents, ++heap_last, ents_size++);
|
||||
}
|
||||
|
||||
IF_DEBUG (heap_check (heap, ents, heap_last));
|
||||
|
||||
/* Now compute prefix code lengths, counting parents. */
|
||||
for (i = 1; i < asize+1; i += 1)
|
||||
{
|
||||
@ -452,11 +480,21 @@ djw_build_prefix (const djw_weight *freq, uint8_t *clen, usize_t asize, usize_t
|
||||
}
|
||||
|
||||
/* clen is 0-origin, unlike ents. */
|
||||
IF_DEBUG2 (DP(RINT "clen[%"W"u] = %"W"u\n", i-1, b));
|
||||
clen[i-1] = b;
|
||||
}
|
||||
|
||||
IF_DEBUG (if (first_bits == 0) first_bits = total_bits);
|
||||
|
||||
if (! overflow)
|
||||
{
|
||||
IF_DEBUG2 (if (first_bits != total_bits)
|
||||
{
|
||||
DP(RINT "code length overflow changed %"W"u bits\n",
|
||||
total_bits - first_bits);
|
||||
});
|
||||
return total_bits;
|
||||
}
|
||||
|
||||
/* OPT: There is a non-looping way to fix overflow shown in zlib, but this
|
||||
* is easier (for now), as done in bzip2. */
|
||||
@ -487,6 +525,8 @@ djw_build_codes (usize_t *codes, const uint8_t *clen, usize_t asize, usize_t abs
|
||||
max_clen = xd3_max (max_clen, (usize_t) clen[i]);
|
||||
}
|
||||
|
||||
XD3_ASSERT (max_clen <= abs_max);
|
||||
|
||||
/* Generate a code for each symbol with the appropriate length. */
|
||||
for (l = min_clen; l <= max_clen; l += 1)
|
||||
{
|
||||
@ -500,6 +540,13 @@ djw_build_codes (usize_t *codes, const uint8_t *clen, usize_t asize, usize_t abs
|
||||
|
||||
code <<= 1;
|
||||
}
|
||||
|
||||
IF_DEBUG2 ({
|
||||
for (i = 0; i < asize; i += 1)
|
||||
{
|
||||
DP(RINT "code[%"W"u] = %"W"u\n", i, codes[i]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
@ -528,6 +575,8 @@ djw_compute_mtf_1_2 (djw_prefix *prefix,
|
||||
|
||||
for (j = 0; mtf[j] != sym; j += 1) { }
|
||||
|
||||
XD3_ASSERT (j <= nsym);
|
||||
|
||||
for (k = j; k >= 1; k -= 1) { mtf[k] = mtf[k-1]; }
|
||||
|
||||
mtf[0] = sym;
|
||||
@ -579,6 +628,14 @@ djw_count_freqs (djw_weight *freq, xd3_output *input)
|
||||
while (++p < p_max);
|
||||
}
|
||||
|
||||
IF_DEBUG2 ({int i;
|
||||
DP(RINT "freqs: ");
|
||||
for (i = 0; i < ALPHABET_SIZE; i += 1)
|
||||
{
|
||||
DP(RINT "%u ", freq[i]);
|
||||
}
|
||||
DP(RINT "\n");});
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@ -643,6 +700,7 @@ djw_encode_prefix (xd3_stream *stream,
|
||||
{
|
||||
num_to_encode -= 1;
|
||||
}
|
||||
XD3_ASSERT (num_to_encode - DJW_EXTRA_12OFFSET < (1 << DJW_EXTRA_CODE_BITS));
|
||||
|
||||
/* Encode: # of extra codes */
|
||||
if ((ret = xd3_encode_bits (stream, output, bstate, DJW_EXTRA_CODE_BITS,
|
||||
@ -789,6 +847,11 @@ xd3_encode_howmany_groups (xd3_stream *stream,
|
||||
(*ret_groups) = cfg_groups;
|
||||
(*ret_sector_size) = cfg_sector_size;
|
||||
|
||||
XD3_ASSERT (cfg_groups > 0 && cfg_groups <= DJW_MAX_GROUPS);
|
||||
XD3_ASSERT (cfg_groups == 1 ||
|
||||
(cfg_sector_size >= DJW_SECTORSZ_MULT &&
|
||||
cfg_sector_size <= DJW_SECTORSZ_MAX));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -814,6 +877,8 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
input_bytes = djw_count_freqs (real_freq, input);
|
||||
input_bits = input_bytes * 8;
|
||||
|
||||
XD3_ASSERT (input_bytes > 0);
|
||||
|
||||
if ((ret = xd3_encode_howmany_groups (stream, cfg, input_bytes,
|
||||
& groups, & sector_size)))
|
||||
{
|
||||
@ -877,12 +942,18 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
usize_t sym = *p++;
|
||||
usize_t bits = clen[sym];
|
||||
|
||||
IF_DEBUG (output_bits -= bits);
|
||||
|
||||
if ((ret = xd3_encode_bits (stream, & output,
|
||||
& bstate, bits, code[sym])))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
}
|
||||
while (p < p_max);
|
||||
}
|
||||
|
||||
XD3_ASSERT (output_bits == 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -902,6 +973,7 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
usize_t gbest_no;
|
||||
usize_t gpcnt;
|
||||
const uint8_t *p;
|
||||
IF_DEBUG2 (usize_t gcount[DJW_MAX_GROUPS]);
|
||||
|
||||
/* Encode: sector size (5 bits) */
|
||||
if ((ret = xd3_encode_bits (stream, & output, & bstate,
|
||||
@ -938,19 +1010,32 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
djw_weight sum = 0;
|
||||
djw_weight goal = left / (groups - gp);
|
||||
|
||||
IF_DEBUG2 (usize_t nz = 0);
|
||||
|
||||
/* Due to the single-code granularity of this distribution, it may
|
||||
* be that we can't generate a distribution for each group. In that
|
||||
* case subtract one group and try again. If (inefficient), we're
|
||||
* testing group behavior, so don't mess things up. */
|
||||
if (goal == 0 && !cfg->inefficient)
|
||||
{
|
||||
IF_DEBUG2 (DP(RINT "too many groups (%"W"u), dropping one\n",
|
||||
groups));
|
||||
groups -= 1;
|
||||
goto regroup;
|
||||
}
|
||||
|
||||
/* Sum == goal is possible when (cfg->inefficient)... */
|
||||
while (sum < goal)
|
||||
{
|
||||
XD3_ASSERT (sym2 < ALPHABET_SIZE);
|
||||
IF_DEBUG2 (nz += real_freq[sym2] != 0);
|
||||
sum += real_freq[sym2++];
|
||||
}
|
||||
|
||||
IF_DEBUG2(DP(RINT "group %"W"u has symbols %"W"u..%"W"u (%"W"u non-zero) "
|
||||
"(%u/%"W"u = %.3f)\n",
|
||||
gp, sym1, sym2, nz, sum,
|
||||
input_bytes, sum / (double)input_bytes););
|
||||
|
||||
for (s = 0; s < ALPHABET_SIZE; s += 1)
|
||||
{
|
||||
@ -966,6 +1051,7 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
niter += 1;
|
||||
gbest_no = 0;
|
||||
memset (evolve_freq, 0, sizeof (evolve_freq[0]) * groups);
|
||||
IF_DEBUG2 (memset (gcount, 0, sizeof (gcount[0]) * groups));
|
||||
|
||||
/* For each input page (loop is irregular to allow non-pow2-size group
|
||||
* size. */
|
||||
@ -1015,7 +1101,9 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
}
|
||||
}
|
||||
|
||||
XD3_ASSERT(gbest_no < gbest_max);
|
||||
gbest[gbest_no++] = winner;
|
||||
IF_DEBUG2 (gcount[winner] += 1);
|
||||
|
||||
p = p0;
|
||||
in = in0;
|
||||
@ -1030,6 +1118,8 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
}
|
||||
while (in != NULL);
|
||||
|
||||
XD3_ASSERT (gbest_no == gbest_max);
|
||||
|
||||
/* Recompute code lengths. */
|
||||
output_bits = 0;
|
||||
for (gp = 0; gp < groups; gp += 1)
|
||||
@ -1065,14 +1155,29 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
* for the (output_bits==0) assert after all bits are output. */
|
||||
if (any_zeros)
|
||||
{
|
||||
IF_DEBUG2 (usize_t save_total = output_bits);
|
||||
|
||||
for (i = 0; i < ALPHABET_SIZE; i += 1)
|
||||
{
|
||||
if (evolve_zero[i]) { output_bits -= evolve_clen[gp][i]; }
|
||||
}
|
||||
|
||||
IF_DEBUG2 (DP(RINT "evolve_zero reduced %"W"u bits in group %"W"u\n",
|
||||
save_total - output_bits, gp));
|
||||
}
|
||||
}
|
||||
|
||||
IF_DEBUG2(
|
||||
DP(RINT "pass %"W"u total bits: %"W"u group uses: ", niter, output_bits);
|
||||
for (gp = 0; gp < groups; gp += 1) { DP(RINT "%"W"u ", gcount[gp]); }
|
||||
DP(RINT "\n");
|
||||
);
|
||||
|
||||
/* End iteration. */
|
||||
|
||||
IF_DEBUG2 (if (niter > 1 && best_bits < output_bits) {
|
||||
DP(RINT "iteration lost %"W"u bits\n", output_bits - best_bits); });
|
||||
|
||||
if (niter == 1 || (niter < DJW_MAX_ITER &&
|
||||
(best_bits - output_bits) >= DJW_MIN_IMPROVEMENT))
|
||||
{
|
||||
@ -1086,6 +1191,9 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
goto nosecond;
|
||||
}
|
||||
|
||||
IF_DEBUG2 (DP(RINT "djw compression: %"W"u -> %0.3f\n",
|
||||
input_bytes, output_bits / 8.0));
|
||||
|
||||
/* Encode: prefix */
|
||||
{
|
||||
uint8_t prefix_symbol[DJW_MAX_GROUPS * ALPHABET_SIZE];
|
||||
@ -1136,10 +1244,18 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
usize_t gp_sel_bits = gbest_clen[gp_mtf];
|
||||
usize_t gp_sel_code = gbest_code[gp_mtf];
|
||||
|
||||
XD3_ASSERT (gp_mtf < groups+1);
|
||||
|
||||
if ((ret = xd3_encode_bits (stream, & output, & bstate,
|
||||
gp_sel_bits, gp_sel_code)))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
IF_DEBUG (select_bits -= gp_sel_bits);
|
||||
}
|
||||
|
||||
XD3_ASSERT (select_bits == 0);
|
||||
}
|
||||
|
||||
/* Efficiency check. */
|
||||
@ -1172,6 +1288,8 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
usize_t *gp_codes = evolve_code[gp_best];
|
||||
uint8_t *gp_clens = evolve_clen[gp_best];
|
||||
|
||||
XD3_ASSERT (sector < gbest_no);
|
||||
|
||||
sector += 1;
|
||||
|
||||
/* Encode the sector data. */
|
||||
@ -1181,14 +1299,21 @@ xd3_encode_huff (xd3_stream *stream,
|
||||
usize_t bits = gp_clens[sym];
|
||||
usize_t code = gp_codes[sym];
|
||||
|
||||
IF_DEBUG (output_bits -= bits);
|
||||
|
||||
if ((ret = xd3_encode_bits (stream, & output, & bstate,
|
||||
bits, code)))
|
||||
{
|
||||
goto failure;
|
||||
}
|
||||
|
||||
GP_PAGE ();
|
||||
}
|
||||
}
|
||||
while (in != NULL);
|
||||
|
||||
XD3_ASSERT (select_bits == 0);
|
||||
XD3_ASSERT (output_bits == 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1231,6 +1356,9 @@ djw_build_decoder (xd3_stream *stream,
|
||||
usize_t min_clen;
|
||||
usize_t max_clen;
|
||||
|
||||
/* Assumption: the two temporary arrays are large enough to hold abs_max. */
|
||||
XD3_ASSERT (abs_max <= DJW_MAX_CODELEN);
|
||||
|
||||
/* This looks something like the start of zlib's inftrees.c */
|
||||
memset (nr_clen, 0, sizeof (nr_clen[0]) * (abs_max+1));
|
||||
|
||||
@ -1239,6 +1367,13 @@ djw_build_decoder (xd3_stream *stream,
|
||||
ci = clen;
|
||||
do
|
||||
{
|
||||
/* Caller _must_ check that values are in-range. Most of the time the
|
||||
* caller decodes a specific number of bits, which imply the max value,
|
||||
* and the other time the caller decodes a huffman value, which must be
|
||||
* in-range. Therefore, its an assertion and this function cannot
|
||||
* otherwise fail. */
|
||||
XD3_ASSERT (*ci <= abs_max);
|
||||
|
||||
nr_clen[*ci++]++;
|
||||
}
|
||||
while (--i != 0);
|
||||
@ -1333,6 +1468,7 @@ djw_decode_symbol (xd3_stream *stream,
|
||||
|
||||
if (offset <= max_sym)
|
||||
{
|
||||
IF_DEBUG2 (DP(RINT "(j) %"W"u ", code));
|
||||
*sym = inorder[offset];
|
||||
return 0;
|
||||
}
|
||||
@ -1384,6 +1520,9 @@ djw_decode_clclen (xd3_stream *stream,
|
||||
/* 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,
|
||||
@ -1645,6 +1784,8 @@ xd3_decode_huff (xd3_stream *stream,
|
||||
{
|
||||
gp = sel_group[c];
|
||||
|
||||
XD3_ASSERT (gp < groups);
|
||||
|
||||
gp_inorder = inorder[gp];
|
||||
gp_base = base[gp];
|
||||
gp_limit = limit[gp];
|
||||
@ -1682,6 +1823,10 @@ xd3_decode_huff (xd3_stream *stream,
|
||||
}
|
||||
}
|
||||
|
||||
IF_REGRESSION (if ((ret = xd3_test_clean_bits (stream, & bstate)))
|
||||
{ goto fail; });
|
||||
XD3_ASSERT (ret == 0);
|
||||
|
||||
fail:
|
||||
xd3_free (stream, sel_group);
|
||||
|
||||
|
22
deps/xdelta3/xdelta3-fgk.h
vendored
22
deps/xdelta3/xdelta3-fgk.h
vendored
@ -204,8 +204,12 @@ static int fgk_init (xd3_stream *stream, fgk_stream *h, int is_encode)
|
||||
fgk_factor_remaining(h); /* set ZFE and ZFR */
|
||||
fgk_factor_remaining(h); /* set ZFDB according to prev state */
|
||||
|
||||
IF_DEBUG (memset (h->alphabet, 0, sizeof (h->alphabet[0]) * h->total_nodes));
|
||||
|
||||
for (ui = 0; ui < h->total_blocks-1; ui += 1)
|
||||
{
|
||||
h->block_array[ui].block_freeptr = &h->block_array[ui + 1];
|
||||
}
|
||||
|
||||
h->block_array[h->total_blocks - 1].block_freeptr = NULL;
|
||||
h->free_block = h->block_array;
|
||||
@ -234,6 +238,8 @@ static usize_t fgk_encode_data (fgk_stream* h, usize_t n)
|
||||
{
|
||||
fgk_node *target_ptr = h->alphabet + n;
|
||||
|
||||
XD3_ASSERT (n < h->alphabet_size);
|
||||
|
||||
h->coded_depth = 0;
|
||||
|
||||
/* First encode the binary representation of the nth remaining
|
||||
@ -290,6 +296,8 @@ static usize_t fgk_encode_data (fgk_stream* h, usize_t n)
|
||||
*/
|
||||
static INLINE fgk_bit fgk_get_encoded_bit (fgk_stream *h)
|
||||
{
|
||||
XD3_ASSERT (h->coded_depth > 0);
|
||||
|
||||
return h->coded_bits[--h->coded_depth];
|
||||
}
|
||||
|
||||
@ -412,6 +420,9 @@ static void fgk_promote (fgk_stream *h, fgk_node *node)
|
||||
node->left_child &&
|
||||
node->left_child->weight == 0)
|
||||
{
|
||||
XD3_ASSERT (node->left_child == h->remaining_zeros);
|
||||
XD3_ASSERT (node->right_child->weight == (node->weight+1)); /* child weight was already incremented */
|
||||
|
||||
if (node->weight == (my_right->weight - 1) && my_right != h->root_node)
|
||||
{
|
||||
fgk_free_block (h, cur_block);
|
||||
@ -613,6 +624,8 @@ static fgk_block* fgk_make_block (fgk_stream *h, fgk_node* lead)
|
||||
{
|
||||
fgk_block *ret = h->free_block;
|
||||
|
||||
XD3_ASSERT (h->free_block != NULL);
|
||||
|
||||
h->free_block = h->free_block->block_freeptr;
|
||||
|
||||
ret->block_leader = lead;
|
||||
@ -652,6 +665,8 @@ static void fgk_factor_remaining (fgk_stream *h)
|
||||
*/
|
||||
static INLINE int fgk_decode_bit (fgk_stream* h, fgk_bit b)
|
||||
{
|
||||
XD3_ASSERT (b == 1 || b == 0);
|
||||
|
||||
if (IS_ADAPTIVE && h->decode_ptr->weight == 0)
|
||||
{
|
||||
usize_t bitsreq;
|
||||
@ -827,6 +842,13 @@ xd3_decode_fgk (xd3_stream *stream,
|
||||
|
||||
if (output == output_max)
|
||||
{
|
||||
/* During regression testing: */
|
||||
IF_REGRESSION ({
|
||||
int ret;
|
||||
bstate.cur_mask <<= 1;
|
||||
if ((ret = xd3_test_clean_bits (stream, & bstate))) { return ret; }
|
||||
});
|
||||
|
||||
(*output_pos) = output;
|
||||
(*input_pos) = input;
|
||||
return 0;
|
||||
|
13
deps/xdelta3/xdelta3-hash.h
vendored
13
deps/xdelta3/xdelta3-hash.h
vendored
@ -20,6 +20,19 @@
|
||||
#include "retro_inline.h"
|
||||
#include "xdelta3-internal.h"
|
||||
|
||||
#if XD3_DEBUG
|
||||
#define SMALL_HASH_DEBUG1(s,inp) \
|
||||
uint32_t debug_state; \
|
||||
uint32_t debug_hval = xd3_checksum_hash (& (s)->small_hash, \
|
||||
xd3_scksum (&debug_state, (inp), (s)->smatcher.small_look))
|
||||
#define SMALL_HASH_DEBUG2(s,inp) \
|
||||
XD3_ASSERT (debug_hval == xd3_checksum_hash (& (s)->small_hash, \
|
||||
xd3_scksum (&debug_state, (inp), (s)->smatcher.small_look)))
|
||||
#else
|
||||
#define SMALL_HASH_DEBUG1(s,inp)
|
||||
#define SMALL_HASH_DEBUG2(s,inp)
|
||||
#endif /* XD3_DEBUG */
|
||||
|
||||
#if UNALIGNED_OK
|
||||
#define UNALIGNED_READ32(dest,src) (*(dest)) = (*(uint32_t*)(src))
|
||||
#else
|
||||
|
87
deps/xdelta3/xdelta3-internal.h
vendored
87
deps/xdelta3/xdelta3-internal.h
vendored
@ -20,6 +20,31 @@
|
||||
#include "retro_inline.h"
|
||||
#include "xdelta3.h"
|
||||
|
||||
typedef struct _main_file main_file;
|
||||
typedef struct _main_extcomp main_extcomp;
|
||||
|
||||
void main_buffree (void *ptr);
|
||||
void* main_bufalloc (size_t size);
|
||||
void main_file_init (main_file *xfile);
|
||||
int main_file_close (main_file *xfile);
|
||||
void main_file_cleanup (main_file *xfile);
|
||||
int main_file_isopen (main_file *xfile);
|
||||
int main_file_open (main_file *xfile, const char* name, int mode);
|
||||
int main_file_exists (main_file *xfile);
|
||||
int main_file_stat (main_file *xfile, xoff_t *size);
|
||||
int xd3_whole_append_window (xd3_stream *stream);
|
||||
int xd3_main_cmdline (int argc, char **argv);
|
||||
int main_file_read (main_file *ifile,
|
||||
uint8_t *buf,
|
||||
size_t size,
|
||||
size_t *nread,
|
||||
const char *msg);
|
||||
int main_file_write (main_file *ofile, uint8_t *buf,
|
||||
usize_t size, const char *msg);
|
||||
void* main_malloc (size_t size);
|
||||
void main_free (void *ptr);
|
||||
|
||||
int test_compare_files (const char* f0, const char* f1);
|
||||
usize_t xd3_bytes_on_srcblk (xd3_source *src, xoff_t blkno);
|
||||
xoff_t xd3_source_eof(const xd3_source *src);
|
||||
|
||||
@ -39,6 +64,7 @@ xd3_output* xd3_alloc_output (xd3_stream *stream,
|
||||
|
||||
int xd3_encode_init_full (xd3_stream *stream);
|
||||
usize_t xd3_pow2_roundup (usize_t x);
|
||||
long get_millisecs_now (void);
|
||||
int xd3_process_stream (int is_encode,
|
||||
xd3_stream *stream,
|
||||
int (*func) (xd3_stream *),
|
||||
@ -49,6 +75,67 @@ int xd3_process_stream (int is_encode,
|
||||
usize_t *output_size,
|
||||
usize_t output_size_max);
|
||||
|
||||
#if PYTHON_MODULE || SWIG_MODULE || NOT_MAIN
|
||||
int xd3_main_cmdline (int argc, char **argv);
|
||||
#endif
|
||||
|
||||
#if REGRESSION_TEST
|
||||
int xd3_selftest (void);
|
||||
#endif
|
||||
|
||||
/* main_file->mode values */
|
||||
typedef enum
|
||||
{
|
||||
XO_READ = 0,
|
||||
XO_WRITE = 1
|
||||
} main_file_modes;
|
||||
|
||||
#ifndef XD3_POSIX
|
||||
#define XD3_POSIX 0
|
||||
#endif
|
||||
#ifndef XD3_STDIO
|
||||
#define XD3_STDIO 0
|
||||
#endif
|
||||
#ifndef XD3_WIN32
|
||||
#define XD3_WIN32 0
|
||||
#endif
|
||||
#ifndef NOT_MAIN
|
||||
#define NOT_MAIN 0
|
||||
#endif
|
||||
|
||||
/* If none are set, default to posix. */
|
||||
#if (XD3_POSIX + XD3_STDIO + XD3_WIN32) == 0
|
||||
#undef XD3_POSIX
|
||||
#define XD3_POSIX 1
|
||||
#endif
|
||||
|
||||
struct _main_file
|
||||
{
|
||||
#if XD3_WIN32
|
||||
HANDLE file;
|
||||
#elif XD3_STDIO
|
||||
FILE *file;
|
||||
#elif XD3_POSIX
|
||||
int file;
|
||||
#endif
|
||||
|
||||
int mode; /* XO_READ and XO_WRITE */
|
||||
const char *filename; /* File name or /dev/stdin,
|
||||
* /dev/stdout, /dev/stderr. */
|
||||
char *filename_copy; /* File name or /dev/stdin,
|
||||
* /dev/stdout, /dev/stderr. */
|
||||
const char *realname; /* File name or /dev/stdin,
|
||||
* /dev/stdout, /dev/stderr. */
|
||||
const main_extcomp *compressor; /* External compression struct. */
|
||||
int flags; /* RD_FIRST, RD_NONEXTERNAL, ... */
|
||||
xoff_t nread; /* for input position */
|
||||
xoff_t nwrite; /* for output position */
|
||||
uint8_t *snprintf_buf; /* internal snprintf() use */
|
||||
int size_known; /* Set by main_set_souze */
|
||||
xoff_t source_position; /* for avoiding seek in getblk_func */
|
||||
int seek_failed; /* after seek fails once, try FIFO */
|
||||
};
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX 4294967295U
|
||||
#endif
|
||||
|
40
deps/xdelta3/xdelta3-second.h
vendored
40
deps/xdelta3/xdelta3-second.h
vendored
@ -65,10 +65,32 @@ static INLINE int xd3_decode_bits (xd3_stream *stream,
|
||||
|
||||
done:
|
||||
|
||||
IF_DEBUG2 (DP(RINT "(d) %"W"u ", value));
|
||||
|
||||
(*valuep) = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if REGRESSION_TEST
|
||||
/* There may be extra bits at the end of secondary decompression, this macro
|
||||
* checks for non-zero bits. This is overly strict, but helps pass the
|
||||
* single-bit-error regression test. */
|
||||
static int
|
||||
xd3_test_clean_bits (xd3_stream *stream, bit_state *bits)
|
||||
{
|
||||
for (; bits->cur_mask != 0x100; bits->cur_mask <<= 1)
|
||||
{
|
||||
if (bits->cur_byte & bits->cur_mask)
|
||||
{
|
||||
stream->msg = "secondary decoder garbage";
|
||||
return XD3_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
xd3_get_secondary (xd3_stream *stream, xd3_sec_stream **sec_streamp,
|
||||
int is_encode)
|
||||
@ -198,15 +220,23 @@ static INLINE int xd3_encode_bits (xd3_stream *stream,
|
||||
int ret;
|
||||
usize_t mask = 1 << nbits;
|
||||
|
||||
XD3_ASSERT (nbits > 0);
|
||||
XD3_ASSERT (nbits < sizeof (usize_t) * 8);
|
||||
XD3_ASSERT (value < mask);
|
||||
|
||||
do
|
||||
{
|
||||
mask >>= 1;
|
||||
|
||||
if ((ret = xd3_encode_bit (stream, output, bits, value & mask)))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
while (mask != 1);
|
||||
|
||||
IF_DEBUG2 (DP(RINT "(e) %"W"u ", value));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -260,8 +290,18 @@ xd3_encode_secondary (xd3_stream *stream,
|
||||
comp_size += tmp_tail->next;
|
||||
}
|
||||
|
||||
XD3_ASSERT (comp_size == xd3_sizeof_output (tmp_head));
|
||||
XD3_ASSERT (tmp_tail != NULL);
|
||||
|
||||
if (comp_size < (orig_size - SECONDARY_MIN_SAVINGS) || cfg->inefficient)
|
||||
{
|
||||
if (comp_size < orig_size)
|
||||
{
|
||||
IF_DEBUG1(DP(RINT "[encode_secondary] saved %"W"u bytes: %"W"u -> %"W"u (%0.2f%%)\n",
|
||||
orig_size - comp_size, orig_size, comp_size,
|
||||
100.0 * (double) comp_size / (double) orig_size));
|
||||
}
|
||||
|
||||
xd3_free_output (stream, *head);
|
||||
|
||||
*head = tmp_head;
|
||||
|
500
deps/xdelta3/xdelta3.c
vendored
500
deps/xdelta3/xdelta3.c
vendored
File diff suppressed because it is too large
Load Diff
184
deps/xdelta3/xdelta3.h
vendored
184
deps/xdelta3/xdelta3.h
vendored
@ -22,11 +22,21 @@
|
||||
#ifndef _XDELTA3_H_
|
||||
#define _XDELTA3_H_
|
||||
|
||||
#define _POSIX_SOURCE 200112L
|
||||
#define _ISOC99_SOURCE
|
||||
#define _C99_SOURCE
|
||||
/* To include RetroArch's INLINE macro */
|
||||
#include <retro_inline.h>
|
||||
#include "retro_inline.h"
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
@ -106,9 +116,46 @@
|
||||
#ifndef _WIN32
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
#endif /* _WIN32 defined */
|
||||
|
||||
#include <stdint.h>
|
||||
#else /* WIN32 case */
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#if XD3_USE_LARGEFILE64
|
||||
/* 64 bit file offsets: uses GetFileSizeEx and SetFilePointerEx. */
|
||||
#define WINVER 0x0500
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#else /* xoff_t is 32bit */
|
||||
/* 32 bit file offsets: uses GetFileSize and SetFilePointer. */
|
||||
#define WINVER 0x0400
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif /* if XD3_USE_LARGEFILE64 */
|
||||
#endif /* ifndef WINVER */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* _MSV_VER is defined by Microsoft tools, not by Mingw32 */
|
||||
#ifdef _MSC_VER
|
||||
typedef signed int ssize_t;
|
||||
typedef int pid_t;
|
||||
#if _MSC_VER < 1600
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned long uint32_t;
|
||||
typedef ULONGLONG uint64_t;
|
||||
#else /* _MSC_VER >= 1600 */
|
||||
/* For MSVC10 and above */
|
||||
#include <stdint.h>
|
||||
#define inline __inline
|
||||
#endif /* _MSC_VER < 1600 */
|
||||
#else /* _MSC_VER not defined */
|
||||
/* Mingw32 */
|
||||
#include <stdint.h>
|
||||
#endif /* _MSC_VER defined */
|
||||
|
||||
#endif /* _WIN32 defined */
|
||||
|
||||
#if SIZE_MAX == UINT64_MAX
|
||||
#define SIZEOF_SIZE_T 8
|
||||
@ -149,6 +196,12 @@
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
_Static_assert(SIZEOF_SIZE_T == sizeof(size_t), "SIZEOF_SIZE_T not correctly set");
|
||||
|
||||
#ifdef SIZEOF_UNSIGNED_LONG_LONG
|
||||
_Static_assert(SIZEOF_UNSIGNED_LONG_LONG == sizeof(unsigned long long), "SIZEOF_UNSIGNED_LONG_LONG not correctly set");
|
||||
#endif
|
||||
|
||||
/* Set a xoff_t typedef and the "Q" printf insert. */
|
||||
#if defined(_WIN32)
|
||||
typedef uint64_t xoff_t;
|
||||
@ -229,8 +282,10 @@ typedef uint32_t usize_t;
|
||||
#error Bad configure script
|
||||
#endif /* size_t printf flags */
|
||||
|
||||
#define USE_UINT32 (SIZEOF_USIZE_T == 4 || SIZEOF_XOFF_T == 4 )
|
||||
#define USE_UINT64 (SIZEOF_USIZE_T == 8 || SIZEOF_XOFF_T == 8 )
|
||||
#define USE_UINT32 (SIZEOF_USIZE_T == 4 || \
|
||||
SIZEOF_XOFF_T == 4 || REGRESSION_TEST)
|
||||
#define USE_UINT64 (SIZEOF_USIZE_T == 8 || \
|
||||
SIZEOF_XOFF_T == 8 || REGRESSION_TEST)
|
||||
|
||||
#ifndef UNALIGNED_OK
|
||||
#ifdef HAVE_ALIGNED_ACCESS_REQUIRED
|
||||
@ -248,6 +303,37 @@ typedef uint32_t usize_t;
|
||||
#define XD3_ENCODER 1
|
||||
#endif
|
||||
|
||||
/* The code returned when main() fails, also defined in system
|
||||
includes. */
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
/* REGRESSION TEST enables the "xdelta3 test" command, which runs a
|
||||
series of self-tests. */
|
||||
#ifndef REGRESSION_TEST
|
||||
#define REGRESSION_TEST 0
|
||||
#endif
|
||||
|
||||
/* XD3_DEBUG=1 enables assertions and various statistics. Levels > 1
|
||||
* enable some additional output only useful during development and
|
||||
* debugging. */
|
||||
#ifndef XD3_DEBUG
|
||||
#define XD3_DEBUG 0
|
||||
#endif
|
||||
|
||||
#ifndef PYTHON_MODULE
|
||||
#define PYTHON_MODULE 0
|
||||
#endif
|
||||
|
||||
#ifndef SWIG_MODULE
|
||||
#define SWIG_MODULE 0
|
||||
#endif
|
||||
|
||||
#ifndef NOT_MAIN
|
||||
#define NOT_MAIN 0
|
||||
#endif
|
||||
|
||||
/* There are three string matching functions supplied: one fast, one
|
||||
* slow (default), and one soft-configurable. To disable any of
|
||||
* these, use the following definitions. */
|
||||
@ -270,6 +356,10 @@ typedef uint32_t usize_t;
|
||||
#define XD3_BUILD_DEFAULT 1
|
||||
#endif
|
||||
|
||||
#if XD3_DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
typedef struct _xd3_stream xd3_stream;
|
||||
typedef struct _xd3_source xd3_source;
|
||||
typedef struct _xd3_hash_cfg xd3_hash_cfg;
|
||||
@ -310,6 +400,52 @@ typedef int (xd3_getblk_func) (xd3_stream *stream,
|
||||
|
||||
typedef const xd3_dinst* (xd3_code_table_func) (void);
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
#define vsnprintf_func _vsnprintf
|
||||
#define snprintf_func _snprintf
|
||||
#else
|
||||
#define vsnprintf_func vsnprintf
|
||||
#define snprintf_func snprintf
|
||||
#endif
|
||||
|
||||
/* Type used for short snprintf calls. */
|
||||
typedef struct {
|
||||
char buf[48];
|
||||
} shortbuf;
|
||||
|
||||
#ifndef PRINTF_ATTRIBUTE
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ATTRIBUTE(x,y) __attribute__ ((__format__ (__printf__, x, y)))
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE(x,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Underlying xprintf() */
|
||||
int xsnprintf_func (char *str, size_t n, const char *fmt, ...)
|
||||
PRINTF_ATTRIBUTE(3,4);
|
||||
|
||||
/* XPR(NT "", ...) (used by main) prefixes an "xdelta3: " to the output. */
|
||||
void xprintf(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
|
||||
#define XPR xprintf
|
||||
#define NT "xdelta3: "
|
||||
#define NTR ""
|
||||
/* DP(RINT ...) */
|
||||
#define DP xprintf
|
||||
#define RINT ""
|
||||
|
||||
#if XD3_DEBUG
|
||||
#define XD3_ASSERT(x) \
|
||||
do { \
|
||||
if (! (x)) { \
|
||||
DP(RINT "%s:%d: XD3 assertion failed: %s\n", \
|
||||
__FILE__, __LINE__, #x); \
|
||||
abort (); } } while (0)
|
||||
#else
|
||||
#define XD3_ASSERT(x) (void)0
|
||||
#endif /* XD3_DEBUG */
|
||||
|
||||
#define xd3_max(x,y) ((x) < (y) ? (y) : (x))
|
||||
#define xd3_min(x,y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
@ -990,6 +1126,14 @@ struct _xd3_stream
|
||||
xoff_t l_run;
|
||||
|
||||
usize_t i_slots_used;
|
||||
|
||||
#if XD3_DEBUG
|
||||
usize_t large_ckcnt;
|
||||
|
||||
/* memory usage */
|
||||
usize_t alloc_cnt;
|
||||
usize_t free_cnt;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**************************************************************************
|
||||
@ -1244,6 +1388,14 @@ void xd3_avail_input (xd3_stream *stream,
|
||||
const uint8_t *idata,
|
||||
usize_t isize)
|
||||
{
|
||||
/* Even if isize is zero, the code expects a non-NULL idata. Why?
|
||||
* It uses this value to determine whether xd3_avail_input has ever
|
||||
* been called. If xd3_encode_input is called before
|
||||
* xd3_avail_input it will return XD3_INPUT right away without
|
||||
* allocating a stream->winsize buffer. This is to avoid an
|
||||
* unwanted allocation. */
|
||||
XD3_ASSERT (idata != NULL || isize == 0);
|
||||
|
||||
stream->next_in = idata;
|
||||
stream->avail_in = isize;
|
||||
}
|
||||
@ -1274,6 +1426,9 @@ usize_t xd3_encoder_srclen (xd3_stream *stream) {
|
||||
static INLINE
|
||||
void xd3_set_flags (xd3_stream *stream, uint32_t flags)
|
||||
{
|
||||
/* The bitwise difference should contain only XD3_FLUSH or
|
||||
XD3_SKIP_WINDOW */
|
||||
XD3_ASSERT(((flags ^ stream->flags) & ~(XD3_FLUSH | XD3_SKIP_WINDOW)) == 0);
|
||||
stream->flags = flags;
|
||||
}
|
||||
|
||||
@ -1296,6 +1451,7 @@ void xd3_blksize_div (const xoff_t offset,
|
||||
usize_t *blkoff) {
|
||||
*blkno = offset >> source->shiftby;
|
||||
*blkoff = offset & source->maskby;
|
||||
XD3_ASSERT (*blkoff < source->blksize);
|
||||
}
|
||||
|
||||
static INLINE
|
||||
@ -1315,6 +1471,8 @@ void xd3_blksize_add (xoff_t *blkno,
|
||||
*blkno += blkdiff;
|
||||
*blkoff &= source->maskby;
|
||||
}
|
||||
|
||||
XD3_ASSERT (*blkoff < source->blksize);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -1327,6 +1485,22 @@ void xd3_blksize_add (xoff_t *blkno,
|
||||
#define XD3_CPY 3U /* XD3_CPY rtypes are represented as (XD3_CPY +
|
||||
* copy-mode value) */
|
||||
|
||||
#if XD3_DEBUG
|
||||
#define IF_DEBUG(x) x
|
||||
#else
|
||||
#define IF_DEBUG(x)
|
||||
#endif
|
||||
#if XD3_DEBUG > 1
|
||||
#define IF_DEBUG1(x) x
|
||||
#else
|
||||
#define IF_DEBUG1(x)
|
||||
#endif
|
||||
#if XD3_DEBUG > 2
|
||||
#define IF_DEBUG2(x) x
|
||||
#else
|
||||
#define IF_DEBUG2(x)
|
||||
#endif
|
||||
|
||||
#define SIZEOF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
#endif /* _XDELTA3_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user