diff options
author | josh.macdonald <jmacd@users.noreply.github.com> | 2012-07-19 07:05:59 +0000 |
---|---|---|
committer | josh.macdonald <jmacd@users.noreply.github.com> | 2012-07-19 07:05:59 +0000 |
commit | 86757b7e62ce6e3a30c66eda2f2aeacbfe2450d6 (patch) | |
tree | d688c5004cd16e8b305127e4d5d5d659f231c7b9 | |
parent | 9376393d3c0c1ce7280b91c4747b0eb1c98a943a (diff) |
Add support for lzma secondary compression (-S lzma)
-rw-r--r-- | xdelta3/config.h.in | 6 | ||||
-rw-r--r-- | xdelta3/configure.ac | 2 | ||||
l--------- | xdelta3/ltmain.sh | 2 | ||||
l--------- | xdelta3/m4/ltversion.m4 | 2 | ||||
-rw-r--r-- | xdelta3/xdelta3-decode.h | 2 | ||||
-rw-r--r-- | xdelta3/xdelta3-djw.h | 9 | ||||
-rw-r--r-- | xdelta3/xdelta3-fgk.h | 8 | ||||
-rw-r--r-- | xdelta3/xdelta3-lzma.h | 185 | ||||
-rw-r--r-- | xdelta3/xdelta3-main.h | 4 | ||||
-rw-r--r-- | xdelta3/xdelta3-second.h | 38 | ||||
-rw-r--r-- | xdelta3/xdelta3-test.h | 10 | ||||
-rw-r--r-- | xdelta3/xdelta3.c | 59 | ||||
-rw-r--r-- | xdelta3/xdelta3.h | 8 |
13 files changed, 292 insertions, 43 deletions
diff --git a/xdelta3/config.h.in b/xdelta3/config.h.in index 19266b3..50345b3 100644 --- a/xdelta3/config.h.in +++ b/xdelta3/config.h.in | |||
@@ -6,6 +6,12 @@ | |||
6 | /* Define to 1 if you have the <inttypes.h> header file. */ | 6 | /* Define to 1 if you have the <inttypes.h> header file. */ |
7 | #undef HAVE_INTTYPES_H | 7 | #undef HAVE_INTTYPES_H |
8 | 8 | ||
9 | /* Define to 1 if you have the `lzma' library (-llzma). */ | ||
10 | #undef HAVE_LIBLZMA | ||
11 | |||
12 | /* Define to 1 if you have the <lzma.h> header file. */ | ||
13 | #undef HAVE_LZMA_H | ||
14 | |||
9 | /* Define to 1 if you have the <memory.h> header file. */ | 15 | /* Define to 1 if you have the <memory.h> header file. */ |
10 | #undef HAVE_MEMORY_H | 16 | #undef HAVE_MEMORY_H |
11 | 17 | ||
diff --git a/xdelta3/configure.ac b/xdelta3/configure.ac index 8d1707f..70b733a 100644 --- a/xdelta3/configure.ac +++ b/xdelta3/configure.ac | |||
@@ -7,6 +7,8 @@ AM_INIT_AUTOMAKE([1.9 no-define foreign tar-ustar]) | |||
7 | AC_DISABLE_STATIC | 7 | AC_DISABLE_STATIC |
8 | AC_PROG_CC | 8 | AC_PROG_CC |
9 | AC_PROG_CXX | 9 | AC_PROG_CXX |
10 | AC_CHECK_HEADERS([lzma.h]) | ||
11 | AC_CHECK_LIB(lzma, lzma_easy_buffer_encode) | ||
10 | #AM_PATH_PYTHON(,, [:]) | 12 | #AM_PATH_PYTHON(,, [:]) |
11 | #AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) | 13 | #AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) |
12 | #AX_PYTHON_DEVEL() | 14 | #AX_PYTHON_DEVEL() |
diff --git a/xdelta3/ltmain.sh b/xdelta3/ltmain.sh index 4159958..377d47b 120000 --- a/xdelta3/ltmain.sh +++ b/xdelta3/ltmain.sh | |||
@@ -1 +1 @@ | |||
/usr/share/libtool/config/ltmain.sh \ No newline at end of file | /usr/local/share/libtool/config/ltmain.sh \ No newline at end of file | ||
diff --git a/xdelta3/m4/ltversion.m4 b/xdelta3/m4/ltversion.m4 index 5eb474f..f5bd471 120000 --- a/xdelta3/m4/ltversion.m4 +++ b/xdelta3/m4/ltversion.m4 | |||
@@ -1 +1 @@ | |||
/usr/share/aclocal/ltversion.m4 \ No newline at end of file | /usr/local/share/aclocal/ltversion.m4 \ No newline at end of file | ||
diff --git a/xdelta3/xdelta3-decode.h b/xdelta3/xdelta3-decode.h index d33a79e..c0cb578 100644 --- a/xdelta3/xdelta3-decode.h +++ b/xdelta3/xdelta3-decode.h | |||
@@ -807,6 +807,8 @@ xd3_decode_input (xd3_stream *stream) | |||
807 | FGK_CASE (stream); | 807 | FGK_CASE (stream); |
808 | case VCD_DJW_ID: | 808 | case VCD_DJW_ID: |
809 | DJW_CASE (stream); | 809 | DJW_CASE (stream); |
810 | case VCD_LZMA_ID: | ||
811 | LZMA_CASE (stream); | ||
810 | default: | 812 | default: |
811 | stream->msg = "unknown secondary compressor ID"; | 813 | stream->msg = "unknown secondary compressor ID"; |
812 | return XD3_INVALID_INPUT; | 814 | return XD3_INVALID_INPUT; |
diff --git a/xdelta3/xdelta3-djw.h b/xdelta3/xdelta3-djw.h index be9cbf2..d6e2881 100644 --- a/xdelta3/xdelta3-djw.h +++ b/xdelta3/xdelta3-djw.h | |||
@@ -200,7 +200,9 @@ static const uint8_t djw_encode_12basic[DJW_BASIC_CODES] = | |||
200 | /*********************************************************************/ | 200 | /*********************************************************************/ |
201 | 201 | ||
202 | static djw_stream* djw_alloc (xd3_stream *stream); | 202 | static djw_stream* djw_alloc (xd3_stream *stream); |
203 | static void djw_init (djw_stream *h); | 203 | static int djw_init (xd3_stream *stream, |
204 | djw_stream *h, | ||
205 | int is_encode); | ||
204 | static void djw_destroy (xd3_stream *stream, | 206 | static void djw_destroy (xd3_stream *stream, |
205 | djw_stream *h); | 207 | djw_stream *h); |
206 | 208 | ||
@@ -229,10 +231,11 @@ djw_alloc (xd3_stream *stream) | |||
229 | return (djw_stream*) xd3_alloc (stream, sizeof (djw_stream), 1); | 231 | return (djw_stream*) xd3_alloc (stream, sizeof (djw_stream), 1); |
230 | } | 232 | } |
231 | 233 | ||
232 | static void | 234 | static int |
233 | djw_init (djw_stream *h) | 235 | djw_init (xd3_stream *stream, djw_stream *h, int is_encode) |
234 | { | 236 | { |
235 | /* Fields are initialized prior to use. */ | 237 | /* Fields are initialized prior to use. */ |
238 | return 0; | ||
236 | } | 239 | } |
237 | 240 | ||
238 | static void | 241 | static void |
diff --git a/xdelta3/xdelta3-fgk.h b/xdelta3/xdelta3-fgk.h index 6c61a96..7011500 100644 --- a/xdelta3/xdelta3-fgk.h +++ b/xdelta3/xdelta3-fgk.h | |||
@@ -106,7 +106,9 @@ struct _fgk_stream | |||
106 | /*********************************************************************/ | 106 | /*********************************************************************/ |
107 | 107 | ||
108 | static fgk_stream* fgk_alloc (xd3_stream *stream /*, usize_t alphabet_size */); | 108 | static fgk_stream* fgk_alloc (xd3_stream *stream /*, usize_t alphabet_size */); |
109 | static void fgk_init (fgk_stream *h); | 109 | static int fgk_init (xd3_stream *stream, |
110 | fgk_stream *h, | ||
111 | int is_encode); | ||
110 | static int fgk_encode_data (fgk_stream *h, | 112 | static int fgk_encode_data (fgk_stream *h, |
111 | usize_t n); | 113 | usize_t n); |
112 | static inline fgk_bit fgk_get_encoded_bit (fgk_stream *h); | 114 | static inline fgk_bit fgk_get_encoded_bit (fgk_stream *h); |
@@ -186,7 +188,7 @@ static fgk_stream* fgk_alloc (xd3_stream *stream /*, int alphabet_size0 */) | |||
186 | return h; | 188 | return h; |
187 | } | 189 | } |
188 | 190 | ||
189 | static void fgk_init (fgk_stream *h) | 191 | static int fgk_init (xd3_stream *stream, fgk_stream *h, int is_encode) |
190 | { | 192 | { |
191 | usize_t ui; | 193 | usize_t ui; |
192 | ssize_t si; | 194 | ssize_t si; |
@@ -219,6 +221,8 @@ static void fgk_init (fgk_stream *h) | |||
219 | { | 221 | { |
220 | fgk_init_node (h->alphabet + si, (usize_t) si, h->alphabet_size); | 222 | fgk_init_node (h->alphabet + si, (usize_t) si, h->alphabet_size); |
221 | } | 223 | } |
224 | |||
225 | return 0; | ||
222 | } | 226 | } |
223 | 227 | ||
224 | static void fgk_swap_ptrs(fgk_node **one, fgk_node **two) | 228 | static void fgk_swap_ptrs(fgk_node **one, fgk_node **two) |
diff --git a/xdelta3/xdelta3-lzma.h b/xdelta3/xdelta3-lzma.h new file mode 100644 index 0000000..aa48e84 --- /dev/null +++ b/xdelta3/xdelta3-lzma.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /* xdelta 3 - delta compression tools and library | ||
2 | * Copyright (C) 2012. Joshua P. MacDonald | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | /* Note: The use of the _easy_ decoder means we're not calling the | ||
20 | * xd3_stream malloc hooks. TODO(jmacd) Fix if anyone cares. */ | ||
21 | |||
22 | #ifndef _XDELTA3_LZMA_H_ | ||
23 | #define _XDELTA3_LZMA_H_ | ||
24 | |||
25 | #include <lzma.h> | ||
26 | |||
27 | typedef struct _xd3_lzma_stream xd3_lzma_stream; | ||
28 | |||
29 | struct _xd3_lzma_stream { | ||
30 | lzma_stream lzma; | ||
31 | }; | ||
32 | |||
33 | xd3_sec_stream* | ||
34 | xd3_lzma_alloc (xd3_stream *stream) | ||
35 | { | ||
36 | return (xd3_sec_stream*) xd3_alloc (stream, sizeof (xd3_lzma_stream), 1); | ||
37 | } | ||
38 | |||
39 | void | ||
40 | xd3_lzma_destroy (xd3_stream *stream, xd3_sec_stream *sec_stream) | ||
41 | { | ||
42 | xd3_lzma_stream *ls = (xd3_lzma_stream*) sec_stream; | ||
43 | lzma_end (&ls->lzma); | ||
44 | xd3_free (stream, ls); | ||
45 | } | ||
46 | |||
47 | int | ||
48 | xd3_lzma_init (xd3_stream *stream, xd3_lzma_stream *sec, int is_encode) | ||
49 | { | ||
50 | int ret; | ||
51 | |||
52 | memset (&sec->lzma, 0, sizeof(sec->lzma)); | ||
53 | |||
54 | if (is_encode) | ||
55 | { | ||
56 | int level = (stream->flags & XD3_COMPLEVEL_MASK) >> XD3_COMPLEVEL_SHIFT; | ||
57 | |||
58 | ret = lzma_easy_encoder (&sec->lzma, level, LZMA_CHECK_CRC32); | ||
59 | } | ||
60 | else | ||
61 | { | ||
62 | ret = lzma_stream_decoder (&sec->lzma, UINT64_MAX, 0); | ||
63 | } | ||
64 | |||
65 | if (ret != LZMA_OK) | ||
66 | { | ||
67 | stream->msg = "lzma stream init failed"; | ||
68 | return XD3_INTERNAL; | ||
69 | } | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | int xd3_decode_lzma (xd3_stream *stream, xd3_lzma_stream *sec, | ||
75 | const uint8_t **input_pos, | ||
76 | const uint8_t *const input_end, | ||
77 | uint8_t **output_pos, | ||
78 | const uint8_t *const output_end) | ||
79 | { | ||
80 | uint8_t *output = *output_pos; | ||
81 | const uint8_t *input = *input_pos; | ||
82 | size_t avail_in = input_end - input; | ||
83 | size_t avail_out = output_end - output; | ||
84 | |||
85 | sec->lzma.avail_in = avail_in; | ||
86 | sec->lzma.next_in = input; | ||
87 | sec->lzma.avail_out = avail_out; | ||
88 | sec->lzma.next_out = output; | ||
89 | |||
90 | while (sec->lzma.avail_in != 0 || sec->lzma.avail_out != 0) | ||
91 | { | ||
92 | int lret = lzma_code (&sec->lzma, LZMA_FINISH); | ||
93 | |||
94 | if (sec->lzma.avail_out == 0 || lret == LZMA_STREAM_END) | ||
95 | { | ||
96 | (*output_pos) = sec->lzma.next_out; | ||
97 | (*input_pos) = sec->lzma.next_in; | ||
98 | } | ||
99 | |||
100 | switch (lret) | ||
101 | { | ||
102 | case LZMA_STREAM_END: | ||
103 | return 0; | ||
104 | case LZMA_OK: | ||
105 | break; | ||
106 | |||
107 | default: | ||
108 | stream->msg = "lzma decoding error"; | ||
109 | return XD3_INTERNAL; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | #if XD3_ENCODER | ||
117 | |||
118 | int xd3_encode_lzma (xd3_stream *stream, | ||
119 | xd3_lzma_stream *sec, | ||
120 | xd3_output *input, | ||
121 | xd3_output *output, | ||
122 | xd3_sec_cfg *cfg) | ||
123 | |||
124 | { | ||
125 | lzma_action action = LZMA_RUN; | ||
126 | |||
127 | sec->lzma.next_in = NULL; | ||
128 | sec->lzma.avail_in = 0; | ||
129 | sec->lzma.next_out = (output->base + output->next); | ||
130 | sec->lzma.avail_out = (output->avail - output->next); | ||
131 | |||
132 | while (1) | ||
133 | { | ||
134 | int lret; | ||
135 | |||
136 | if (sec->lzma.avail_in == 0 && input != NULL) | ||
137 | { | ||
138 | sec->lzma.avail_in = input->next; | ||
139 | sec->lzma.next_in = input->base; | ||
140 | |||
141 | if ((input = input->next_page) == NULL) | ||
142 | { | ||
143 | action = LZMA_SYNC_FLUSH; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | lret = lzma_code (&sec->lzma, action); | ||
148 | |||
149 | if (sec->lzma.avail_out == 0 || lret == LZMA_STREAM_END) | ||
150 | { | ||
151 | size_t nwrite = (output->avail - output->next) - sec->lzma.avail_out; | ||
152 | output->next += nwrite; | ||
153 | |||
154 | if (output->next == output->avail) | ||
155 | { | ||
156 | if ((output = xd3_alloc_output (stream, output)) == NULL) | ||
157 | { | ||
158 | return ENOMEM; | ||
159 | } | ||
160 | |||
161 | sec->lzma.next_out = output->base; | ||
162 | sec->lzma.avail_out = output->avail; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | switch (lret) | ||
167 | { | ||
168 | case LZMA_OK: | ||
169 | break; | ||
170 | |||
171 | case LZMA_STREAM_END: | ||
172 | return 0; | ||
173 | |||
174 | default: | ||
175 | stream->msg = "lzma encoding error"; | ||
176 | return XD3_INTERNAL; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | #endif /* XD3_ENCODER */ | ||
184 | |||
185 | #endif /* _XDELTA3_LZMA_H_ */ | ||
diff --git a/xdelta3/xdelta3-main.h b/xdelta3/xdelta3-main.h index d68aa98..d2058c2 100644 --- a/xdelta3/xdelta3-main.h +++ b/xdelta3/xdelta3-main.h | |||
@@ -1161,6 +1161,10 @@ main_set_secondary_flags (xd3_config *config) | |||
1161 | { | 1161 | { |
1162 | config->flags |= XD3_SEC_FGK; | 1162 | config->flags |= XD3_SEC_FGK; |
1163 | } | 1163 | } |
1164 | else if (strcmp (option_secondary, "lzma") == 0 && HAVE_LZMA_H) | ||
1165 | { | ||
1166 | config->flags |= XD3_SEC_LZMA; | ||
1167 | } | ||
1164 | else if (strncmp (option_secondary, "djw", 3) == 0 && SECONDARY_DJW) | 1168 | else if (strncmp (option_secondary, "djw", 3) == 0 && SECONDARY_DJW) |
1165 | { | 1169 | { |
1166 | usize_t level = XD3_DEFAULT_SECONDARY_LEVEL; | 1170 | usize_t level = XD3_DEFAULT_SECONDARY_LEVEL; |
diff --git a/xdelta3/xdelta3-second.h b/xdelta3/xdelta3-second.h index f72ed9b..b9830ab 100644 --- a/xdelta3/xdelta3-second.h +++ b/xdelta3/xdelta3-second.h | |||
@@ -94,25 +94,27 @@ xd3_test_clean_bits (xd3_stream *stream, bit_state *bits) | |||
94 | } | 94 | } |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | static xd3_sec_stream* | 97 | static int |
98 | xd3_get_secondary (xd3_stream *stream, xd3_sec_stream **sec_streamp) | 98 | xd3_get_secondary (xd3_stream *stream, xd3_sec_stream **sec_streamp, |
99 | int is_encode) | ||
99 | { | 100 | { |
100 | xd3_sec_stream *sec_stream; | 101 | if (*sec_streamp == NULL) |
101 | |||
102 | if ((sec_stream = *sec_streamp) == NULL) | ||
103 | { | 102 | { |
103 | int ret; | ||
104 | |||
104 | if ((*sec_streamp = stream->sec_type->alloc (stream)) == NULL) | 105 | if ((*sec_streamp = stream->sec_type->alloc (stream)) == NULL) |
105 | { | 106 | { |
106 | return NULL; | 107 | stream->msg = "error initializing secondary stream"; |
108 | return XD3_INVALID; | ||
107 | } | 109 | } |
108 | 110 | ||
109 | sec_stream = *sec_streamp; | 111 | if ((ret = stream->sec_type->init (stream, *sec_streamp, is_encode)) != 0) |
110 | 112 | { | |
111 | /* If cuumulative stats, init once. */ | 113 | return ret; |
112 | stream->sec_type->init (sec_stream); | 114 | } |
113 | } | 115 | } |
114 | 116 | ||
115 | return sec_stream; | 117 | return 0; |
116 | } | 118 | } |
117 | 119 | ||
118 | static int | 120 | static int |
@@ -120,14 +122,13 @@ xd3_decode_secondary (xd3_stream *stream, | |||
120 | xd3_desect *sect, | 122 | xd3_desect *sect, |
121 | xd3_sec_stream **sec_streamp) | 123 | xd3_sec_stream **sec_streamp) |
122 | { | 124 | { |
123 | xd3_sec_stream *sec_stream; | ||
124 | uint32_t dec_size; | 125 | uint32_t dec_size; |
125 | uint8_t *out_used; | 126 | uint8_t *out_used; |
126 | int ret; | 127 | int ret; |
127 | 128 | ||
128 | if ((sec_stream = xd3_get_secondary (stream, sec_streamp)) == NULL) | 129 | if ((ret = xd3_get_secondary (stream, sec_streamp, 0)) != 0) |
129 | { | 130 | { |
130 | return ENOMEM; | 131 | return ret; |
131 | } | 132 | } |
132 | 133 | ||
133 | /* Decode the size, allocate the buffer. */ | 134 | /* Decode the size, allocate the buffer. */ |
@@ -141,7 +142,7 @@ xd3_decode_secondary (xd3_stream *stream, | |||
141 | 142 | ||
142 | out_used = sect->copied2; | 143 | out_used = sect->copied2; |
143 | 144 | ||
144 | if ((ret = stream->sec_type->decode (stream, sec_stream, | 145 | if ((ret = stream->sec_type->decode (stream, *sec_streamp, |
145 | & sect->buf, sect->buf_max, | 146 | & sect->buf, sect->buf_max, |
146 | & out_used, out_used + dec_size))) | 147 | & out_used, out_used + dec_size))) |
147 | { | 148 | { |
@@ -244,7 +245,6 @@ xd3_encode_secondary (xd3_stream *stream, | |||
244 | xd3_sec_cfg *cfg, | 245 | xd3_sec_cfg *cfg, |
245 | int *did_it) | 246 | int *did_it) |
246 | { | 247 | { |
247 | xd3_sec_stream *sec_stream; | ||
248 | xd3_output *tmp_head; | 248 | xd3_output *tmp_head; |
249 | xd3_output *tmp_tail; | 249 | xd3_output *tmp_tail; |
250 | 250 | ||
@@ -257,9 +257,9 @@ xd3_encode_secondary (xd3_stream *stream, | |||
257 | 257 | ||
258 | if (orig_size < SECONDARY_MIN_INPUT) { return 0; } | 258 | if (orig_size < SECONDARY_MIN_INPUT) { return 0; } |
259 | 259 | ||
260 | if ((sec_stream = xd3_get_secondary (stream, sec_streamp)) == NULL) | 260 | if ((ret = xd3_get_secondary (stream, sec_streamp, 1)) != 0) |
261 | { | 261 | { |
262 | return ENOMEM; | 262 | return ret; |
263 | } | 263 | } |
264 | 264 | ||
265 | tmp_head = xd3_alloc_output (stream, NULL); | 265 | tmp_head = xd3_alloc_output (stream, NULL); |
@@ -268,7 +268,7 @@ xd3_encode_secondary (xd3_stream *stream, | |||
268 | * simpler, but is a little gross. Should not need the entire | 268 | * simpler, but is a little gross. Should not need the entire |
269 | * section in contiguous memory, but it is much easier this way. */ | 269 | * section in contiguous memory, but it is much easier this way. */ |
270 | if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) || | 270 | if ((ret = xd3_emit_size (stream, & tmp_head, orig_size)) || |
271 | (ret = stream->sec_type->encode (stream, sec_stream, *head, | 271 | (ret = stream->sec_type->encode (stream, *sec_streamp, *head, |
272 | tmp_head, cfg))) | 272 | tmp_head, cfg))) |
273 | { | 273 | { |
274 | goto getout; | 274 | goto getout; |
diff --git a/xdelta3/xdelta3-test.h b/xdelta3/xdelta3-test.h index bd04f56..7464c4f 100644 --- a/xdelta3/xdelta3-test.h +++ b/xdelta3/xdelta3-test.h | |||
@@ -1185,7 +1185,7 @@ static int | |||
1185 | sec_dist_func7 (xd3_stream *stream, xd3_output *data) | 1185 | sec_dist_func7 (xd3_stream *stream, xd3_output *data) |
1186 | { | 1186 | { |
1187 | int i, ret, x; | 1187 | int i, ret, x; |
1188 | for (i = 0; i < ALPHABET_SIZE*20; i += 1) | 1188 | for (i = 0; i < ALPHABET_SIZE*200; i += 1) |
1189 | { | 1189 | { |
1190 | x = mt_random (&static_mtrand) % ALPHABET_SIZE; | 1190 | x = mt_random (&static_mtrand) % ALPHABET_SIZE; |
1191 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } | 1191 | if ((ret = xd3_emit_byte (stream, & data, x))) { return ret; } |
@@ -1305,7 +1305,7 @@ test_secondary_decode (xd3_stream *stream, | |||
1305 | 1305 | ||
1306 | if ((dec_stream = sec->alloc (stream)) == NULL) { return ENOMEM; } | 1306 | if ((dec_stream = sec->alloc (stream)) == NULL) { return ENOMEM; } |
1307 | 1307 | ||
1308 | sec->init (dec_stream); | 1308 | if ((ret = sec->init (stream, dec_stream, 0)) != 0) { goto fail; } |
1309 | 1309 | ||
1310 | dec_input_used = dec_input; | 1310 | dec_input_used = dec_input; |
1311 | dec_input_end = dec_input + compress_size; | 1311 | dec_input_end = dec_input + compress_size; |
@@ -1382,7 +1382,7 @@ test_secondary (xd3_stream *stream, const xd3_sec_type *sec, usize_t groups) | |||
1382 | 1382 | ||
1383 | if ((ret = sec_dists[test_i] (stream, in_head))) { goto fail; } | 1383 | if ((ret = sec_dists[test_i] (stream, in_head))) { goto fail; } |
1384 | 1384 | ||
1385 | sec->init (enc_stream); | 1385 | if ((ret = sec->init (stream, enc_stream, 1)) != 0) { goto fail; } |
1386 | 1386 | ||
1387 | /* Encode data */ | 1387 | /* Encode data */ |
1388 | if ((ret = sec->encode (stream, enc_stream, | 1388 | if ((ret = sec->encode (stream, enc_stream, |
@@ -1482,6 +1482,8 @@ IF_FGK (static int test_secondary_fgk (xd3_stream *stream, usize_t gp) | |||
1482 | { return test_secondary (stream, & fgk_sec_type, gp); }) | 1482 | { return test_secondary (stream, & fgk_sec_type, gp); }) |
1483 | IF_DJW (static int test_secondary_huff (xd3_stream *stream, usize_t gp) | 1483 | IF_DJW (static int test_secondary_huff (xd3_stream *stream, usize_t gp) |
1484 | { return test_secondary (stream, & djw_sec_type, gp); }) | 1484 | { return test_secondary (stream, & djw_sec_type, gp); }) |
1485 | IF_LZMA (static int test_secondary_lzma (xd3_stream *stream, usize_t gp) | ||
1486 | { return test_secondary (stream, & lzma_sec_type, gp); }) | ||
1485 | #endif | 1487 | #endif |
1486 | 1488 | ||
1487 | /*********************************************************************** | 1489 | /*********************************************************************** |
@@ -2818,6 +2820,7 @@ xd3_selftest (void) | |||
2818 | DO_TEST (decompress_single_bit_error, 0, 3); | 2820 | DO_TEST (decompress_single_bit_error, 0, 3); |
2819 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); | 2821 | DO_TEST (decompress_single_bit_error, XD3_ADLER32, 3); |
2820 | 2822 | ||
2823 | IF_LZMA (DO_TEST (decompress_single_bit_error, XD3_SEC_LZMA, 3)); | ||
2821 | IF_FGK (DO_TEST (decompress_single_bit_error, XD3_SEC_FGK, 3)); | 2824 | IF_FGK (DO_TEST (decompress_single_bit_error, XD3_SEC_FGK, 3)); |
2822 | IF_DJW (DO_TEST (decompress_single_bit_error, XD3_SEC_DJW, 8)); | 2825 | IF_DJW (DO_TEST (decompress_single_bit_error, XD3_SEC_DJW, 8)); |
2823 | 2826 | ||
@@ -2840,6 +2843,7 @@ xd3_selftest (void) | |||
2840 | DO_TEST (recode_command, 0, 0); | 2843 | DO_TEST (recode_command, 0, 0); |
2841 | #endif | 2844 | #endif |
2842 | 2845 | ||
2846 | IF_LZMA (DO_TEST (secondary_lzma, 0, 1)); | ||
2843 | IF_DJW (DO_TEST (secondary_huff, 0, DJW_MAX_GROUPS)); | 2847 | IF_DJW (DO_TEST (secondary_huff, 0, DJW_MAX_GROUPS)); |
2844 | IF_FGK (DO_TEST (secondary_fgk, 0, 1)); | 2848 | IF_FGK (DO_TEST (secondary_fgk, 0, 1)); |
2845 | 2849 | ||
diff --git a/xdelta3/xdelta3.c b/xdelta3/xdelta3.c index 9d9e52c..cb6bde6 100644 --- a/xdelta3/xdelta3.c +++ b/xdelta3/xdelta3.c | |||
@@ -278,17 +278,17 @@ | |||
278 | #define VCDIFF_TOOLS XD3_MAIN | 278 | #define VCDIFF_TOOLS XD3_MAIN |
279 | #endif | 279 | #endif |
280 | 280 | ||
281 | #ifndef SECONDARY_FGK /* one from the algorithm preservation department: */ | 281 | #ifndef SECONDARY_FGK /* one from the algorithm preservation department: */ |
282 | #define SECONDARY_FGK 0 /* adaptive Huffman routines */ | 282 | #define SECONDARY_FGK 0 /* adaptive Huffman routines */ |
283 | #endif | 283 | #endif |
284 | 284 | ||
285 | #ifndef SECONDARY_DJW /* semi-adaptive/static Huffman for the eventual */ | 285 | #ifndef SECONDARY_DJW /* semi-adaptive/static Huffman for the eventual */ |
286 | #define SECONDARY_DJW 0 /* standardization, off by default until such time. */ | 286 | #define SECONDARY_DJW 0 /* standardization, off by default until such time. */ |
287 | #endif | 287 | #endif |
288 | 288 | ||
289 | #ifndef GENERIC_ENCODE_TABLES /* These three are the RFC-spec'd app-specific */ | 289 | #ifndef GENERIC_ENCODE_TABLES /* These three are the RFC-spec app-specific */ |
290 | #define GENERIC_ENCODE_TABLES 0 /* code features. This is tested but not recommended */ | 290 | #define GENERIC_ENCODE_TABLES 0 /* code features. This is tested but not */ |
291 | #endif /* unless there's a real application. */ | 291 | #endif /* recommended unless there's a real use. */ |
292 | #ifndef GENERIC_ENCODE_TABLES_COMPUTE | 292 | #ifndef GENERIC_ENCODE_TABLES_COMPUTE |
293 | #define GENERIC_ENCODE_TABLES_COMPUTE 0 | 293 | #define GENERIC_ENCODE_TABLES_COMPUTE 0 |
294 | #endif | 294 | #endif |
@@ -326,6 +326,7 @@ | |||
326 | 326 | ||
327 | typedef enum { | 327 | typedef enum { |
328 | VCD_DJW_ID = 1, | 328 | VCD_DJW_ID = 1, |
329 | VCD_LZMA_ID = 2, | ||
329 | VCD_FGK_ID = 16 /* Note: these are not standard IANA-allocated IDs! */ | 330 | VCD_FGK_ID = 16 /* Note: these are not standard IANA-allocated IDs! */ |
330 | } xd3_secondary_ids; | 331 | } xd3_secondary_ids; |
331 | 332 | ||
@@ -371,7 +372,7 @@ XD3_MAKELIST(xd3_rlist, xd3_rinst, link); | |||
371 | #define CODE_TABLE_VCDIFF_SIZE (6 * 256) /* Should fit a compressed code | 372 | #define CODE_TABLE_VCDIFF_SIZE (6 * 256) /* Should fit a compressed code |
372 | * table string */ | 373 | * table string */ |
373 | 374 | ||
374 | #define SECONDARY_ANY (SECONDARY_DJW || SECONDARY_FGK) | 375 | #define SECONDARY_ANY (SECONDARY_DJW || SECONDARY_FGK || HAVE_LZMA_H) |
375 | 376 | ||
376 | #define ALPHABET_SIZE 256 /* Used in test code--size of the secondary | 377 | #define ALPHABET_SIZE 256 /* Used in test code--size of the secondary |
377 | * compressor alphabet. */ | 378 | * compressor alphabet. */ |
@@ -630,7 +631,9 @@ struct _xd3_sec_type | |||
630 | xd3_sec_stream* (*alloc) (xd3_stream *stream); | 631 | xd3_sec_stream* (*alloc) (xd3_stream *stream); |
631 | void (*destroy) (xd3_stream *stream, | 632 | void (*destroy) (xd3_stream *stream, |
632 | xd3_sec_stream *sec); | 633 | xd3_sec_stream *sec); |
633 | void (*init) (xd3_sec_stream *sec); | 634 | int (*init) (xd3_stream *stream, |
635 | xd3_sec_stream *sec_stream, | ||
636 | int is_encode); | ||
634 | int (*decode) (xd3_stream *stream, | 637 | int (*decode) (xd3_stream *stream, |
635 | xd3_sec_stream *sec_stream, | 638 | xd3_sec_stream *sec_stream, |
636 | const uint8_t **input, | 639 | const uint8_t **input, |
@@ -703,6 +706,19 @@ extern const xd3_sec_type djw_sec_type; | |||
703 | return XD3_INTERNAL; | 706 | return XD3_INTERNAL; |
704 | #endif | 707 | #endif |
705 | 708 | ||
709 | #if HAVE_LZMA_H | ||
710 | extern const xd3_sec_type lzma_sec_type; | ||
711 | #define IF_LZMA(x) x | ||
712 | #define LZMA_CASE(s) \ | ||
713 | s->sec_type = & lzma_sec_type; \ | ||
714 | break; | ||
715 | #else | ||
716 | #define IF_LZMA(x) | ||
717 | #define LZMA_CASE(s) \ | ||
718 | s->msg = "unavailable secondary compressor: LZMA"; \ | ||
719 | return XD3_INTERNAL; | ||
720 | #endif | ||
721 | |||
706 | /***********************************************************************/ | 722 | /***********************************************************************/ |
707 | 723 | ||
708 | #include "xdelta3-hash.h" | 724 | #include "xdelta3-hash.h" |
@@ -731,7 +747,7 @@ const xd3_sec_type fgk_sec_type = | |||
731 | SEC_NOFLAGS, | 747 | SEC_NOFLAGS, |
732 | (xd3_sec_stream* (*)(xd3_stream*)) fgk_alloc, | 748 | (xd3_sec_stream* (*)(xd3_stream*)) fgk_alloc, |
733 | (void (*)(xd3_stream*, xd3_sec_stream*)) fgk_destroy, | 749 | (void (*)(xd3_stream*, xd3_sec_stream*)) fgk_destroy, |
734 | (void (*)(xd3_sec_stream*)) fgk_init, | 750 | (int (*)(xd3_stream*, xd3_sec_stream*, int)) fgk_init, |
735 | (int (*)(xd3_stream*, xd3_sec_stream*, const uint8_t**, const uint8_t*, | 751 | (int (*)(xd3_stream*, xd3_sec_stream*, const uint8_t**, const uint8_t*, |
736 | uint8_t**, const uint8_t*)) xd3_decode_fgk, | 752 | uint8_t**, const uint8_t*)) xd3_decode_fgk, |
737 | IF_ENCODER((int (*)(xd3_stream*, xd3_sec_stream*, xd3_output*, | 753 | IF_ENCODER((int (*)(xd3_stream*, xd3_sec_stream*, xd3_output*, |
@@ -748,7 +764,7 @@ const xd3_sec_type djw_sec_type = | |||
748 | SEC_COUNT_FREQS, | 764 | SEC_COUNT_FREQS, |
749 | (xd3_sec_stream* (*)(xd3_stream*)) djw_alloc, | 765 | (xd3_sec_stream* (*)(xd3_stream*)) djw_alloc, |
750 | (void (*)(xd3_stream*, xd3_sec_stream*)) djw_destroy, | 766 | (void (*)(xd3_stream*, xd3_sec_stream*)) djw_destroy, |
751 | (void (*)(xd3_sec_stream*)) djw_init, | 767 | (int (*)(xd3_stream*, xd3_sec_stream*, int)) djw_init, |
752 | (int (*)(xd3_stream*, xd3_sec_stream*, const uint8_t**, const uint8_t*, | 768 | (int (*)(xd3_stream*, xd3_sec_stream*, const uint8_t**, const uint8_t*, |
753 | uint8_t**, const uint8_t*)) xd3_decode_huff, | 769 | uint8_t**, const uint8_t*)) xd3_decode_huff, |
754 | IF_ENCODER((int (*)(xd3_stream*, xd3_sec_stream*, xd3_output*, | 770 | IF_ENCODER((int (*)(xd3_stream*, xd3_sec_stream*, xd3_output*, |
@@ -756,6 +772,23 @@ const xd3_sec_type djw_sec_type = | |||
756 | }; | 772 | }; |
757 | #endif | 773 | #endif |
758 | 774 | ||
775 | #if HAVE_LZMA_H | ||
776 | #include "xdelta3-lzma.h" | ||
777 | const xd3_sec_type lzma_sec_type = | ||
778 | { | ||
779 | VCD_LZMA_ID, | ||
780 | "lzma", | ||
781 | SEC_NOFLAGS, | ||
782 | (xd3_sec_stream* (*)(xd3_stream*)) xd3_lzma_alloc, | ||
783 | (void (*)(xd3_stream*, xd3_sec_stream*)) xd3_lzma_destroy, | ||
784 | (int (*)(xd3_stream*, xd3_sec_stream*, int)) xd3_lzma_init, | ||
785 | (int (*)(xd3_stream*, xd3_sec_stream*, const uint8_t**, const uint8_t*, | ||
786 | uint8_t**, const uint8_t*)) xd3_decode_lzma, | ||
787 | IF_ENCODER((int (*)(xd3_stream*, xd3_sec_stream*, xd3_output*, | ||
788 | xd3_output*, xd3_sec_cfg*)) xd3_encode_lzma) | ||
789 | }; | ||
790 | #endif | ||
791 | |||
759 | #if XD3_MAIN || PYTHON_MODULE || SWIG_MODULE || NOT_MAIN | 792 | #if XD3_MAIN || PYTHON_MODULE || SWIG_MODULE || NOT_MAIN |
760 | #include "xdelta3-main.h" | 793 | #include "xdelta3-main.h" |
761 | #endif | 794 | #endif |
@@ -1678,7 +1711,7 @@ static inline int | |||
1678 | xd3_emit_bytes (xd3_stream *stream, | 1711 | xd3_emit_bytes (xd3_stream *stream, |
1679 | xd3_output **outputp, | 1712 | xd3_output **outputp, |
1680 | const uint8_t *base, | 1713 | const uint8_t *base, |
1681 | usize_t size) | 1714 | usize_t size) |
1682 | { | 1715 | { |
1683 | xd3_output *output = (*outputp); | 1716 | xd3_output *output = (*outputp); |
1684 | 1717 | ||
@@ -2381,6 +2414,8 @@ xd3_config_stream(xd3_stream *stream, | |||
2381 | FGK_CASE (stream); | 2414 | FGK_CASE (stream); |
2382 | case XD3_SEC_DJW: | 2415 | case XD3_SEC_DJW: |
2383 | DJW_CASE (stream); | 2416 | DJW_CASE (stream); |
2417 | case XD3_SEC_LZMA: | ||
2418 | LZMA_CASE (stream); | ||
2384 | default: | 2419 | default: |
2385 | stream->msg = "too many secondary compressor types set"; | 2420 | stream->msg = "too many secondary compressor types set"; |
2386 | return XD3_INTERNAL; | 2421 | return XD3_INTERNAL; |
diff --git a/xdelta3/xdelta3.h b/xdelta3/xdelta3.h index 5c1e5a5..8a94729 100644 --- a/xdelta3/xdelta3.h +++ b/xdelta3/xdelta3.h | |||
@@ -29,6 +29,8 @@ | |||
29 | #define _ISOC99_SOURCE | 29 | #define _ISOC99_SOURCE |
30 | #define _C99_SOURCE | 30 | #define _C99_SOURCE |
31 | 31 | ||
32 | #include "config.h" | ||
33 | |||
32 | #include <errno.h> | 34 | #include <errno.h> |
33 | #include <stdarg.h> | 35 | #include <stdarg.h> |
34 | #include <stddef.h> | 36 | #include <stddef.h> |
@@ -358,7 +360,9 @@ typedef enum | |||
358 | 360 | ||
359 | XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */ | 361 | XD3_SEC_DJW = (1 << 5), /* use DJW static huffman */ |
360 | XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */ | 362 | XD3_SEC_FGK = (1 << 6), /* use FGK adaptive huffman */ |
361 | XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK), | 363 | XD3_SEC_LZMA = (1 << 24), /* use LZMA secondary */ |
364 | |||
365 | XD3_SEC_TYPE = (XD3_SEC_DJW | XD3_SEC_FGK | XD3_SEC_LZMA), | ||
362 | 366 | ||
363 | XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of | 367 | XD3_SEC_NODATA = (1 << 7), /* disable secondary compression of |
364 | the data section. */ | 368 | the data section. */ |
@@ -391,7 +395,7 @@ typedef enum | |||
391 | * and is independent of compression level). This is for | 395 | * and is independent of compression level). This is for |
392 | * convenience, especially with xd3_encode_memory(). */ | 396 | * convenience, especially with xd3_encode_memory(). */ |
393 | 397 | ||
394 | XD3_COMPLEVEL_SHIFT = 20, /* 20 - 24 */ | 398 | XD3_COMPLEVEL_SHIFT = 20, /* 20 - 23 */ |
395 | XD3_COMPLEVEL_MASK = (0xF << XD3_COMPLEVEL_SHIFT), | 399 | XD3_COMPLEVEL_MASK = (0xF << XD3_COMPLEVEL_SHIFT), |
396 | XD3_COMPLEVEL_1 = (1 << XD3_COMPLEVEL_SHIFT), | 400 | XD3_COMPLEVEL_1 = (1 << XD3_COMPLEVEL_SHIFT), |
397 | XD3_COMPLEVEL_2 = (2 << XD3_COMPLEVEL_SHIFT), | 401 | XD3_COMPLEVEL_2 = (2 << XD3_COMPLEVEL_SHIFT), |