diff options
-rw-r--r-- | xdelta3/xdelta3.c | 37 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 10 |
2 files changed, 39 insertions, 8 deletions
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 88de13a..1e92c25 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -1549,6 +1549,18 @@ xd3_check_pow2 (usize_t value, usize_t *logof) | |||
1549 | } | 1549 | } |
1550 | 1550 | ||
1551 | static usize_t | 1551 | static usize_t |
1552 | xd3_pow2_roundup (usize_t x) | ||
1553 | { | ||
1554 | int i = 1; | ||
1555 | int s = 0; | ||
1556 | while (x > i) { | ||
1557 | i <<= 1; | ||
1558 | s++; | ||
1559 | } | ||
1560 | return i; | ||
1561 | } | ||
1562 | |||
1563 | static usize_t | ||
1552 | xd3_round_blksize (usize_t sz, usize_t blksz) | 1564 | xd3_round_blksize (usize_t sz, usize_t blksz) |
1553 | { | 1565 | { |
1554 | usize_t mod = sz & (blksz-1); | 1566 | usize_t mod = sz & (blksz-1); |
@@ -2629,13 +2641,29 @@ xd3_set_source (xd3_stream *stream, | |||
2629 | xd3_source *src) | 2641 | xd3_source *src) |
2630 | { | 2642 | { |
2631 | xoff_t blk_num; | 2643 | xoff_t blk_num; |
2632 | usize_t tail_size; | 2644 | usize_t tail_size, shiftby; |
2633 | 2645 | ||
2634 | IF_DEBUG1 (DP(RINT "[set source] size %"Q"u\n", src->size)); | 2646 | IF_DEBUG1 (DP(RINT "[set source] size %"Q"u\n", src->size)); |
2635 | 2647 | ||
2636 | if (src == NULL || src->size < stream->smatcher.large_look) { return 0; } | 2648 | if (src == NULL || src->size < stream->smatcher.large_look) { return 0; } |
2637 | 2649 | ||
2638 | stream->src = src; | 2650 | stream->src = src; |
2651 | |||
2652 | // If src->blksize is a power-of-two, xd3_blksize_div() will use | ||
2653 | // shift and mask rather than divide. Check that here. | ||
2654 | if (xd3_check_pow2 (src->blksize, &shiftby) == 0) | ||
2655 | { | ||
2656 | src->shiftby = shiftby; | ||
2657 | src->maskby = (1 << shiftby) - 1; | ||
2658 | } | ||
2659 | else if (src->size <= src->blksize) | ||
2660 | { | ||
2661 | int x = xd3_pow2_roundup (src->blksize); | ||
2662 | xd3_check_pow2 (x, &shiftby); | ||
2663 | src->shiftby = shiftby; | ||
2664 | src->maskby = (1 << shiftby) - 1; | ||
2665 | } | ||
2666 | |||
2639 | xd3_blksize_div (src->size, src, &blk_num, &tail_size); | 2667 | xd3_blksize_div (src->size, src, &blk_num, &tail_size); |
2640 | src->blocks = blk_num + (tail_size > 0); | 2668 | src->blocks = blk_num + (tail_size > 0); |
2641 | src->onlastblk = xd3_bytes_on_srcblk (src, src->blocks - 1); | 2669 | src->onlastblk = xd3_bytes_on_srcblk (src, src->blocks - 1); |
@@ -4006,13 +4034,9 @@ xd3_process_memory (int is_encode, | |||
4006 | config.winsize = min(input_size, (usize_t) XD3_DEFAULT_WINSIZE); | 4034 | config.winsize = min(input_size, (usize_t) XD3_DEFAULT_WINSIZE); |
4007 | config.iopt_size = min(input_size / 32, XD3_DEFAULT_IOPT_SIZE); | 4035 | config.iopt_size = min(input_size / 32, XD3_DEFAULT_IOPT_SIZE); |
4008 | config.iopt_size = max(config.iopt_size, 128U); | 4036 | config.iopt_size = max(config.iopt_size, 128U); |
4009 | |||
4010 | config.sprevsz = XD3_DEFAULT_SPREVSZ; | 4037 | config.sprevsz = XD3_DEFAULT_SPREVSZ; |
4011 | 4038 | ||
4012 | while (config.sprevsz / 2 > input_size) | 4039 | while (config.sprevsz / 2 > input_size) { config.sprevsz /= 2; } |
4013 | { | ||
4014 | config.sprevsz /= 2; | ||
4015 | } | ||
4016 | } | 4040 | } |
4017 | 4041 | ||
4018 | if ((ret = xd3_config_stream (&stream, &config)) != 0) | 4042 | if ((ret = xd3_config_stream (&stream, &config)) != 0) |
@@ -4024,6 +4048,7 @@ xd3_process_memory (int is_encode, | |||
4024 | { | 4048 | { |
4025 | memset (& src, 0, sizeof (src)); | 4049 | memset (& src, 0, sizeof (src)); |
4026 | src.size = source_size; | 4050 | src.size = source_size; |
4051 | |||
4027 | src.blksize = source_size; | 4052 | src.blksize = source_size; |
4028 | src.onblk = source_size; | 4053 | src.onblk = source_size; |
4029 | src.curblk = source; | 4054 | src.curblk = source; |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 9abddbf..a26f8d0 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -677,6 +677,8 @@ struct _xd3_source | |||
677 | xoff_t blocks; /* the total number of blocks in | 677 | xoff_t blocks; /* the total number of blocks in |
678 | this source */ | 678 | this source */ |
679 | usize_t onlastblk; /* cached size info, avoid __udivdi3 */ | 679 | usize_t onlastblk; /* cached size info, avoid __udivdi3 */ |
680 | int shiftby; /* for power-of-two blocksizes */ | ||
681 | int maskby; /* for power-of-two blocksizes */ | ||
680 | xoff_t cpyoff_blocks; /* offset of dec_cpyoff in blocks */ | 682 | xoff_t cpyoff_blocks; /* offset of dec_cpyoff in blocks */ |
681 | usize_t cpyoff_blkoff; /* offset of copy window in | 683 | usize_t cpyoff_blkoff; /* offset of copy window in |
682 | blocks, remainder */ | 684 | blocks, remainder */ |
@@ -1171,8 +1173,12 @@ void xd3_blksize_div (const xoff_t offset, | |||
1171 | const xd3_source *source, | 1173 | const xd3_source *source, |
1172 | xoff_t *blkno, | 1174 | xoff_t *blkno, |
1173 | usize_t *blkoff) { | 1175 | usize_t *blkoff) { |
1174 | *blkno = offset / source->blksize; | 1176 | *blkno = source->maskby ? |
1175 | *blkoff = offset - (*blkno * source->blksize); | 1177 | (offset >> source->shiftby) : |
1178 | (offset / source->blksize); | ||
1179 | *blkoff = source->maskby ? | ||
1180 | (offset & source->maskby) : | ||
1181 | (offset - *blkno * source->blksize); | ||
1176 | } | 1182 | } |
1177 | 1183 | ||
1178 | /* This function tells the number of bytes expected to be set in | 1184 | /* This function tells the number of bytes expected to be set in |