libmspack 0.0.5 → 0.10.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.github/workflows/rake.yml +37 -0
- data/.gitignore +2 -0
- data/.yardopts +1 -1
- data/README.md +1 -1
- data/Rakefile +11 -5
- data/ext/Rakefile +1 -1
- data/ext/libmspack/AUTHORS +1 -0
- data/ext/libmspack/ChangeLog +321 -4
- data/ext/libmspack/INSTALL +368 -0
- data/ext/libmspack/Makefile.am +86 -95
- data/ext/libmspack/Makefile.in +1729 -0
- data/ext/libmspack/README +30 -30
- data/ext/libmspack/acinclude.m4 +99 -0
- data/ext/libmspack/aclocal.m4 +1218 -0
- data/ext/libmspack/ar-lib +270 -0
- data/ext/libmspack/compile +347 -0
- data/ext/libmspack/config.guess +1480 -0
- data/ext/libmspack/config.h.in +129 -0
- data/ext/libmspack/config.sub +1801 -0
- data/ext/libmspack/configure +15487 -0
- data/ext/libmspack/configure.ac +11 -13
- data/ext/libmspack/depcomp +791 -0
- data/ext/libmspack/install-sh +508 -0
- data/ext/libmspack/libmscabd.la +41 -0
- data/ext/libmspack/libmschmd.la +41 -0
- data/ext/libmspack/libmspack.la +41 -0
- data/ext/libmspack/ltmain.sh +11156 -0
- data/ext/libmspack/m4/libtool.m4 +8387 -0
- data/ext/libmspack/m4/ltoptions.m4 +437 -0
- data/ext/libmspack/m4/ltsugar.m4 +124 -0
- data/ext/libmspack/m4/ltversion.m4 +23 -0
- data/ext/libmspack/m4/lt~obsolete.m4 +99 -0
- data/ext/libmspack/missing +215 -0
- data/ext/libmspack/mspack/cab.h +20 -7
- data/ext/libmspack/mspack/cabd.c +301 -236
- data/ext/libmspack/mspack/chmd.c +304 -319
- data/ext/libmspack/mspack/crc32.c +52 -52
- data/ext/libmspack/mspack/crc32.h +1 -1
- data/ext/libmspack/mspack/kwajd.c +178 -172
- data/ext/libmspack/mspack/lzss.h +4 -4
- data/ext/libmspack/mspack/lzssd.c +42 -42
- data/ext/libmspack/mspack/lzx.h +11 -11
- data/ext/libmspack/mspack/lzxd.c +370 -361
- data/ext/libmspack/mspack/mspack.h +109 -77
- data/ext/libmspack/mspack/mszip.h +6 -6
- data/ext/libmspack/mspack/mszipd.c +140 -139
- data/ext/libmspack/mspack/oab.h +1 -0
- data/ext/libmspack/mspack/oabd.c +71 -73
- data/ext/libmspack/mspack/qtm.h +4 -4
- data/ext/libmspack/mspack/qtmd.c +118 -117
- data/ext/libmspack/mspack/readbits.h +52 -52
- data/ext/libmspack/mspack/readhuff.h +61 -61
- data/ext/libmspack/mspack/system.c +15 -9
- data/ext/libmspack/mspack/system.h +38 -50
- data/ext/libmspack/mspack/szddd.c +35 -35
- data/ext/libmspack/test-driver +148 -0
- data/ext/x86_64-linux/libmspack.so +0 -0
- data/ext/x86_64-windows/mspack.dll +0 -0
- data/lib/libmspack/version.rb +2 -1
- data/lib/libmspack.rb +1 -1
- data/libmspack.gemspec +4 -4
- data/spec/libmspack_spec.rb +5 -4
- metadata +38 -105
- data/.travis.yml +0 -5
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/cleanup.sh +0 -9
- data/ext/libmspack/debian/changelog +0 -6
- data/ext/libmspack/debian/control +0 -14
- data/ext/libmspack/debian/rules +0 -101
- data/ext/libmspack/doc/Doxyfile.in +0 -22
- data/ext/libmspack/doc/Makefile.in +0 -14
- data/ext/libmspack/doc/szdd_kwaj_format.html +0 -331
- data/ext/libmspack/mspack/mspack.def +0 -28
- data/ext/libmspack/mspack/qtmc.c +0 -18
- data/ext/libmspack/rebuild.sh +0 -8
- data/ext/libmspack/test/cabd_c10 +0 -19
- data/ext/libmspack/test/cabd_compare +0 -34
- data/ext/libmspack/test/cabd_md5.c +0 -161
- data/ext/libmspack/test/cabd_memory.c +0 -179
- data/ext/libmspack/test/cabd_test.c +0 -386
- data/ext/libmspack/test/cabrip.c +0 -81
- data/ext/libmspack/test/chmd_compare +0 -38
- data/ext/libmspack/test/chmd_find.c +0 -95
- data/ext/libmspack/test/chmd_md5.c +0 -67
- data/ext/libmspack/test/chmd_order.c +0 -144
- data/ext/libmspack/test/chminfo.c +0 -284
- data/ext/libmspack/test/chmx.c +0 -216
- data/ext/libmspack/test/error.h +0 -22
- data/ext/libmspack/test/expand.c +0 -79
- data/ext/libmspack/test/md5.c +0 -457
- data/ext/libmspack/test/md5.h +0 -165
- data/ext/libmspack/test/md5_fh.h +0 -123
- data/ext/libmspack/test/msdecompile_md5 +0 -24
- data/ext/libmspack/test/msexpand_md5 +0 -39
- data/ext/libmspack/test/multifh.c +0 -435
- data/ext/libmspack/test/oabx.c +0 -41
- data/ext/libmspack/test/test_files/cabd/1.pl +0 -84
- data/ext/libmspack/test/test_files/cabd/2.pl +0 -75
- data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
- data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
- data/ext/libmspack/winbuild.sh +0 -26
- data/ext/libmspack.h +0 -259
- data/ext/x86_64-windows/libmspack.dll +0 -0
data/ext/libmspack/mspack/qtmd.c
CHANGED
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
#define BITS_TYPE struct qtmd_stream
|
|
28
28
|
#define BITS_VAR qtm
|
|
29
29
|
#define BITS_ORDER_MSB
|
|
30
|
-
#define READ_BYTES do {
|
|
31
|
-
unsigned char b0, b1;
|
|
32
|
-
READ_IF_NEEDED; b0 = *i_ptr++;
|
|
33
|
-
READ_IF_NEEDED; b1 = *i_ptr++;
|
|
34
|
-
INJECT_BITS((b0 << 8) | b1, 16);
|
|
30
|
+
#define READ_BYTES do { \
|
|
31
|
+
unsigned char b0, b1; \
|
|
32
|
+
READ_IF_NEEDED; b0 = *i_ptr++; \
|
|
33
|
+
READ_IF_NEEDED; b1 = *i_ptr++; \
|
|
34
|
+
INJECT_BITS((b0 << 8) | b1, 16); \
|
|
35
35
|
} while (0)
|
|
36
36
|
#include <readbits.h>
|
|
37
37
|
|
|
@@ -115,7 +115,7 @@ static const unsigned char length_extra[27] = {
|
|
|
115
115
|
else break; \
|
|
116
116
|
} \
|
|
117
117
|
L <<= 1; H = (H << 1) | 1; \
|
|
118
|
-
ENSURE_BITS(1);
|
|
118
|
+
ENSURE_BITS(1); \
|
|
119
119
|
C = (C << 1) | PEEK_BITS(1); \
|
|
120
120
|
REMOVE_BITS(1); \
|
|
121
121
|
} \
|
|
@@ -130,7 +130,7 @@ static void qtmd_update_model(struct qtmd_model *model) {
|
|
|
130
130
|
/* -1, not -2; the 0 entry saves this */
|
|
131
131
|
model->syms[i].cumfreq >>= 1;
|
|
132
132
|
if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
|
|
133
|
-
|
|
133
|
+
model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
}
|
|
@@ -149,11 +149,11 @@ static void qtmd_update_model(struct qtmd_model *model) {
|
|
|
149
149
|
* characteristics */
|
|
150
150
|
for (i = 0; i < model->entries - 1; i++) {
|
|
151
151
|
for (j = i + 1; j < model->entries; j++) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
|
|
153
|
+
tmp = model->syms[i];
|
|
154
|
+
model->syms[i] = model->syms[j];
|
|
155
|
+
model->syms[j] = tmp;
|
|
156
|
+
}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
@@ -166,7 +166,7 @@ static void qtmd_update_model(struct qtmd_model *model) {
|
|
|
166
166
|
|
|
167
167
|
/* Initialises a model to decode symbols from [start] to [start]+[len]-1 */
|
|
168
168
|
static void qtmd_init_model(struct qtmd_model *model,
|
|
169
|
-
|
|
169
|
+
struct qtmd_modelsym *syms, int start, int len)
|
|
170
170
|
{
|
|
171
171
|
int i;
|
|
172
172
|
|
|
@@ -184,9 +184,9 @@ static void qtmd_init_model(struct qtmd_model *model,
|
|
|
184
184
|
/*-------- main Quantum code --------*/
|
|
185
185
|
|
|
186
186
|
struct qtmd_stream *qtmd_init(struct mspack_system *system,
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
struct mspack_file *input,
|
|
188
|
+
struct mspack_file *output,
|
|
189
|
+
int window_bits, int input_buffer_size)
|
|
190
190
|
{
|
|
191
191
|
unsigned int window_size = 1 << window_bits;
|
|
192
192
|
struct qtmd_stream *qtm;
|
|
@@ -197,6 +197,7 @@ struct qtmd_stream *qtmd_init(struct mspack_system *system,
|
|
|
197
197
|
/* Quantum supports window sizes of 2^10 (1Kb) through 2^21 (2Mb) */
|
|
198
198
|
if (window_bits < 10 || window_bits > 21) return NULL;
|
|
199
199
|
|
|
200
|
+
/* round up input buffer size to multiple of two */
|
|
200
201
|
input_buffer_size = (input_buffer_size + 1) & -2;
|
|
201
202
|
if (input_buffer_size < 2) return NULL;
|
|
202
203
|
|
|
@@ -307,113 +308,113 @@ int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
|
|
|
307
308
|
while (window_posn < frame_end) {
|
|
308
309
|
GET_SYMBOL(qtm->model7, selector);
|
|
309
310
|
if (selector < 4) {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
311
|
+
/* literal byte */
|
|
312
|
+
struct qtmd_model *mdl = (selector == 0) ? &qtm->model0 :
|
|
313
|
+
((selector == 1) ? &qtm->model1 :
|
|
314
|
+
((selector == 2) ? &qtm->model2 :
|
|
314
315
|
&qtm->model3));
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
316
|
+
GET_SYMBOL((*mdl), sym);
|
|
317
|
+
window[window_posn++] = sym;
|
|
318
|
+
frame_todo--;
|
|
318
319
|
}
|
|
319
320
|
else {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
321
|
+
/* match repeated string */
|
|
322
|
+
switch (selector) {
|
|
323
|
+
case 4: /* selector 4 = fixed length match (3 bytes) */
|
|
324
|
+
GET_SYMBOL(qtm->model4, sym);
|
|
325
|
+
READ_MANY_BITS(extra, extra_bits[sym]);
|
|
326
|
+
match_offset = position_base[sym] + extra + 1;
|
|
327
|
+
match_length = 3;
|
|
328
|
+
break;
|
|
329
|
+
|
|
330
|
+
case 5: /* selector 5 = fixed length match (4 bytes) */
|
|
331
|
+
GET_SYMBOL(qtm->model5, sym);
|
|
332
|
+
READ_MANY_BITS(extra, extra_bits[sym]);
|
|
333
|
+
match_offset = position_base[sym] + extra + 1;
|
|
334
|
+
match_length = 4;
|
|
335
|
+
break;
|
|
336
|
+
|
|
337
|
+
case 6: /* selector 6 = variable length match */
|
|
338
|
+
GET_SYMBOL(qtm->model6len, sym);
|
|
339
|
+
READ_MANY_BITS(extra, length_extra[sym]);
|
|
340
|
+
match_length = length_base[sym] + extra + 5;
|
|
341
|
+
|
|
342
|
+
GET_SYMBOL(qtm->model6, sym);
|
|
343
|
+
READ_MANY_BITS(extra, extra_bits[sym]);
|
|
344
|
+
match_offset = position_base[sym] + extra + 1;
|
|
345
|
+
break;
|
|
346
|
+
|
|
347
|
+
default:
|
|
348
|
+
/* should be impossible, model7 can only return 0-6 */
|
|
349
|
+
D(("got %d from selector", selector))
|
|
350
|
+
return qtm->error = MSPACK_ERR_DECRUNCH;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
rundest = &window[window_posn];
|
|
354
|
+
frame_todo -= match_length;
|
|
355
|
+
|
|
356
|
+
/* does match destination wrap the window? This situation is possible
|
|
357
|
+
* where the window size is less than the 32k frame size, but matches
|
|
358
|
+
* must not go beyond a frame boundary */
|
|
359
|
+
if ((window_posn + match_length) > qtm->window_size) {
|
|
359
360
|
/* copy first part of match, before window end */
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
361
|
+
i = qtm->window_size - window_posn;
|
|
362
|
+
j = window_posn - match_offset;
|
|
363
|
+
while (i--) *rundest++ = window[j++ & (qtm->window_size - 1)];
|
|
364
|
+
|
|
365
|
+
/* flush currently stored data */
|
|
366
|
+
i = (&window[qtm->window_size] - qtm->o_ptr);
|
|
367
|
+
|
|
368
|
+
/* this should not happen, but if it does then this code
|
|
369
|
+
* can't handle the situation (can't flush up to the end of
|
|
370
|
+
* the window, but can't break out either because we haven't
|
|
371
|
+
* finished writing the match). bail out in this case */
|
|
372
|
+
if (i > out_bytes) {
|
|
373
|
+
D(("during window-wrap match; %d bytes to flush but only need %d",
|
|
374
|
+
i, (int) out_bytes))
|
|
375
|
+
return qtm->error = MSPACK_ERR_DECRUNCH;
|
|
376
|
+
}
|
|
377
|
+
if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
|
|
378
|
+
return qtm->error = MSPACK_ERR_WRITE;
|
|
379
|
+
}
|
|
380
|
+
out_bytes -= i;
|
|
381
|
+
qtm->o_ptr = &window[0];
|
|
382
|
+
qtm->o_end = &window[0];
|
|
383
|
+
|
|
384
|
+
/* copy second part of match, after window wrap */
|
|
385
|
+
rundest = &window[0];
|
|
386
|
+
i = match_length - (qtm->window_size - window_posn);
|
|
387
|
+
while (i--) *rundest++ = window[j++ & (qtm->window_size - 1)];
|
|
388
|
+
window_posn = window_posn + match_length - qtm->window_size;
|
|
388
389
|
|
|
389
390
|
break; /* because "window_posn < frame_end" has now failed */
|
|
390
|
-
|
|
391
|
-
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
392
393
|
/* normal match - output won't wrap window or frame end */
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
394
|
+
i = match_length;
|
|
395
|
+
|
|
396
|
+
/* does match _offset_ wrap the window? */
|
|
397
|
+
if (match_offset > window_posn) {
|
|
398
|
+
/* j = length from match offset to end of window */
|
|
399
|
+
j = match_offset - window_posn;
|
|
400
|
+
if (j > (int) qtm->window_size) {
|
|
401
|
+
D(("match offset beyond window boundaries"))
|
|
402
|
+
return qtm->error = MSPACK_ERR_DECRUNCH;
|
|
403
|
+
}
|
|
404
|
+
runsrc = &window[qtm->window_size - j];
|
|
405
|
+
if (j < i) {
|
|
406
|
+
/* if match goes over the window edge, do two copy runs */
|
|
407
|
+
i -= j; while (j-- > 0) *rundest++ = *runsrc++;
|
|
408
|
+
runsrc = window;
|
|
409
|
+
}
|
|
410
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
runsrc = rundest - match_offset;
|
|
414
|
+
while (i-- > 0) *rundest++ = *runsrc++;
|
|
415
|
+
}
|
|
416
|
+
window_posn += match_length;
|
|
417
|
+
}
|
|
417
418
|
} /* if (window_posn+match_length > frame_end) */
|
|
418
419
|
} /* while (window_posn < frame_end) */
|
|
419
420
|
|
|
@@ -448,7 +449,7 @@ int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes) {
|
|
|
448
449
|
/* break out if we have more than enough to finish this request */
|
|
449
450
|
if (i >= out_bytes) break;
|
|
450
451
|
if (qtm->sys->write(qtm->output, qtm->o_ptr, i) != i) {
|
|
451
|
-
|
|
452
|
+
return qtm->error = MSPACK_ERR_WRITE;
|
|
452
453
|
}
|
|
453
454
|
out_bytes -= i;
|
|
454
455
|
qtm->o_ptr = &window[0];
|
|
@@ -100,48 +100,48 @@
|
|
|
100
100
|
#endif
|
|
101
101
|
#define BITBUF_WIDTH (sizeof(bit_buffer) * CHAR_BIT)
|
|
102
102
|
|
|
103
|
-
#define INIT_BITS do {
|
|
104
|
-
BITS_VAR->i_ptr = &BITS_VAR->inbuf[0];
|
|
105
|
-
BITS_VAR->i_end = &BITS_VAR->inbuf[0];
|
|
106
|
-
BITS_VAR->bit_buffer = 0;
|
|
107
|
-
BITS_VAR->bits_left = 0;
|
|
108
|
-
BITS_VAR->input_end = 0;
|
|
103
|
+
#define INIT_BITS do { \
|
|
104
|
+
BITS_VAR->i_ptr = &BITS_VAR->inbuf[0]; \
|
|
105
|
+
BITS_VAR->i_end = &BITS_VAR->inbuf[0]; \
|
|
106
|
+
BITS_VAR->bit_buffer = 0; \
|
|
107
|
+
BITS_VAR->bits_left = 0; \
|
|
108
|
+
BITS_VAR->input_end = 0; \
|
|
109
109
|
} while (0)
|
|
110
110
|
|
|
111
|
-
#define STORE_BITS do {
|
|
112
|
-
BITS_VAR->i_ptr = i_ptr;
|
|
113
|
-
BITS_VAR->i_end = i_end;
|
|
114
|
-
BITS_VAR->bit_buffer = bit_buffer;
|
|
115
|
-
BITS_VAR->bits_left = bits_left;
|
|
111
|
+
#define STORE_BITS do { \
|
|
112
|
+
BITS_VAR->i_ptr = i_ptr; \
|
|
113
|
+
BITS_VAR->i_end = i_end; \
|
|
114
|
+
BITS_VAR->bit_buffer = bit_buffer; \
|
|
115
|
+
BITS_VAR->bits_left = bits_left; \
|
|
116
116
|
} while (0)
|
|
117
117
|
|
|
118
|
-
#define RESTORE_BITS do {
|
|
119
|
-
i_ptr = BITS_VAR->i_ptr;
|
|
120
|
-
i_end = BITS_VAR->i_end;
|
|
121
|
-
bit_buffer = BITS_VAR->bit_buffer;
|
|
122
|
-
bits_left = BITS_VAR->bits_left;
|
|
118
|
+
#define RESTORE_BITS do { \
|
|
119
|
+
i_ptr = BITS_VAR->i_ptr; \
|
|
120
|
+
i_end = BITS_VAR->i_end; \
|
|
121
|
+
bit_buffer = BITS_VAR->bit_buffer; \
|
|
122
|
+
bits_left = BITS_VAR->bits_left; \
|
|
123
123
|
} while (0)
|
|
124
124
|
|
|
125
|
-
#define ENSURE_BITS(nbits) do {
|
|
126
|
-
while (bits_left < (nbits)) READ_BYTES;
|
|
125
|
+
#define ENSURE_BITS(nbits) do { \
|
|
126
|
+
while (bits_left < (nbits)) READ_BYTES; \
|
|
127
127
|
} while (0)
|
|
128
128
|
|
|
129
|
-
#define READ_BITS(val, nbits) do {
|
|
130
|
-
ENSURE_BITS(nbits);
|
|
131
|
-
(val) = PEEK_BITS(nbits);
|
|
132
|
-
REMOVE_BITS(nbits);
|
|
129
|
+
#define READ_BITS(val, nbits) do { \
|
|
130
|
+
ENSURE_BITS(nbits); \
|
|
131
|
+
(val) = PEEK_BITS(nbits); \
|
|
132
|
+
REMOVE_BITS(nbits); \
|
|
133
133
|
} while (0)
|
|
134
134
|
|
|
135
|
-
#define READ_MANY_BITS(val, bits) do {
|
|
136
|
-
unsigned char needed = (bits), bitrun;
|
|
137
|
-
(val) = 0;
|
|
138
|
-
while (needed > 0) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
135
|
+
#define READ_MANY_BITS(val, bits) do { \
|
|
136
|
+
unsigned char needed = (bits), bitrun; \
|
|
137
|
+
(val) = 0; \
|
|
138
|
+
while (needed > 0) { \
|
|
139
|
+
if (bits_left <= (BITBUF_WIDTH - 16)) READ_BYTES; \
|
|
140
|
+
bitrun = (bits_left < needed) ? bits_left : needed; \
|
|
141
|
+
(val) = ((val) << bitrun) | PEEK_BITS(bitrun); \
|
|
142
|
+
REMOVE_BITS(bitrun); \
|
|
143
|
+
needed -= bitrun; \
|
|
144
|
+
} \
|
|
145
145
|
} while (0)
|
|
146
146
|
|
|
147
147
|
#ifdef BITS_ORDER_MSB
|
|
@@ -163,21 +163,21 @@ static const unsigned short lsb_bit_mask[17] = {
|
|
|
163
163
|
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
|
|
164
164
|
};
|
|
165
165
|
# define PEEK_BITS_T(nbits) (bit_buffer & lsb_bit_mask[(nbits)])
|
|
166
|
-
# define READ_BITS_T(val, nbits) do {
|
|
167
|
-
ENSURE_BITS(nbits);
|
|
168
|
-
(val) = PEEK_BITS_T(nbits);
|
|
169
|
-
REMOVE_BITS(nbits);
|
|
166
|
+
# define READ_BITS_T(val, nbits) do { \
|
|
167
|
+
ENSURE_BITS(nbits); \
|
|
168
|
+
(val) = PEEK_BITS_T(nbits); \
|
|
169
|
+
REMOVE_BITS(nbits); \
|
|
170
170
|
} while (0)
|
|
171
171
|
#endif
|
|
172
172
|
|
|
173
173
|
#ifndef BITS_NO_READ_INPUT
|
|
174
|
-
# define READ_IF_NEEDED do {
|
|
175
|
-
if (i_ptr >= i_end) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
174
|
+
# define READ_IF_NEEDED do { \
|
|
175
|
+
if (i_ptr >= i_end) { \
|
|
176
|
+
if (read_input(BITS_VAR)) \
|
|
177
|
+
return BITS_VAR->error; \
|
|
178
|
+
i_ptr = BITS_VAR->i_ptr; \
|
|
179
|
+
i_end = BITS_VAR->i_end; \
|
|
180
|
+
} \
|
|
181
181
|
} while (0)
|
|
182
182
|
|
|
183
183
|
static int read_input(BITS_TYPE *p) {
|
|
@@ -187,15 +187,15 @@ static int read_input(BITS_TYPE *p) {
|
|
|
187
187
|
/* we might overrun the input stream by asking for bits we don't use,
|
|
188
188
|
* so fake 2 more bytes at the end of input */
|
|
189
189
|
if (read == 0) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
190
|
+
if (p->input_end) {
|
|
191
|
+
D(("out of input bytes"))
|
|
192
|
+
return p->error = MSPACK_ERR_READ;
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
read = 2;
|
|
196
|
+
p->inbuf[0] = p->inbuf[1] = 0;
|
|
197
|
+
p->input_end = 1;
|
|
198
|
+
}
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/* update i_ptr and i_end */
|
|
@@ -31,32 +31,32 @@
|
|
|
31
31
|
/* Decodes the next huffman symbol from the input bitstream into var.
|
|
32
32
|
* Do not use this macro on a table unless build_decode_table() succeeded.
|
|
33
33
|
*/
|
|
34
|
-
#define READ_HUFFSYM(tbl, var) do {
|
|
35
|
-
ENSURE_BITS(HUFF_MAXBITS);
|
|
36
|
-
sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl)));
|
|
37
|
-
if (sym >= MAXSYMBOLS(tbl))
|
|
38
|
-
(var) = sym;
|
|
39
|
-
i = HUFF_LEN(tbl, sym);
|
|
40
|
-
REMOVE_BITS(i);
|
|
34
|
+
#define READ_HUFFSYM(tbl, var) do { \
|
|
35
|
+
ENSURE_BITS(HUFF_MAXBITS); \
|
|
36
|
+
sym = HUFF_TABLE(tbl, PEEK_BITS(TABLEBITS(tbl))); \
|
|
37
|
+
if (sym >= MAXSYMBOLS(tbl)) HUFF_TRAVERSE(tbl); \
|
|
38
|
+
(var) = sym; \
|
|
39
|
+
i = HUFF_LEN(tbl, sym); \
|
|
40
|
+
REMOVE_BITS(i); \
|
|
41
41
|
} while (0)
|
|
42
42
|
|
|
43
43
|
#ifdef BITS_ORDER_LSB
|
|
44
|
-
# define HUFF_TRAVERSE(tbl) do {
|
|
45
|
-
i = TABLEBITS(tbl) - 1;
|
|
46
|
-
do {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
(sym << 1) | ((bit_buffer >> i) & 1));
|
|
50
|
-
} while (sym >= MAXSYMBOLS(tbl));
|
|
44
|
+
# define HUFF_TRAVERSE(tbl) do { \
|
|
45
|
+
i = TABLEBITS(tbl) - 1; \
|
|
46
|
+
do { \
|
|
47
|
+
if (i++ > HUFF_MAXBITS) HUFF_ERROR; \
|
|
48
|
+
sym = HUFF_TABLE(tbl, \
|
|
49
|
+
(sym << 1) | ((bit_buffer >> i) & 1)); \
|
|
50
|
+
} while (sym >= MAXSYMBOLS(tbl)); \
|
|
51
51
|
} while (0)
|
|
52
52
|
#else
|
|
53
|
-
#define HUFF_TRAVERSE(tbl) do {
|
|
54
|
-
i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl));
|
|
55
|
-
do {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
} while (sym >= MAXSYMBOLS(tbl));
|
|
53
|
+
#define HUFF_TRAVERSE(tbl) do { \
|
|
54
|
+
i = 1 << (BITBUF_WIDTH - TABLEBITS(tbl)); \
|
|
55
|
+
do { \
|
|
56
|
+
if ((i >>= 1) == 0) HUFF_ERROR; \
|
|
57
|
+
sym = HUFF_TABLE(tbl, \
|
|
58
|
+
(sym << 1) | ((bit_buffer & i) ? 1 : 0)); \
|
|
59
|
+
} while (sym >= MAXSYMBOLS(tbl)); \
|
|
60
60
|
} while (0)
|
|
61
61
|
#endif
|
|
62
62
|
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
* Returns 0 for OK or 1 for error
|
|
77
77
|
*/
|
|
78
78
|
static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
|
79
|
-
|
|
79
|
+
unsigned char *length, unsigned short *table)
|
|
80
80
|
{
|
|
81
81
|
register unsigned short sym, next_symbol;
|
|
82
82
|
register unsigned int leaf, fill;
|
|
@@ -90,27 +90,27 @@ static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
|
|
90
90
|
|
|
91
91
|
/* fill entries for codes short enough for a direct mapping */
|
|
92
92
|
for (bit_num = 1; bit_num <= nbits; bit_num++) {
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
for (sym = 0; sym < nsyms; sym++) {
|
|
94
|
+
if (length[sym] != bit_num) continue;
|
|
95
95
|
#ifdef BITS_ORDER_MSB
|
|
96
|
-
|
|
96
|
+
leaf = pos;
|
|
97
97
|
#else
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
98
|
+
/* reverse the significant bits */
|
|
99
|
+
fill = length[sym]; reverse = pos >> (nbits - fill); leaf = 0;
|
|
100
|
+
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
|
101
101
|
#endif
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
if((pos += bit_mask) > table_mask) return 1; /* table overrun */
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
/* fill all possible lookups of this symbol with the symbol itself */
|
|
106
106
|
#ifdef BITS_ORDER_MSB
|
|
107
|
-
|
|
107
|
+
for (fill = bit_mask; fill-- > 0;) table[leaf++] = sym;
|
|
108
108
|
#else
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
fill = bit_mask; next_symbol = 1 << bit_num;
|
|
110
|
+
do { table[leaf] = sym; leaf += next_symbol; } while (--fill);
|
|
111
111
|
#endif
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
}
|
|
113
|
+
bit_mask >>= 1;
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/* exit with success if table is now complete */
|
|
@@ -119,11 +119,11 @@ static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
|
|
119
119
|
/* mark all remaining table entries as unused */
|
|
120
120
|
for (sym = pos; sym < table_mask; sym++) {
|
|
121
121
|
#ifdef BITS_ORDER_MSB
|
|
122
|
-
|
|
122
|
+
table[sym] = 0xFFFF;
|
|
123
123
|
#else
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
reverse = sym; leaf = 0; fill = nbits;
|
|
125
|
+
do { leaf <<= 1; leaf |= reverse & 1; reverse >>= 1; } while (--fill);
|
|
126
|
+
table[leaf] = 0xFFFF;
|
|
127
127
|
#endif
|
|
128
128
|
}
|
|
129
129
|
|
|
@@ -137,33 +137,33 @@ static int make_decode_table(unsigned int nsyms, unsigned int nbits,
|
|
|
137
137
|
bit_mask = 1 << 15;
|
|
138
138
|
|
|
139
139
|
for (bit_num = nbits+1; bit_num <= HUFF_MAXBITS; bit_num++) {
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
for (sym = 0; sym < nsyms; sym++) {
|
|
141
|
+
if (length[sym] != bit_num) continue;
|
|
142
142
|
if (pos >= table_mask) return 1; /* table overflow */
|
|
143
143
|
|
|
144
144
|
#ifdef BITS_ORDER_MSB
|
|
145
|
-
|
|
145
|
+
leaf = pos >> 16;
|
|
146
146
|
#else
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
/* leaf = the first nbits of the code, reversed */
|
|
148
|
+
reverse = pos >> 16; leaf = 0; fill = nbits;
|
|
149
|
+
do {leaf <<= 1; leaf |= reverse & 1; reverse >>= 1;} while (--fill);
|
|
150
150
|
#endif
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
151
|
+
for (fill = 0; fill < (bit_num - nbits); fill++) {
|
|
152
|
+
/* if this path hasn't been taken yet, 'allocate' two entries */
|
|
153
|
+
if (table[leaf] == 0xFFFF) {
|
|
154
|
+
table[(next_symbol << 1) ] = 0xFFFF;
|
|
155
|
+
table[(next_symbol << 1) + 1 ] = 0xFFFF;
|
|
156
|
+
table[leaf] = next_symbol++;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* follow the path and select either left or right for next bit */
|
|
160
|
+
leaf = table[leaf] << 1;
|
|
161
|
+
if ((pos >> (15-fill)) & 1) leaf++;
|
|
162
|
+
}
|
|
163
|
+
table[leaf] = sym;
|
|
164
|
+
pos += bit_mask;
|
|
165
|
+
}
|
|
166
|
+
bit_mask >>= 1;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
/* full table? */
|