1 /* MikMod sound library (c) 2003-2015 Raphael Assenat and others -
2 * see AUTHORS file for a complete list.
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.
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.
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
20 /* MMCMP ("ziRCONia") decompression support
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 )
26 * Rewritten for libmikmod by O. Sezer <sezero@users.sourceforge.net>
27 * with some extra ideas from the libxmp version by Claudio Matsuoka.
44 #include "mikmod_internals.h"
47 extern int fprintf(FILE *, const char *, ...);
50 /*#define MMCMP_DEBUG*/
52 typedef struct MMCMPFILEHDR
54 UBYTE id[8]; /* string 'ziRCONia' */
55 UWORD hdrsize; /* sizeof MMCMPHEADER */
56 } MMCMPFILEHDR; /* 10 bytes */
58 typedef struct MMCMPHEADER
66 } MMCMPHEADER; /* 14 bytes */
68 typedef struct MMCMPBLOCK
77 } MMCMPBLOCK; /* 20 bytes */
79 typedef struct MMCMPSUBBLOCK
83 } MMCMPSUBBLOCK; /* 8 bytes */
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
93 typedef struct MMCMPBITBUFFER
101 static ULONG MMCMP_GetBits(MMCMPBITBUFFER* b, ULONG nBits)
104 if (!nBits) return 0;
105 while (b->bitcount < 24)
107 b->bitbuffer |= ((b->start < b->end) ? *b->start++ : 0) << b->bitcount;
110 d = b->bitbuffer & ((1 << nBits) - 1);
111 b->bitbuffer >>= nBits;
112 b->bitcount -= nBits;
116 static const ULONG MMCMP8BitCommands[8] =
118 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF8
121 static const ULONG MMCMP8BitFetch[8] =
123 3, 3, 3, 3, 2, 1, 0, 0
126 static const ULONG MMCMP16BitCommands[16] =
128 0x01, 0x03, 0x07, 0x0F, 0x1E, 0x3C, 0x78, 0xF0,
129 0x1F0, 0x3F0, 0x7F0, 0xFF0, 0x1FF0, 0x3FF0, 0x7FF0, 0xFFF0
132 static const ULONG MMCMP16BitFetch[16] =
134 4, 4, 4, 4, 3, 2, 1, 0,
135 0, 0, 0, 0, 0, 0, 0, 0
139 BOOL MMCMP_Unpack(MREADER* reader, void** out, long* outlen)
141 ULONG srclen, destlen;
142 UBYTE *destbuf, *destptr;
145 MMCMPSUBBLOCK *subblocks;
146 ULONG i, blockidx, numsubs;
147 UBYTE *buf; ULONG bufsize;
149 _mm_fseek(reader,0,SEEK_END);
150 srclen = _mm_ftell(reader);
151 if (srclen < 256) return 0;
154 if (_mm_read_I_ULONG(reader) != 0x4352697A) /* 'ziRC' */
156 if (_mm_read_I_ULONG(reader) != 0x61694e4f) /* 'ONia' */
158 if (_mm_read_I_UWORD(reader) != 14) /* header size */
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);
168 if ((!mmh.nblocks) || (mmh.filesize < 16) || (mmh.filesize > 0x8000000) ||
169 (mmh.blktable >= srclen) || (mmh.blktable + 4*mmh.nblocks > srclen)) {
172 destlen = mmh.filesize;
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)
183 _mm_fseek(reader,mmh.blktable,SEEK_SET);
184 for (blockidx = 0; blockidx < mmh.nblocks; blockidx++) {
185 pblk_table[blockidx] = _mm_read_I_ULONG(reader);
188 for (blockidx = 0; blockidx < mmh.nblocks; blockidx++)
190 ULONG srcpos = pblk_table[blockidx];
193 if (srcpos + 20 >= srclen) goto err;
195 _mm_fseek(reader,srcpos,SEEK_SET);
196 block.unpk_size = _mm_read_I_ULONG(reader);
197 block.pk_size = _mm_read_I_ULONG(reader);
198 block.xor_chk = _mm_read_I_ULONG(reader);
199 block.sub_blk = _mm_read_I_UWORD(reader);
200 block.flags = _mm_read_I_UWORD(reader);
201 block.tt_entries = _mm_read_I_UWORD(reader);
202 block.num_bits = _mm_read_I_UWORD(reader);
204 if (!block.unpk_size || !block.pk_size || !block.sub_blk)
206 if (block.pk_size <= block.tt_entries)
208 if (block.flags & MMCMP_COMP) {
209 if (block.flags & MMCMP_16BIT) {
210 if (block.num_bits >= 16)
214 if (block.num_bits >= 8)
219 srcpos += 20 + block.sub_blk*8;
220 if (srcpos >= srclen) goto err;
222 if (numsubs < block.sub_blk) {
223 numsubs = (block.sub_blk + 31) & ~31;
224 MikMod_free(subblocks);
225 subblocks = (MMCMPSUBBLOCK*)MikMod_malloc(numsubs*sizeof(MMCMPSUBBLOCK));
226 if (!subblocks) goto err;
228 for (i = 0; i < block.sub_blk; i++) {
229 subblocks[i].unpk_pos = _mm_read_I_ULONG(reader);
230 subblocks[i].unpk_size = _mm_read_I_ULONG(reader);
231 if (subblocks[i].unpk_pos >= destlen) goto err;
232 if (subblocks[i].unpk_size > destlen) goto err;
233 if (subblocks[i].unpk_size > destlen - subblocks[i].unpk_pos) goto err;
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);
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;
250 fprintf(stderr, " Unpacked sub-block %u: offset %u, size=%u\n",
251 i, subblocks[i].unpk_pos, subblocks[i].unpk_size);
253 _mm_read_UBYTES(destptr,subblocks[i].unpk_size,reader);
254 destptr += subblocks[i].unpk_size;
255 if (++i == block.sub_blk) break;
258 else if (block.flags & MMCMP_16BIT)
259 { /* Data is 16-bit packed */
263 ULONG numbits = block.num_bits;
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");
273 size = block.pk_size - block.tt_entries;
274 if (bufsize < size) {
275 while (bufsize < size) bufsize += 65536;
277 if (!(buf = (UBYTE*)MikMod_malloc(bufsize)))
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;
294 ULONG newval = 0x10000;
295 ULONG d = MMCMP_GetBits(&bb, numbits+1);
297 if (d >= MMCMP16BitCommands[numbits])
299 ULONG nFetch = MMCMP16BitFetch[numbits];
300 ULONG newbits = MMCMP_GetBits(&bb, nFetch) + ((d - MMCMP16BitCommands[numbits]) << nFetch);
301 if (newbits != numbits)
303 numbits = newbits & 0x0F;
306 if ((d = MMCMP_GetBits(&bb, 4)) == 0x0F)
308 if (MMCMP_GetBits(&bb, 1)) break;
319 if (newval < 0x10000)
321 newval = (newval & 1) ? (ULONG)(-(SLONG)((newval+1) >> 1)) : (ULONG)(newval >> 1);
322 if (block.flags & MMCMP_DELTA)
327 if (!(block.flags & MMCMP_ABS16))
331 destptr[pos++] = (UBYTE) (((UWORD)newval) & 0xff);
332 destptr[pos++] = (UBYTE) (((UWORD)newval) >> 8);
336 if (++i == block.sub_blk) break;
337 size = subblocks[i].unpk_size;
338 destptr = destbuf + subblocks[i].unpk_pos;
344 { /* Data is 8-bit packed */
348 ULONG numbits = block.num_bits;
352 size = block.pk_size - block.tt_entries;
353 if (bufsize < size) {
354 while (bufsize < size) bufsize += 65536;
356 if (!(buf = (UBYTE*)MikMod_malloc(bufsize)))
365 _mm_read_UBYTES(ptable,0x100,reader);
366 _mm_fseek(reader,srcpos+block.tt_entries,SEEK_SET);
367 _mm_read_UBYTES(buf,size,reader);
368 destptr = destbuf + subblocks[0].unpk_pos;
369 size = subblocks[0].unpk_size;
374 ULONG newval = 0x100;
375 ULONG d = MMCMP_GetBits(&bb, numbits+1);
377 if (d >= MMCMP8BitCommands[numbits])
379 ULONG nFetch = MMCMP8BitFetch[numbits];
380 ULONG newbits = MMCMP_GetBits(&bb, nFetch) + ((d - MMCMP8BitCommands[numbits]) << nFetch);
381 if (newbits != numbits)
383 numbits = newbits & 0x07;
386 if ((d = MMCMP_GetBits(&bb, 3)) == 7)
388 if (MMCMP_GetBits(&bb, 1)) break;
401 int n = ptable[newval];
402 if (block.flags & MMCMP_DELTA)
407 destptr[pos++] = (UBYTE)n;
411 if (++i == block.sub_blk) break;
412 size = subblocks[i].unpk_size;
413 destptr = destbuf + subblocks[i].unpk_pos;
421 MikMod_free(pblk_table);
422 MikMod_free(subblocks);
429 MikMod_free(pblk_table);
430 MikMod_free(subblocks);
431 MikMod_free(destbuf);