summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xdelta3/xdelta3.c37
-rw-r--r--xdelta3/xdelta3.h10
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
1551static usize_t 1551static usize_t
1552xd3_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
1563static usize_t
1552xd3_round_blksize (usize_t sz, usize_t blksz) 1564xd3_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