libmspack 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +5 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/README.md +75 -0
- data/Rakefile +22 -0
- data/UNLICENSE +24 -0
- data/ext/Rakefile +16 -0
- data/ext/i386-windows/libmspack.dll +0 -0
- data/ext/libmspack/AUTHORS +12 -0
- data/ext/libmspack/COPYING.LIB +504 -0
- data/ext/libmspack/ChangeLog +491 -0
- data/ext/libmspack/Makefile.am +100 -0
- data/ext/libmspack/NEWS +0 -0
- data/ext/libmspack/README +130 -0
- data/ext/libmspack/TODO +8 -0
- data/ext/libmspack/cleanup.sh +9 -0
- data/ext/libmspack/configure.ac +50 -0
- data/ext/libmspack/debian/changelog +6 -0
- data/ext/libmspack/debian/control +14 -0
- data/ext/libmspack/debian/rules +101 -0
- data/ext/libmspack/doc/Doxyfile.in +22 -0
- data/ext/libmspack/doc/Makefile.in +14 -0
- data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
- data/ext/libmspack/libmspack.pc.in +10 -0
- data/ext/libmspack/mspack/cab.h +127 -0
- data/ext/libmspack/mspack/cabc.c +24 -0
- data/ext/libmspack/mspack/cabd.c +1444 -0
- data/ext/libmspack/mspack/chm.h +122 -0
- data/ext/libmspack/mspack/chmc.c +24 -0
- data/ext/libmspack/mspack/chmd.c +1392 -0
- data/ext/libmspack/mspack/crc32.c +95 -0
- data/ext/libmspack/mspack/crc32.h +17 -0
- data/ext/libmspack/mspack/des.h +15 -0
- data/ext/libmspack/mspack/hlp.h +33 -0
- data/ext/libmspack/mspack/hlpc.c +24 -0
- data/ext/libmspack/mspack/hlpd.c +24 -0
- data/ext/libmspack/mspack/kwaj.h +118 -0
- data/ext/libmspack/mspack/kwajc.c +24 -0
- data/ext/libmspack/mspack/kwajd.c +561 -0
- data/ext/libmspack/mspack/lit.h +35 -0
- data/ext/libmspack/mspack/litc.c +24 -0
- data/ext/libmspack/mspack/litd.c +24 -0
- data/ext/libmspack/mspack/lzss.h +66 -0
- data/ext/libmspack/mspack/lzssd.c +93 -0
- data/ext/libmspack/mspack/lzx.h +221 -0
- data/ext/libmspack/mspack/lzxc.c +18 -0
- data/ext/libmspack/mspack/lzxd.c +895 -0
- data/ext/libmspack/mspack/mspack.def +28 -0
- data/ext/libmspack/mspack/mspack.h +2353 -0
- data/ext/libmspack/mspack/mszip.h +126 -0
- data/ext/libmspack/mspack/mszipc.c +18 -0
- data/ext/libmspack/mspack/mszipd.c +514 -0
- data/ext/libmspack/mspack/oab.h +60 -0
- data/ext/libmspack/mspack/oabc.c +24 -0
- data/ext/libmspack/mspack/oabd.c +408 -0
- data/ext/libmspack/mspack/qtm.h +128 -0
- data/ext/libmspack/mspack/qtmc.c +18 -0
- data/ext/libmspack/mspack/qtmd.c +489 -0
- data/ext/libmspack/mspack/readbits.h +207 -0
- data/ext/libmspack/mspack/readhuff.h +173 -0
- data/ext/libmspack/mspack/sha.h +15 -0
- data/ext/libmspack/mspack/system.c +239 -0
- data/ext/libmspack/mspack/system.h +124 -0
- data/ext/libmspack/mspack/szdd.h +39 -0
- data/ext/libmspack/mspack/szddc.c +24 -0
- data/ext/libmspack/mspack/szddd.c +247 -0
- data/ext/libmspack/rebuild.sh +8 -0
- data/ext/libmspack/test/cabd_c10 +19 -0
- data/ext/libmspack/test/cabd_compare +34 -0
- data/ext/libmspack/test/cabd_md5.c +161 -0
- data/ext/libmspack/test/cabd_memory.c +179 -0
- data/ext/libmspack/test/cabd_test.c +386 -0
- data/ext/libmspack/test/cabrip.c +81 -0
- data/ext/libmspack/test/chmd_compare +38 -0
- data/ext/libmspack/test/chmd_find.c +95 -0
- data/ext/libmspack/test/chmd_md5.c +67 -0
- data/ext/libmspack/test/chmd_order.c +144 -0
- data/ext/libmspack/test/chminfo.c +284 -0
- data/ext/libmspack/test/chmx.c +216 -0
- data/ext/libmspack/test/error.h +22 -0
- data/ext/libmspack/test/expand.c +79 -0
- data/ext/libmspack/test/md5.c +457 -0
- data/ext/libmspack/test/md5.h +165 -0
- data/ext/libmspack/test/md5_fh.h +123 -0
- data/ext/libmspack/test/msdecompile_md5 +24 -0
- data/ext/libmspack/test/msexpand_md5 +39 -0
- data/ext/libmspack/test/multifh.c +435 -0
- data/ext/libmspack/test/oabx.c +41 -0
- data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
- data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
- 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 +26 -0
- data/ext/x86_64-windows/libmspack.dll +0 -0
- data/lib/libmspack/constants.rb +9 -0
- data/lib/libmspack/exceptions.rb +12 -0
- data/lib/libmspack/mscab.rb +722 -0
- data/lib/libmspack/mschm.rb +301 -0
- data/lib/libmspack/mshlp.rb +15 -0
- data/lib/libmspack/mskwaj.rb +124 -0
- data/lib/libmspack/mslit.rb +18 -0
- data/lib/libmspack/msoab.rb +36 -0
- data/lib/libmspack/mspack.rb +208 -0
- data/lib/libmspack/msszdd.rb +81 -0
- data/lib/libmspack/system.rb +84 -0
- data/lib/libmspack/version.rb +4 -0
- data/lib/libmspack.rb +121 -0
- data/libmspack.gemspec +33 -0
- data/spec/libmspack_spec.rb +26 -0
- data/spec/spec_helper.rb +5 -0
- metadata +309 -0
@@ -0,0 +1,60 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* © 2013 Intel Corporation
|
3
|
+
*
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
6
|
+
*
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
#ifndef MSPACK_OAB_H
|
11
|
+
#define MSPACK_OAB_H 1
|
12
|
+
|
13
|
+
#include <system.h>
|
14
|
+
|
15
|
+
/* generic OAB definitions */
|
16
|
+
|
17
|
+
/* OAB compression definitions */
|
18
|
+
|
19
|
+
struct msoab_compressor_p {
|
20
|
+
struct msoab_compressor base;
|
21
|
+
struct mspack_system *system;
|
22
|
+
/* todo */
|
23
|
+
};
|
24
|
+
|
25
|
+
/* OAB decompression definitions */
|
26
|
+
|
27
|
+
struct msoab_decompressor_p {
|
28
|
+
struct msoab_decompressor base;
|
29
|
+
struct mspack_system *system;
|
30
|
+
/* todo */
|
31
|
+
};
|
32
|
+
|
33
|
+
#define oabhead_VersionHi (0x0000)
|
34
|
+
#define oabhead_VersionLo (0x0004)
|
35
|
+
#define oabhead_BlockMax (0x0008)
|
36
|
+
#define oabhead_TargetSize (0x000c)
|
37
|
+
#define oabhead_SIZEOF (0x0010)
|
38
|
+
|
39
|
+
#define oabblk_Flags (0x0000)
|
40
|
+
#define oabblk_CompSize (0x0004)
|
41
|
+
#define oabblk_UncompSize (0x0008)
|
42
|
+
#define oabblk_CRC (0x000c)
|
43
|
+
#define oabblk_SIZEOF (0x0010)
|
44
|
+
|
45
|
+
#define patchhead_VersionHi (0x0000)
|
46
|
+
#define patchhead_VersionLo (0x0004)
|
47
|
+
#define patchhead_BlockMax (0x0008)
|
48
|
+
#define patchhead_SourceSize (0x000c)
|
49
|
+
#define patchhead_TargetSize (0x0010)
|
50
|
+
#define patchhead_SourceCRC (0x0014)
|
51
|
+
#define patchhead_TargetCRC (0x0018)
|
52
|
+
#define patchhead_SIZEOF (0x001c)
|
53
|
+
|
54
|
+
#define patchblk_PatchSize (0x0000)
|
55
|
+
#define patchblk_TargetSize (0x0004)
|
56
|
+
#define patchblk_SourceSize (0x0008)
|
57
|
+
#define patchblk_CRC (0x000c)
|
58
|
+
#define patchblk_SIZEOF (0x0010)
|
59
|
+
|
60
|
+
#endif
|
@@ -0,0 +1,24 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* © 2013 Intel Corporation
|
3
|
+
*
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
6
|
+
*
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* OAB compression implementation */
|
11
|
+
|
12
|
+
#include <system.h>
|
13
|
+
#include <oab.h>
|
14
|
+
|
15
|
+
struct msoab_compressor *
|
16
|
+
mspack_create_oab_compressor(struct mspack_system *sys)
|
17
|
+
{
|
18
|
+
/* todo */
|
19
|
+
return NULL;
|
20
|
+
}
|
21
|
+
|
22
|
+
void mspack_destroy_oab_compressor(struct msoab_compressor *self) {
|
23
|
+
/* todo */
|
24
|
+
}
|
@@ -0,0 +1,408 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* © 2013 Intel Corporation
|
3
|
+
*
|
4
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
5
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
6
|
+
*
|
7
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
8
|
+
*/
|
9
|
+
|
10
|
+
/* The Exchange Online Addressbook (OAB or sometimes OAL) is distributed
|
11
|
+
* as a .LZX file in one of two forms. Either a "full download" containing
|
12
|
+
* the entire address list, or an incremental binary patch which should be
|
13
|
+
* applied to a previous version of the full decompressed data.
|
14
|
+
*
|
15
|
+
* The contents and format of the decompressed OAB are not handled here.
|
16
|
+
*
|
17
|
+
* For a complete description of the format, see the MSDN site:
|
18
|
+
*
|
19
|
+
* http://msdn.microsoft.com/en-us/library/cc463914 - [MS-OXOAB].pdf
|
20
|
+
* http://msdn.microsoft.com/en-us/library/cc483133 - [MS-PATCH].pdf
|
21
|
+
*/
|
22
|
+
|
23
|
+
/* OAB decompression implementation */
|
24
|
+
|
25
|
+
#include <system.h>
|
26
|
+
#include <oab.h>
|
27
|
+
#include <lzx.h>
|
28
|
+
#include <crc32.h>
|
29
|
+
|
30
|
+
/* prototypes */
|
31
|
+
static int oabd_decompress(struct msoab_decompressor *self, const char *input,
|
32
|
+
const char *output);
|
33
|
+
static int oabd_decompress_incremental(struct msoab_decompressor *self,
|
34
|
+
const char *input, const char *base,
|
35
|
+
const char *output);
|
36
|
+
|
37
|
+
struct msoab_decompressor *
|
38
|
+
mspack_create_oab_decompressor(struct mspack_system *sys)
|
39
|
+
{
|
40
|
+
struct msoab_decompressor_p *self = NULL;
|
41
|
+
|
42
|
+
if (!sys) sys = mspack_default_system;
|
43
|
+
if (!mspack_valid_system(sys)) return NULL;
|
44
|
+
|
45
|
+
if ((self = (struct msoab_decompressor_p *) sys->alloc(sys, sizeof(struct msoab_decompressor_p)))) {
|
46
|
+
self->base.decompress = &oabd_decompress;
|
47
|
+
self->base.decompress_incremental = &oabd_decompress_incremental;
|
48
|
+
self->system = sys;
|
49
|
+
}
|
50
|
+
return (struct msoab_decompressor *) self;
|
51
|
+
}
|
52
|
+
|
53
|
+
void mspack_destroy_oab_decompressor(struct msoab_decompressor *base) {
|
54
|
+
struct msoab_decompressor_p *self = (struct msoab_decompressor_p *)base;
|
55
|
+
if (self) {
|
56
|
+
struct mspack_system *sys = self->system;
|
57
|
+
sys->free(self);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
struct oabd_file {
|
62
|
+
struct mspack_system *orig_sys;
|
63
|
+
struct mspack_file *orig_file;
|
64
|
+
unsigned int crc;
|
65
|
+
size_t available;
|
66
|
+
};
|
67
|
+
|
68
|
+
|
69
|
+
static int oabd_sys_read (struct mspack_file *base_file, void *buf, int size)
|
70
|
+
{
|
71
|
+
struct oabd_file *file = (struct oabd_file *)base_file;
|
72
|
+
int bytes_read;
|
73
|
+
|
74
|
+
if ((size_t)size > file->available)
|
75
|
+
size = file->available;
|
76
|
+
|
77
|
+
bytes_read = file->orig_sys->read(file->orig_file, buf, size);
|
78
|
+
if (bytes_read < 0)
|
79
|
+
return bytes_read;
|
80
|
+
|
81
|
+
file->available -= bytes_read;
|
82
|
+
return bytes_read;
|
83
|
+
}
|
84
|
+
|
85
|
+
static int oabd_sys_write (struct mspack_file *base_file, void *buf, int size)
|
86
|
+
{
|
87
|
+
struct oabd_file *file = (struct oabd_file *)base_file;
|
88
|
+
int bytes_written = file->orig_sys->write(file->orig_file, buf, size);
|
89
|
+
|
90
|
+
if (bytes_written > 0)
|
91
|
+
file->crc = crc32(file->crc, buf, bytes_written);
|
92
|
+
|
93
|
+
return bytes_written;
|
94
|
+
}
|
95
|
+
|
96
|
+
static int oabd_decompress(struct msoab_decompressor *_self, const char *input,
|
97
|
+
const char *output)
|
98
|
+
{
|
99
|
+
struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) _self;
|
100
|
+
struct mspack_system *sys;
|
101
|
+
struct mspack_file *infh = NULL;
|
102
|
+
struct mspack_file *outfh = NULL;
|
103
|
+
unsigned char *buf = NULL;
|
104
|
+
unsigned char hdrbuf[oabhead_SIZEOF];
|
105
|
+
unsigned int block_max, target_size;
|
106
|
+
struct lzxd_stream *lzx = NULL;
|
107
|
+
struct mspack_system oabd_sys;
|
108
|
+
struct oabd_file in_ofh, out_ofh;
|
109
|
+
unsigned int window_bits;
|
110
|
+
int ret = MSPACK_ERR_OK;
|
111
|
+
|
112
|
+
if (!self) return MSPACK_ERR_ARGS;
|
113
|
+
sys = self->system;
|
114
|
+
|
115
|
+
infh = sys->open(sys, input, MSPACK_SYS_OPEN_READ);
|
116
|
+
if (!infh) {
|
117
|
+
ret = MSPACK_ERR_OPEN;
|
118
|
+
goto out;
|
119
|
+
}
|
120
|
+
|
121
|
+
if (sys->read(infh, hdrbuf, oabhead_SIZEOF) != oabhead_SIZEOF) {
|
122
|
+
ret = MSPACK_ERR_READ;
|
123
|
+
goto out;
|
124
|
+
}
|
125
|
+
|
126
|
+
if (EndGetI32(&hdrbuf[oabhead_VersionHi]) != 3 ||
|
127
|
+
EndGetI32(&hdrbuf[oabhead_VersionLo]) != 1) {
|
128
|
+
ret = MSPACK_ERR_SIGNATURE;
|
129
|
+
goto out;
|
130
|
+
}
|
131
|
+
|
132
|
+
block_max = EndGetI32(&hdrbuf[oabhead_BlockMax]);
|
133
|
+
target_size = EndGetI32(&hdrbuf[oabhead_TargetSize]);
|
134
|
+
|
135
|
+
/* We use it for reading block headers too */
|
136
|
+
if (block_max < oabblk_SIZEOF)
|
137
|
+
block_max = oabblk_SIZEOF;
|
138
|
+
|
139
|
+
outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
|
140
|
+
if (!outfh) {
|
141
|
+
ret = MSPACK_ERR_OPEN;
|
142
|
+
goto out;
|
143
|
+
}
|
144
|
+
|
145
|
+
buf = sys->alloc(sys, block_max);
|
146
|
+
if (!buf) {
|
147
|
+
ret = MSPACK_ERR_NOMEMORY;
|
148
|
+
goto out;
|
149
|
+
}
|
150
|
+
|
151
|
+
oabd_sys = *sys;
|
152
|
+
oabd_sys.read = oabd_sys_read;
|
153
|
+
oabd_sys.write = oabd_sys_write;
|
154
|
+
|
155
|
+
in_ofh.orig_sys = sys;
|
156
|
+
in_ofh.orig_file = infh;
|
157
|
+
|
158
|
+
out_ofh.orig_sys = sys;
|
159
|
+
out_ofh.orig_file = outfh;
|
160
|
+
|
161
|
+
while (target_size) {
|
162
|
+
unsigned int blk_csize, blk_dsize, blk_crc, blk_flags;
|
163
|
+
|
164
|
+
if (sys->read(infh, buf, oabblk_SIZEOF) != oabblk_SIZEOF) {
|
165
|
+
ret = MSPACK_ERR_READ;
|
166
|
+
goto out;
|
167
|
+
}
|
168
|
+
blk_flags = EndGetI32(&buf[oabblk_Flags]);
|
169
|
+
blk_csize = EndGetI32(&buf[oabblk_CompSize]);
|
170
|
+
blk_dsize = EndGetI32(&buf[oabblk_UncompSize]);
|
171
|
+
blk_crc = EndGetI32(&buf[oabblk_CRC]);
|
172
|
+
|
173
|
+
if (blk_dsize > block_max || blk_dsize > target_size || blk_flags > 1) {
|
174
|
+
ret = MSPACK_ERR_DATAFORMAT;
|
175
|
+
goto out;
|
176
|
+
}
|
177
|
+
|
178
|
+
if (!blk_flags) {
|
179
|
+
/* Uncompressed block */
|
180
|
+
if (blk_dsize != blk_csize) {
|
181
|
+
ret = MSPACK_ERR_DATAFORMAT;
|
182
|
+
goto out;
|
183
|
+
}
|
184
|
+
if (sys->read(infh, buf, blk_dsize) != (int)blk_dsize) {
|
185
|
+
ret = MSPACK_ERR_READ;
|
186
|
+
goto out;
|
187
|
+
}
|
188
|
+
if (sys->write(outfh, buf, blk_dsize) != (int)blk_dsize) {
|
189
|
+
ret = MSPACK_ERR_WRITE;
|
190
|
+
goto out;
|
191
|
+
}
|
192
|
+
} else {
|
193
|
+
/* LZX compressed block */
|
194
|
+
window_bits = 17;
|
195
|
+
|
196
|
+
while (window_bits < 25 && (1U << window_bits) < blk_dsize)
|
197
|
+
window_bits++;
|
198
|
+
|
199
|
+
in_ofh.available = blk_csize;
|
200
|
+
out_ofh.crc = 0xffffffff;
|
201
|
+
|
202
|
+
lzx = lzxd_init(&oabd_sys, (void *)&in_ofh, (void *)&out_ofh, window_bits,
|
203
|
+
0, 4096, blk_dsize, 1);
|
204
|
+
if (!lzx) {
|
205
|
+
ret = MSPACK_ERR_NOMEMORY;
|
206
|
+
goto out;
|
207
|
+
}
|
208
|
+
|
209
|
+
ret = lzxd_decompress(lzx, blk_dsize);
|
210
|
+
if (ret != MSPACK_ERR_OK)
|
211
|
+
goto out;
|
212
|
+
|
213
|
+
lzxd_free(lzx);
|
214
|
+
lzx = NULL;
|
215
|
+
|
216
|
+
/* Consume any trailing padding bytes before the next block */
|
217
|
+
while (in_ofh.available) {
|
218
|
+
int count = block_max;
|
219
|
+
if ((size_t)count > in_ofh.available)
|
220
|
+
count = in_ofh.available;
|
221
|
+
|
222
|
+
count = sys->read(infh, buf, count);
|
223
|
+
if (count < 0) {
|
224
|
+
ret = MSPACK_ERR_READ;
|
225
|
+
goto out;
|
226
|
+
}
|
227
|
+
in_ofh.available -= count;
|
228
|
+
}
|
229
|
+
|
230
|
+
if (out_ofh.crc != blk_crc) {
|
231
|
+
ret = MSPACK_ERR_CHECKSUM;
|
232
|
+
goto out;
|
233
|
+
}
|
234
|
+
}
|
235
|
+
target_size -= blk_dsize;
|
236
|
+
}
|
237
|
+
|
238
|
+
out:
|
239
|
+
if (lzx)
|
240
|
+
lzxd_free(lzx);
|
241
|
+
if (buf)
|
242
|
+
sys->free(buf);
|
243
|
+
if (outfh)
|
244
|
+
sys->close(outfh);
|
245
|
+
if (infh)
|
246
|
+
sys->close(infh);
|
247
|
+
|
248
|
+
return ret;
|
249
|
+
}
|
250
|
+
|
251
|
+
static int oabd_decompress_incremental(struct msoab_decompressor *_self,
|
252
|
+
const char *input, const char *base,
|
253
|
+
const char *output)
|
254
|
+
{
|
255
|
+
struct msoab_decompressor_p *self = (struct msoab_decompressor_p *) _self;
|
256
|
+
struct mspack_system *sys;
|
257
|
+
struct mspack_file *infh = NULL;
|
258
|
+
struct mspack_file *basefh = NULL;
|
259
|
+
struct mspack_file *outfh = NULL;
|
260
|
+
unsigned char *buf = NULL;
|
261
|
+
unsigned char hdrbuf[patchhead_SIZEOF];
|
262
|
+
unsigned int block_max, source_size, target_size, source_crc, target_crc;
|
263
|
+
struct lzxd_stream *lzx = NULL;
|
264
|
+
struct mspack_system oabd_sys;
|
265
|
+
struct oabd_file in_ofh, out_ofh;
|
266
|
+
unsigned int window_bits, window_size;
|
267
|
+
int ret = MSPACK_ERR_OK;
|
268
|
+
|
269
|
+
if (!self) return MSPACK_ERR_ARGS;
|
270
|
+
sys = self->system;
|
271
|
+
|
272
|
+
infh = sys->open(sys, input, MSPACK_SYS_OPEN_READ);
|
273
|
+
if (!infh) {
|
274
|
+
ret = MSPACK_ERR_OPEN;
|
275
|
+
goto out;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (sys->read(infh, hdrbuf, patchhead_SIZEOF) != patchhead_SIZEOF) {
|
279
|
+
ret = MSPACK_ERR_READ;
|
280
|
+
goto out;
|
281
|
+
}
|
282
|
+
|
283
|
+
if (EndGetI32(&hdrbuf[patchhead_VersionHi]) != 3 ||
|
284
|
+
EndGetI32(&hdrbuf[patchhead_VersionLo]) != 2) {
|
285
|
+
ret = MSPACK_ERR_SIGNATURE;
|
286
|
+
goto out;
|
287
|
+
}
|
288
|
+
|
289
|
+
block_max = EndGetI32(&hdrbuf[patchhead_BlockMax]);
|
290
|
+
source_size = EndGetI32(&hdrbuf[patchhead_SourceSize]);
|
291
|
+
target_size = EndGetI32(&hdrbuf[patchhead_TargetSize]);
|
292
|
+
source_crc = EndGetI32(&hdrbuf[patchhead_SourceCRC]);
|
293
|
+
target_crc = EndGetI32(&hdrbuf[patchhead_TargetCRC]);
|
294
|
+
|
295
|
+
/* We use it for reading block headers too */
|
296
|
+
if (block_max < patchblk_SIZEOF)
|
297
|
+
block_max = patchblk_SIZEOF;
|
298
|
+
|
299
|
+
basefh = sys->open(sys, base, MSPACK_SYS_OPEN_READ);
|
300
|
+
if (!basefh) {
|
301
|
+
ret = MSPACK_ERR_OPEN;
|
302
|
+
goto out;
|
303
|
+
}
|
304
|
+
|
305
|
+
outfh = sys->open(sys, output, MSPACK_SYS_OPEN_WRITE);
|
306
|
+
if (!outfh) {
|
307
|
+
ret = MSPACK_ERR_OPEN;
|
308
|
+
goto out;
|
309
|
+
}
|
310
|
+
|
311
|
+
buf = sys->alloc(sys, block_max);
|
312
|
+
if (!buf) {
|
313
|
+
ret = MSPACK_ERR_NOMEMORY;
|
314
|
+
goto out;
|
315
|
+
}
|
316
|
+
|
317
|
+
oabd_sys = *sys;
|
318
|
+
oabd_sys.read = oabd_sys_read;
|
319
|
+
oabd_sys.write = oabd_sys_write;
|
320
|
+
|
321
|
+
in_ofh.orig_sys = sys;
|
322
|
+
in_ofh.orig_file = infh;
|
323
|
+
|
324
|
+
out_ofh.orig_sys = sys;
|
325
|
+
out_ofh.orig_file = outfh;
|
326
|
+
|
327
|
+
while (target_size) {
|
328
|
+
unsigned int blk_csize, blk_dsize, blk_ssize, blk_crc;
|
329
|
+
|
330
|
+
if (sys->read(infh, buf, patchblk_SIZEOF) != patchblk_SIZEOF) {
|
331
|
+
ret = MSPACK_ERR_READ;
|
332
|
+
goto out;
|
333
|
+
}
|
334
|
+
blk_csize = EndGetI32(&buf[patchblk_PatchSize]);
|
335
|
+
blk_dsize = EndGetI32(&buf[patchblk_TargetSize]);
|
336
|
+
blk_ssize = EndGetI32(&buf[patchblk_SourceSize]);
|
337
|
+
blk_crc = EndGetI32(&buf[patchblk_CRC]);
|
338
|
+
|
339
|
+
if (blk_dsize > block_max || blk_dsize > target_size ||
|
340
|
+
blk_ssize > block_max) {
|
341
|
+
ret = MSPACK_ERR_DATAFORMAT;
|
342
|
+
goto out;
|
343
|
+
}
|
344
|
+
|
345
|
+
|
346
|
+
window_size = (blk_ssize + 32767) & ~32767;
|
347
|
+
window_size += blk_dsize;
|
348
|
+
window_bits = 17;
|
349
|
+
|
350
|
+
while (window_bits < 25 && (1U << window_bits) < window_size)
|
351
|
+
window_bits++;
|
352
|
+
|
353
|
+
in_ofh.available = blk_csize;
|
354
|
+
out_ofh.crc = 0xffffffff;
|
355
|
+
|
356
|
+
lzx = lzxd_init(&oabd_sys, (void *)&in_ofh, (void *)&out_ofh, window_bits,
|
357
|
+
0, 4096, blk_dsize, 1);
|
358
|
+
if (!lzx) {
|
359
|
+
ret = MSPACK_ERR_NOMEMORY;
|
360
|
+
goto out;
|
361
|
+
}
|
362
|
+
ret = lzxd_set_reference_data(lzx, sys, basefh, blk_ssize);
|
363
|
+
if (ret != MSPACK_ERR_OK)
|
364
|
+
goto out;
|
365
|
+
|
366
|
+
ret = lzxd_decompress(lzx, blk_dsize);
|
367
|
+
if (ret != MSPACK_ERR_OK)
|
368
|
+
goto out;
|
369
|
+
|
370
|
+
lzxd_free(lzx);
|
371
|
+
lzx = NULL;
|
372
|
+
|
373
|
+
/* Consume any trailing padding bytes before the next block */
|
374
|
+
while (in_ofh.available) {
|
375
|
+
int count = block_max;
|
376
|
+
if ((size_t)count > in_ofh.available)
|
377
|
+
count = in_ofh.available;
|
378
|
+
|
379
|
+
count = sys->read(infh, buf, count);
|
380
|
+
if (count < 0) {
|
381
|
+
ret = MSPACK_ERR_READ;
|
382
|
+
goto out;
|
383
|
+
}
|
384
|
+
in_ofh.available -= count;
|
385
|
+
}
|
386
|
+
|
387
|
+
if (out_ofh.crc != blk_crc) {
|
388
|
+
ret = MSPACK_ERR_CHECKSUM;
|
389
|
+
goto out;
|
390
|
+
}
|
391
|
+
|
392
|
+
target_size -= blk_dsize;
|
393
|
+
}
|
394
|
+
|
395
|
+
out:
|
396
|
+
if (lzx)
|
397
|
+
lzxd_free(lzx);
|
398
|
+
if (buf)
|
399
|
+
sys->free(buf);
|
400
|
+
if (outfh)
|
401
|
+
sys->close(outfh);
|
402
|
+
if (basefh)
|
403
|
+
sys->close(basefh);
|
404
|
+
if (infh)
|
405
|
+
sys->close(infh);
|
406
|
+
|
407
|
+
return ret;
|
408
|
+
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
3
|
+
*
|
4
|
+
* The Quantum method was created by David Stafford, adapted by Microsoft
|
5
|
+
* Corporation.
|
6
|
+
*
|
7
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
8
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
9
|
+
*
|
10
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
11
|
+
*/
|
12
|
+
|
13
|
+
#ifndef MSPACK_QTM_H
|
14
|
+
#define MSPACK_QTM_H 1
|
15
|
+
|
16
|
+
#ifdef __cplusplus
|
17
|
+
extern "C" {
|
18
|
+
#endif
|
19
|
+
|
20
|
+
/* Quantum compression / decompression definitions */
|
21
|
+
|
22
|
+
#define QTM_FRAME_SIZE (32768)
|
23
|
+
|
24
|
+
struct qtmd_modelsym {
|
25
|
+
unsigned short sym, cumfreq;
|
26
|
+
};
|
27
|
+
|
28
|
+
struct qtmd_model {
|
29
|
+
int shiftsleft, entries;
|
30
|
+
struct qtmd_modelsym *syms;
|
31
|
+
};
|
32
|
+
|
33
|
+
struct qtmd_stream {
|
34
|
+
struct mspack_system *sys; /* I/O routines */
|
35
|
+
struct mspack_file *input; /* input file handle */
|
36
|
+
struct mspack_file *output; /* output file handle */
|
37
|
+
|
38
|
+
unsigned char *window; /* decoding window */
|
39
|
+
unsigned int window_size; /* window size */
|
40
|
+
unsigned int window_posn; /* decompression offset within window */
|
41
|
+
unsigned int frame_todo; /* bytes remaining for current frame */
|
42
|
+
|
43
|
+
unsigned short H, L, C; /* high/low/current: arith coding state */
|
44
|
+
unsigned char header_read; /* have we started decoding a new frame? */
|
45
|
+
|
46
|
+
int error;
|
47
|
+
|
48
|
+
/* I/O buffers */
|
49
|
+
unsigned char *inbuf, *i_ptr, *i_end, *o_ptr, *o_end;
|
50
|
+
unsigned int bit_buffer, inbuf_size;
|
51
|
+
unsigned char bits_left, input_end;
|
52
|
+
|
53
|
+
/* four literal models, each representing 64 symbols
|
54
|
+
* model0 for literals from 0 to 63 (selector = 0)
|
55
|
+
* model1 for literals from 64 to 127 (selector = 1)
|
56
|
+
* model2 for literals from 128 to 191 (selector = 2)
|
57
|
+
* model3 for literals from 129 to 255 (selector = 3) */
|
58
|
+
struct qtmd_model model0, model1, model2, model3;
|
59
|
+
|
60
|
+
/* three match models.
|
61
|
+
* model4 for match with fixed length of 3 bytes
|
62
|
+
* model5 for match with fixed length of 4 bytes
|
63
|
+
* model6 for variable length match, encoded with model6len model */
|
64
|
+
struct qtmd_model model4, model5, model6, model6len;
|
65
|
+
|
66
|
+
/* selector model. 0-6 to say literal (0,1,2,3) or match (4,5,6) */
|
67
|
+
struct qtmd_model model7;
|
68
|
+
|
69
|
+
/* symbol arrays for all models */
|
70
|
+
struct qtmd_modelsym m0sym[64 + 1];
|
71
|
+
struct qtmd_modelsym m1sym[64 + 1];
|
72
|
+
struct qtmd_modelsym m2sym[64 + 1];
|
73
|
+
struct qtmd_modelsym m3sym[64 + 1];
|
74
|
+
struct qtmd_modelsym m4sym[24 + 1];
|
75
|
+
struct qtmd_modelsym m5sym[36 + 1];
|
76
|
+
struct qtmd_modelsym m6sym[42 + 1], m6lsym[27 + 1];
|
77
|
+
struct qtmd_modelsym m7sym[7 + 1];
|
78
|
+
};
|
79
|
+
|
80
|
+
/* allocates Quantum decompression state for decoding the given stream.
|
81
|
+
*
|
82
|
+
* - returns NULL if window_bits is outwith the range 10 to 21 (inclusive).
|
83
|
+
*
|
84
|
+
* - uses system->alloc() to allocate memory
|
85
|
+
*
|
86
|
+
* - returns NULL if not enough memory
|
87
|
+
*
|
88
|
+
* - window_bits is the size of the Quantum window, from 1Kb (10) to 2Mb (21).
|
89
|
+
*
|
90
|
+
* - input_buffer_size is the number of bytes to use to store bitstream data.
|
91
|
+
*/
|
92
|
+
extern struct qtmd_stream *qtmd_init(struct mspack_system *system,
|
93
|
+
struct mspack_file *input,
|
94
|
+
struct mspack_file *output,
|
95
|
+
int window_bits,
|
96
|
+
int input_buffer_size);
|
97
|
+
|
98
|
+
/* decompresses, or decompresses more of, a Quantum stream.
|
99
|
+
*
|
100
|
+
* - out_bytes of data will be decompressed and the function will return
|
101
|
+
* with an MSPACK_ERR_OK return code.
|
102
|
+
*
|
103
|
+
* - decompressing will stop as soon as out_bytes is reached. if the true
|
104
|
+
* amount of bytes decoded spills over that amount, they will be kept for
|
105
|
+
* a later invocation of qtmd_decompress().
|
106
|
+
*
|
107
|
+
* - the output bytes will be passed to the system->write() function given in
|
108
|
+
* qtmd_init(), using the output file handle given in qtmd_init(). More
|
109
|
+
* than one call may be made to system->write()
|
110
|
+
*
|
111
|
+
* - Quantum will read input bytes as necessary using the system->read()
|
112
|
+
* function given in qtmd_init(), using the input file handle given in
|
113
|
+
* qtmd_init(). This will continue until system->read() returns 0 bytes,
|
114
|
+
* or an error.
|
115
|
+
*/
|
116
|
+
extern int qtmd_decompress(struct qtmd_stream *qtm, off_t out_bytes);
|
117
|
+
|
118
|
+
/* frees all state associated with a Quantum data stream
|
119
|
+
*
|
120
|
+
* - calls system->free() using the system pointer given in qtmd_init()
|
121
|
+
*/
|
122
|
+
void qtmd_free(struct qtmd_stream *qtm);
|
123
|
+
|
124
|
+
#ifdef __cplusplus
|
125
|
+
}
|
126
|
+
#endif
|
127
|
+
|
128
|
+
#endif
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/* This file is part of libmspack.
|
2
|
+
* (C) 2003-2004 Stuart Caie.
|
3
|
+
*
|
4
|
+
* The Quantum method was created by David Stafford, adapted by Microsoft
|
5
|
+
* Corporation.
|
6
|
+
*
|
7
|
+
* libmspack is free software; you can redistribute it and/or modify it under
|
8
|
+
* the terms of the GNU Lesser General Public License (LGPL) version 2.1
|
9
|
+
*
|
10
|
+
* For further details, see the file COPYING.LIB distributed with libmspack
|
11
|
+
*/
|
12
|
+
|
13
|
+
/* Quantum compression implementation */
|
14
|
+
|
15
|
+
#include <system.h>
|
16
|
+
#include <qtm.h>
|
17
|
+
|
18
|
+
/* todo */
|