1 /* MikMod sound library (c) 2003-2015 Raphael Assenat and others -
2 * see AUTHORS file for a complete list.
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (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 Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17 * 02111-1307, USA.
18 */
19
20 /* MMCMP ("ziRCONia") decompression support
21 *
22 * Based on the public domain version from the libmodplug library by
23 * Olivier Lapicque <olivierl@jps.net> (sezero's fork of libmodplug
24 * at github: http://github.com/sezero/libmodplug/tree/sezero )
25 *
26 * Rewritten for libmikmod by O. Sezer <sezero@users.sourceforge.net>
27 * with some extra ideas from the libxmp version by Claudio Matsuoka.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <stdio.h>
39 #ifdef HAVE_MEMORY_H
40 #include <memory.h>
41 #endif
42 #include <string.h>
43
44 #include "mikmod_internals.h"
45
46 #ifdef SUNOS
47 extern int fprintf(FILE *, const char *, ...);
48 #endif
49
50 /*#define MMCMP_DEBUG*/
51
52 typedef struct MMCMPFILEHDR
53 {
54 UBYTE id[8]; /* string 'ziRCONia' */
55 UWORD hdrsize; /* sizeof MMCMPHEADER */
56 } MMCMPFILEHDR; /* 10 bytes */
57
58 typedef struct MMCMPHEADER
59 {
60 UWORD version;
61 UWORD nblocks;
62 ULONG filesize;
63 ULONG blktable;
64 UBYTE glb_comp;
65 UBYTE fmt_comp;
66 } MMCMPHEADER; /* 14 bytes */
67
68 typedef struct MMCMPBLOCK
69 {
70 ULONG unpk_size;
71 ULONG pk_size;
72 ULONG xor_chk;
73 UWORD sub_blk;
74 UWORD flags;
75 UWORD tt_entries;
76 UWORD num_bits;
77 } MMCMPBLOCK; /* 20 bytes */
78
79 typedef struct MMCMPSUBBLOCK
80 {
81 ULONG unpk_pos;
82 ULONG unpk_size;
83 } MMCMPSUBBLOCK; /* 8 bytes */
84
85 #define MMCMP_COMP 0x0001
86 #define MMCMP_DELTA 0x0002
87 #define MMCMP_16BIT 0x0004
88 #define MMCMP_STEREO 0x0100
89 #define MMCMP_ABS16 0x0200
90 #define MMCMP_ENDIAN 0x0400
91
92
93 typedef struct MMCMPBITBUFFER
94 {
95 ULONG bitcount;
96 ULONG bitbuffer;
97 const UBYTE *start;
98 const UBYTE *end;
99 } MMCMPBITBUFFER;
100
MMCMP_GetBits(MMCMPBITBUFFER * b,ULONG nBits)101 static ULONG MMCMP_GetBits(MMCMPBITBUFFER* b, ULONG nBits)
102 {
103 ULONG d;
104 if (!nBits) return 0;
105 while (b->bitcount < 24)
106 {
107 b->bitbuffer |= ((b->start < b->end) ? *b->start++ : 0) << b->bitcount;
108 b->bitcount += 8;
109 }
110 d = b->bitbuffer & ((1 << nBits) - 1);
111 b->bitbuffer >>= nBits;
112 b->bitcount -= nBits;
113 return d;
114 }
115
116 static const ULONG MMCMP8BitCommands[8] =
117 {
118 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF8
119 };
120
121 static const ULONG MMCMP8BitFetch[8] =
122 {
123 3, 3, 3, 3, 2, 1, 0, 0
124 };
125
126 static const ULONG MMCMP16BitCommands[16] =
127 {
128 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0,
129 0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0
130 };
131
132 static const ULONG MMCMP16BitFetch[16] =
133 {
134 4, 4, 4, 4, 3, 2, 1, 0,
135 0, 0, 0, 0, 0, 0, 0, 0
136 };
137
138
MMCMP_Unpack(MREADER * reader,void ** out,long * outlen)139 BOOL MMCMP_Unpack(MREADER* reader, void** out, long* outlen)
140 {
141 ULONG srclen, destlen;
142 UBYTE *destbuf, *destptr, *destend;
143 MMCMPHEADER mmh;
144 ULONG *pblk_table;
145 MMCMPSUBBLOCK *subblocks;
146 ULONG i, blockidx, numsubs;
147 UBYTE *buf; ULONG bufsize;
148
149 _mm_fseek(reader,0,SEEK_END);
150 srclen = _mm_ftell(reader);
151 if (srclen < 256) return 0;
152
153 _mm_rewind(reader);
154 if (_mm_read_I_ULONG(reader) != 0x4352697A) /* 'ziRC' */
155 return 0;
156 if (_mm_read_I_ULONG(reader) != 0x61694e4f) /* 'ONia' */
157 return 0;
158 if (_mm_read_I_UWORD(reader) != 14) /* header size */
159 return 0;
160
161 mmh.version = _mm_read_I_UWORD(reader);
162 mmh.nblocks = _mm_read_I_UWORD(reader);
163 mmh.filesize = _mm_read_I_ULONG(reader);
164 mmh.blktable = _mm_read_I_ULONG(reader);
165 mmh.glb_comp = _mm_read_UBYTE(reader);
166 mmh.fmt_comp = _mm_read_UBYTE(reader);
167
168 if ((!mmh.nblocks) || (mmh.filesize < 16) || (mmh.filesize > 0x8000000) ||
169 (mmh.blktable >= srclen) || (mmh.blktable + 4*mmh.nblocks > srclen)) {
170 return 0;
171 }
172 destlen = mmh.filesize;
173 numsubs = 32;
174 bufsize = 65536;
175
176 destbuf = (UBYTE*)MikMod_malloc(destlen);
177 buf = (UBYTE*)MikMod_malloc(bufsize);
178 pblk_table = (ULONG*)MikMod_malloc(mmh.nblocks*4);
179 subblocks = (MMCMPSUBBLOCK*)MikMod_malloc(numsubs*sizeof(MMCMPSUBBLOCK));
180 if (!destbuf || !buf || !pblk_table || !subblocks)
181 goto err;
182 destend = destbuf + destlen;
183
184 _mm_fseek(reader,mmh.blktable,SEEK_SET);
185 for (blockidx = 0; blockidx < mmh.nblocks; blockidx++) {
186 pblk_table[blockidx] = _mm_read_I_ULONG(reader);
187 }
188
189 for (blockidx = 0; blockidx < mmh.nblocks; blockidx++)
190 {
191 ULONG srcpos = pblk_table[blockidx];
192 MMCMPBLOCK block;
193
194 if (srcpos + 20 >= srclen) goto err;
195
196 _mm_fseek(reader,srcpos,SEEK_SET);
197 block.unpk_size = _mm_read_I_ULONG(reader);
198 block.pk_size = _mm_read_I_ULONG(reader);
199 block.xor_chk = _mm_read_I_ULONG(reader);
200 block.sub_blk = _mm_read_I_UWORD(reader);
201 block.flags = _mm_read_I_UWORD(reader);
202 block.tt_entries = _mm_read_I_UWORD(reader);
203 block.num_bits = _mm_read_I_UWORD(reader);
204
205 if (!block.unpk_size || !block.pk_size || !block.sub_blk)
206 goto err;
207 if (block.pk_size <= block.tt_entries)
208 goto err;
209 if (block.flags & MMCMP_COMP) {
210 if (block.flags & MMCMP_16BIT) {
211 if (block.num_bits >= 16)
212 goto err;
213 }
214 else {
215 if (block.num_bits >= 8)
216 goto err;
217 }
218 }
219
220 srcpos += 20 + block.sub_blk*8;
221 if (srcpos >= srclen) goto err;
222
223 if (numsubs < block.sub_blk) {
224 numsubs = (block.sub_blk + 31) & ~31;
225 MikMod_free(subblocks);
226 subblocks = (MMCMPSUBBLOCK*)MikMod_malloc(numsubs*sizeof(MMCMPSUBBLOCK));
227 if (!subblocks) goto err;
228 }
229 for (i = 0; i < block.sub_blk; i++) {
230 subblocks[i].unpk_pos = _mm_read_I_ULONG(reader);
231 subblocks[i].unpk_size = _mm_read_I_ULONG(reader);
232 if (subblocks[i].unpk_pos >= destlen) goto err;
233 if (subblocks[i].unpk_size > destlen - subblocks[i].unpk_pos) goto err;
234 }
235
236 #ifdef MMCMP_DEBUG
237 fprintf(stderr, "block %u: flags=%04X sub_blocks=%u",
238 blockidx, (unsigned)block.flags, (unsigned)block.sub_blk);
239 fprintf(stderr, " pksize=%u unpksize=%u", block.pk_size, block.unpk_size);
240 fprintf(stderr, " tt_entries=%u num_bits=%u\n", block.tt_entries, block.num_bits);
241 #endif
242 if (!(block.flags & MMCMP_COMP))
243 { /* Data is not packed */
244 _mm_fseek(reader,srcpos,SEEK_SET);
245 destptr = destbuf + subblocks[0].unpk_pos;
246 i = 0;
247
248 while (1) {
249 #ifdef MMCMP_DEBUG
250 fprintf(stderr, " Unpacked sub-block %u: offset %u, size=%u\n",
251 i, subblocks[i].unpk_pos, subblocks[i].unpk_size);
252 #endif
253 _mm_read_UBYTES(destptr,subblocks[i].unpk_size,reader);
254 destptr += subblocks[i].unpk_size;
255 if (++i == block.sub_blk) break;
256 }
257 }
258 else if (block.flags & MMCMP_16BIT)
259 { /* Data is 16-bit packed */
260 MMCMPBITBUFFER bb;
261 ULONG size;
262 ULONG pos = 0;
263 ULONG numbits = block.num_bits;
264 ULONG oldval = 0;
265
266 #ifdef MMCMP_DEBUG
267 fprintf(stderr, " 16-bit block: pos=%u size=%u ",
268 subblocks[0].unpk_pos, subblocks[0].unpk_size);
269 if (block.flags & MMCMP_DELTA) fprintf(stderr, "DELTA ");
270 if (block.flags & MMCMP_ABS16) fprintf(stderr, "ABS16 ");
271 fprintf(stderr, "\n");
272 #endif
273 size = block.pk_size - block.tt_entries;
274 if (bufsize < size) {
275 while (bufsize < size) bufsize += 65536;
276 MikMod_free(buf);
277 if (!(buf = (UBYTE*)MikMod_malloc(bufsize)))
278 goto err;
279 }
280
281 bb.bitcount = 0;
282 bb.bitbuffer = 0;
283 bb.start = buf;
284 bb.end = buf + size;
285
286 _mm_fseek(reader,srcpos+block.tt_entries,SEEK_SET);
287 _mm_read_UBYTES(buf,size,reader);
288 destptr = destbuf + subblocks[0].unpk_pos;
289 size = subblocks[0].unpk_size;
290 i = 0;
291
292 while (1)
293 {
294 ULONG newval = 0x10000;
295 ULONG d = MMCMP_GetBits(&bb, numbits+1);
296
297 if (d >= MMCMP16BitCommands[numbits])
298 {
299 ULONG nFetch = MMCMP16BitFetch[numbits];
300 ULONG newbits = MMCMP_GetBits(&bb, nFetch) + ((d - MMCMP16BitCommands[numbits]) << nFetch);
301 if (newbits != numbits)
302 {
303 numbits = newbits & 0x0F;
304 } else
305 {
306 if ((d = MMCMP_GetBits(&bb, 4)) == 0x0F)
307 {
308 if (MMCMP_GetBits(&bb, 1)) break;
309 newval = 0xFFFF;
310 } else
311 {
312 newval = 0xFFF0 + d;
313 }
314 }
315 } else
316 {
317 newval = d;
318 }
319 if (newval < 0x10000)
320 {
321 newval = (newval & 1) ? (ULONG)(-(SLONG)((newval+1) >> 1)) : (ULONG)(newval >> 1);
322 if (block.flags & MMCMP_DELTA)
323 {
324 newval += oldval;
325 oldval = newval;
326 } else
327 if (!(block.flags & MMCMP_ABS16))
328 {
329 newval ^= 0x8000;
330 }
331 if (destend - destptr < 2) goto err;
332 pos += 2;
333 *destptr++ = (UBYTE) (((UWORD)newval) & 0xff);
334 *destptr++ = (UBYTE) (((UWORD)newval) >> 8);
335 }
336 if (pos >= size)
337 {
338 if (++i == block.sub_blk) break;
339 size = subblocks[i].unpk_size;
340 destptr = destbuf + subblocks[i].unpk_pos;
341 pos = 0;
342 }
343 }
344 }
345 else
346 { /* Data is 8-bit packed */
347 MMCMPBITBUFFER bb;
348 ULONG size;
349 ULONG pos = 0;
350 ULONG numbits = block.num_bits;
351 ULONG oldval = 0;
352 UBYTE ptable[0x100];
353
354 size = block.pk_size - block.tt_entries;
355 if (bufsize < size) {
356 while (bufsize < size) bufsize += 65536;
357 MikMod_free(buf);
358 if (!(buf = (UBYTE*)MikMod_malloc(bufsize)))
359 goto err;
360 }
361
362 bb.bitcount = 0;
363 bb.bitbuffer = 0;
364 bb.start = buf;
365 bb.end = buf + size;
366
367 _mm_read_UBYTES(ptable,0x100,reader);
368 _mm_fseek(reader,srcpos+block.tt_entries,SEEK_SET);
369 _mm_read_UBYTES(buf,size,reader);
370 destptr = destbuf + subblocks[0].unpk_pos;
371 size = subblocks[0].unpk_size;
372 i = 0;
373
374 while (1)
375 {
376 ULONG newval = 0x100;
377 ULONG d = MMCMP_GetBits(&bb, numbits+1);
378
379 if (d >= MMCMP8BitCommands[numbits])
380 {
381 ULONG nFetch = MMCMP8BitFetch[numbits];
382 ULONG newbits = MMCMP_GetBits(&bb, nFetch) + ((d - MMCMP8BitCommands[numbits]) << nFetch);
383 if (newbits != numbits)
384 {
385 numbits = newbits & 0x07;
386 } else
387 {
388 if ((d = MMCMP_GetBits(&bb, 3)) == 7)
389 {
390 if (MMCMP_GetBits(&bb, 1)) break;
391 newval = 0xFF;
392 } else
393 {
394 newval = 0xF8 + d;
395 }
396 }
397 } else
398 {
399 newval = d;
400 }
401 if (newval < 0x100)
402 {
403 int n = ptable[newval];
404 if (block.flags & MMCMP_DELTA)
405 {
406 n += oldval;
407 oldval = n;
408 }
409 destptr[pos++] = (UBYTE)n;
410 }
411 if (pos >= size)
412 {
413 if (++i == block.sub_blk) break;
414 size = subblocks[i].unpk_size;
415 destptr = destbuf + subblocks[i].unpk_pos;
416 pos = 0;
417 }
418 }
419 }
420 }
421
422 MikMod_free(buf);
423 MikMod_free(pblk_table);
424 MikMod_free(subblocks);
425 *out = destbuf;
426 *outlen = destlen;
427 return 1;
428
429 err:
430 MikMod_free(buf);
431 MikMod_free(pblk_table);
432 MikMod_free(subblocks);
433 MikMod_free(destbuf);
434 return 0;
435 }
436