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 /* amiga Powerpack PP20 decompression support
22 * Code from Heikki Orsila's amigadepack 0.02
23 * based on code by Stuart Caie <kyzer@4u.net>
24 * This software is in the Public Domain
26 * Modified for xmp by Claudio Matsuoka, 08/2007
27 * - merged mld's checks from the old depack sources. Original credits:
28 * - corrupt file and data detection
29 * (thanks to Don Adan and Dirk Stoecker for help and infos)
30 * - implemeted "efficiency" checks
31 * - further detection based on code by Georg Hoermann
33 * Modified for xmp by Claudio Matsuoka, 05/2013
34 * - decryption code removed
36 * Modified for libmikmod by O. Sezer, Apr. 2015, with a few extra bits
37 * from the libmodplug library by Olivier Lapicque.
54 #include "mikmod_internals.h"
57 extern int fprintf(FILE *, const char *, ...);
60 #define PP_READ_BITS(nbits, var) do { \
62 while (bits_left < bit_cnt) { \
63 if (buf_src < src) return 0; /* out of source bits */ \
64 bit_buffer |= (*--buf_src << bits_left); \
68 bits_left -= bit_cnt; \
70 (var) = ((var) << 1) | (bit_buffer & 1); \
75 #define PP_BYTE_OUT(byte) do { \
76 if (out <= dest) return 0; /* output overflow */ \
81 static BOOL ppDecrunch(const UBYTE *src, UBYTE *dest,
82 const UBYTE *offset_lens,
83 ULONG src_len, ULONG dest_len,
86 ULONG bit_buffer, x, todo, offbits, offset, written;
88 UBYTE *out, *dest_end, bits_left, bit_cnt;
90 /* set up input and output pointers */
91 buf_src = src + src_len;
92 out = dest_end = dest + dest_len;
98 /* skip the first few bits */
99 PP_READ_BITS(skip_bits, x);
101 /* while there are input bits left */
102 while (written < dest_len) {
105 /* 1bit==0: literal, then match. 1bit==1: just match */
106 todo = 1; do { PP_READ_BITS(2, x); todo += x; } while (x == 3);
107 while (todo--) { PP_READ_BITS(8, x); PP_BYTE_OUT(x); }
109 /* should we end decoding on a literal, break out of the main loop */
110 if (written == dest_len) break;
113 /* match: read 2 bits for initial offset bitlength / match length */
115 offbits = offset_lens[x];
119 if (x==0) offbits = 7;
120 PP_READ_BITS(offbits, offset);
121 do { PP_READ_BITS(3, x); todo += x; } while (x == 7);
124 PP_READ_BITS(offbits, offset);
126 if ((out + offset) >= dest_end) return 0; /* match overflow */
127 while (todo--) { x = out[offset]; PP_BYTE_OUT(x); }
130 /* all output bytes written without error */
132 /* return (src == buf_src) ? 1 : 0; */
135 BOOL PP20_Unpack(MREADER* reader, void** out, long* outlen)
137 ULONG srclen, destlen;
138 UBYTE *destbuf, *srcbuf;
143 * 1 longword identifier 'PP20' or 'PX20'
144 * [1 word checksum (if 'PX20') $ssss]
145 * 1 longword efficiency $eeeeeeee
146 * X longwords crunched file $cccccccc,$cccccccc,...
147 * 1 longword decrunch info 'decrlen' << 8 | '8 bits other info'
150 _mm_fseek(reader,0,SEEK_END);
151 srclen = _mm_ftell(reader);
152 if (srclen < 256) return 0;
153 /* file length should be a multiple of 4 */
154 if (srclen & 3) return 0;
157 if (_mm_read_I_ULONG(reader) != 0x30325050) /* 'PP20' */
160 _mm_fseek(reader,srclen-4,SEEK_SET);
161 _mm_read_UBYTES(tmp,4,reader);
162 destlen = tmp[0] << 16;
163 destlen |= tmp[1] << 8;
167 _mm_fseek(reader,4,SEEK_SET);
168 _mm_read_UBYTES(tmp,4,reader);
170 /* original pp20 only support efficiency
171 * from 9 9 9 9 up to 9 10 12 13, afaik,
172 * but the xfd detection code says this...
177 * and.l #$f0f0f0f0,d0
180 if ((tmp[0] < 9) || (tmp[0] & 0xf0)) return 0;
181 if ((tmp[1] < 9) || (tmp[1] & 0xf0)) return 0;
182 if ((tmp[2] < 9) || (tmp[2] & 0xf0)) return 0;
183 if ((tmp[3] < 9) || (tmp[3] & 0xf0)) return 0;
185 if ((destlen < 512) || (destlen > 0x400000) || (destlen > 16*srclen))
187 if ((destbuf = (UBYTE*)MikMod_malloc(destlen)) == NULL)
191 if ((srcbuf = (UBYTE*)MikMod_malloc(srclen)) == NULL) {
192 MikMod_free(destbuf);
195 _mm_read_UBYTES(srcbuf,srclen,reader);
197 ret = ppDecrunch(srcbuf, destbuf, tmp, srclen, destlen, skip);
201 MikMod_free(destbuf);