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