libmspack 0.0.1

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.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.travis.yml +5 -0
  4. data/.yardopts +1 -0
  5. data/Gemfile +4 -0
  6. data/README.md +75 -0
  7. data/Rakefile +22 -0
  8. data/UNLICENSE +24 -0
  9. data/ext/Rakefile +16 -0
  10. data/ext/i386-windows/libmspack.dll +0 -0
  11. data/ext/libmspack/AUTHORS +12 -0
  12. data/ext/libmspack/COPYING.LIB +504 -0
  13. data/ext/libmspack/ChangeLog +491 -0
  14. data/ext/libmspack/Makefile.am +100 -0
  15. data/ext/libmspack/NEWS +0 -0
  16. data/ext/libmspack/README +130 -0
  17. data/ext/libmspack/TODO +8 -0
  18. data/ext/libmspack/cleanup.sh +9 -0
  19. data/ext/libmspack/configure.ac +50 -0
  20. data/ext/libmspack/debian/changelog +6 -0
  21. data/ext/libmspack/debian/control +14 -0
  22. data/ext/libmspack/debian/rules +101 -0
  23. data/ext/libmspack/doc/Doxyfile.in +22 -0
  24. data/ext/libmspack/doc/Makefile.in +14 -0
  25. data/ext/libmspack/doc/szdd_kwaj_format.html +331 -0
  26. data/ext/libmspack/libmspack.pc.in +10 -0
  27. data/ext/libmspack/mspack/cab.h +127 -0
  28. data/ext/libmspack/mspack/cabc.c +24 -0
  29. data/ext/libmspack/mspack/cabd.c +1444 -0
  30. data/ext/libmspack/mspack/chm.h +122 -0
  31. data/ext/libmspack/mspack/chmc.c +24 -0
  32. data/ext/libmspack/mspack/chmd.c +1392 -0
  33. data/ext/libmspack/mspack/crc32.c +95 -0
  34. data/ext/libmspack/mspack/crc32.h +17 -0
  35. data/ext/libmspack/mspack/des.h +15 -0
  36. data/ext/libmspack/mspack/hlp.h +33 -0
  37. data/ext/libmspack/mspack/hlpc.c +24 -0
  38. data/ext/libmspack/mspack/hlpd.c +24 -0
  39. data/ext/libmspack/mspack/kwaj.h +118 -0
  40. data/ext/libmspack/mspack/kwajc.c +24 -0
  41. data/ext/libmspack/mspack/kwajd.c +561 -0
  42. data/ext/libmspack/mspack/lit.h +35 -0
  43. data/ext/libmspack/mspack/litc.c +24 -0
  44. data/ext/libmspack/mspack/litd.c +24 -0
  45. data/ext/libmspack/mspack/lzss.h +66 -0
  46. data/ext/libmspack/mspack/lzssd.c +93 -0
  47. data/ext/libmspack/mspack/lzx.h +221 -0
  48. data/ext/libmspack/mspack/lzxc.c +18 -0
  49. data/ext/libmspack/mspack/lzxd.c +895 -0
  50. data/ext/libmspack/mspack/mspack.def +28 -0
  51. data/ext/libmspack/mspack/mspack.h +2353 -0
  52. data/ext/libmspack/mspack/mszip.h +126 -0
  53. data/ext/libmspack/mspack/mszipc.c +18 -0
  54. data/ext/libmspack/mspack/mszipd.c +514 -0
  55. data/ext/libmspack/mspack/oab.h +60 -0
  56. data/ext/libmspack/mspack/oabc.c +24 -0
  57. data/ext/libmspack/mspack/oabd.c +408 -0
  58. data/ext/libmspack/mspack/qtm.h +128 -0
  59. data/ext/libmspack/mspack/qtmc.c +18 -0
  60. data/ext/libmspack/mspack/qtmd.c +489 -0
  61. data/ext/libmspack/mspack/readbits.h +207 -0
  62. data/ext/libmspack/mspack/readhuff.h +173 -0
  63. data/ext/libmspack/mspack/sha.h +15 -0
  64. data/ext/libmspack/mspack/system.c +239 -0
  65. data/ext/libmspack/mspack/system.h +124 -0
  66. data/ext/libmspack/mspack/szdd.h +39 -0
  67. data/ext/libmspack/mspack/szddc.c +24 -0
  68. data/ext/libmspack/mspack/szddd.c +247 -0
  69. data/ext/libmspack/rebuild.sh +8 -0
  70. data/ext/libmspack/test/cabd_c10 +19 -0
  71. data/ext/libmspack/test/cabd_compare +34 -0
  72. data/ext/libmspack/test/cabd_md5.c +161 -0
  73. data/ext/libmspack/test/cabd_memory.c +179 -0
  74. data/ext/libmspack/test/cabd_test.c +386 -0
  75. data/ext/libmspack/test/cabrip.c +81 -0
  76. data/ext/libmspack/test/chmd_compare +38 -0
  77. data/ext/libmspack/test/chmd_find.c +95 -0
  78. data/ext/libmspack/test/chmd_md5.c +67 -0
  79. data/ext/libmspack/test/chmd_order.c +144 -0
  80. data/ext/libmspack/test/chminfo.c +284 -0
  81. data/ext/libmspack/test/chmx.c +216 -0
  82. data/ext/libmspack/test/error.h +22 -0
  83. data/ext/libmspack/test/expand.c +79 -0
  84. data/ext/libmspack/test/md5.c +457 -0
  85. data/ext/libmspack/test/md5.h +165 -0
  86. data/ext/libmspack/test/md5_fh.h +123 -0
  87. data/ext/libmspack/test/msdecompile_md5 +24 -0
  88. data/ext/libmspack/test/msexpand_md5 +39 -0
  89. data/ext/libmspack/test/multifh.c +435 -0
  90. data/ext/libmspack/test/oabx.c +41 -0
  91. data/ext/libmspack/test/test_files/cabd/1.pl +84 -0
  92. data/ext/libmspack/test/test_files/cabd/2.pl +75 -0
  93. data/ext/libmspack/test/test_files/cabd/bad_folderindex.cab +0 -0
  94. data/ext/libmspack/test/test_files/cabd/bad_nofiles.cab +0 -0
  95. data/ext/libmspack/test/test_files/cabd/bad_nofolders.cab +0 -0
  96. data/ext/libmspack/test/test_files/cabd/bad_signature.cab +0 -0
  97. data/ext/libmspack/test/test_files/cabd/multi_basic_pt1.cab +0 -0
  98. data/ext/libmspack/test/test_files/cabd/multi_basic_pt2.cab +0 -0
  99. data/ext/libmspack/test/test_files/cabd/multi_basic_pt3.cab +0 -0
  100. data/ext/libmspack/test/test_files/cabd/multi_basic_pt4.cab +0 -0
  101. data/ext/libmspack/test/test_files/cabd/multi_basic_pt5.cab +0 -0
  102. data/ext/libmspack/test/test_files/cabd/normal_255c_filename.cab +0 -0
  103. data/ext/libmspack/test/test_files/cabd/normal_2files_1folder.cab +0 -0
  104. data/ext/libmspack/test/test_files/cabd/partial_nodata.cab +0 -0
  105. data/ext/libmspack/test/test_files/cabd/partial_nofiles.cab +0 -0
  106. data/ext/libmspack/test/test_files/cabd/partial_nofolder.cab +0 -0
  107. data/ext/libmspack/test/test_files/cabd/partial_shortextheader.cab +0 -0
  108. data/ext/libmspack/test/test_files/cabd/partial_shortfile1.cab +0 -0
  109. data/ext/libmspack/test/test_files/cabd/partial_shortfile2.cab +0 -0
  110. data/ext/libmspack/test/test_files/cabd/partial_shortfolder.cab +0 -0
  111. data/ext/libmspack/test/test_files/cabd/partial_shortheader.cab +0 -0
  112. data/ext/libmspack/test/test_files/cabd/partial_str_nofname.cab +0 -0
  113. data/ext/libmspack/test/test_files/cabd/partial_str_noninfo.cab +0 -0
  114. data/ext/libmspack/test/test_files/cabd/partial_str_nonname.cab +0 -0
  115. data/ext/libmspack/test/test_files/cabd/partial_str_nopinfo.cab +0 -0
  116. data/ext/libmspack/test/test_files/cabd/partial_str_nopname.cab +0 -0
  117. data/ext/libmspack/test/test_files/cabd/partial_str_shortfname.cab +0 -0
  118. data/ext/libmspack/test/test_files/cabd/partial_str_shortninfo.cab +0 -0
  119. data/ext/libmspack/test/test_files/cabd/partial_str_shortnname.cab +0 -0
  120. data/ext/libmspack/test/test_files/cabd/partial_str_shortpinfo.cab +0 -0
  121. data/ext/libmspack/test/test_files/cabd/partial_str_shortpname.cab +0 -0
  122. data/ext/libmspack/test/test_files/cabd/reserve_---.cab +0 -0
  123. data/ext/libmspack/test/test_files/cabd/reserve_--D.cab +0 -0
  124. data/ext/libmspack/test/test_files/cabd/reserve_-F-.cab +0 -0
  125. data/ext/libmspack/test/test_files/cabd/reserve_-FD.cab +0 -0
  126. data/ext/libmspack/test/test_files/cabd/reserve_H--.cab +0 -0
  127. data/ext/libmspack/test/test_files/cabd/reserve_H-D.cab +0 -0
  128. data/ext/libmspack/test/test_files/cabd/reserve_HF-.cab +0 -0
  129. data/ext/libmspack/test/test_files/cabd/reserve_HFD.cab +0 -0
  130. data/ext/libmspack/test/test_files/cabd/search_basic.cab +0 -0
  131. data/ext/libmspack/test/test_files/cabd/search_tricky1.cab +0 -0
  132. data/ext/libmspack/winbuild.sh +26 -0
  133. data/ext/x86_64-windows/libmspack.dll +0 -0
  134. data/lib/libmspack/constants.rb +9 -0
  135. data/lib/libmspack/exceptions.rb +12 -0
  136. data/lib/libmspack/mscab.rb +722 -0
  137. data/lib/libmspack/mschm.rb +301 -0
  138. data/lib/libmspack/mshlp.rb +15 -0
  139. data/lib/libmspack/mskwaj.rb +124 -0
  140. data/lib/libmspack/mslit.rb +18 -0
  141. data/lib/libmspack/msoab.rb +36 -0
  142. data/lib/libmspack/mspack.rb +208 -0
  143. data/lib/libmspack/msszdd.rb +81 -0
  144. data/lib/libmspack/system.rb +84 -0
  145. data/lib/libmspack/version.rb +4 -0
  146. data/lib/libmspack.rb +121 -0
  147. data/libmspack.gemspec +33 -0
  148. data/spec/libmspack_spec.rb +26 -0
  149. data/spec/spec_helper.rb +5 -0
  150. 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 */