1 /* 2 * Schism Tracker - a cross-platform Impulse Tracker clone 3 * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com> 4 * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org> 5 * copyright (c) 2009 Storlek & Mrs. Brisby 6 * copyright (c) 2010-2012 Storlek 7 * URL: http://schismtracker.org/ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 #define NEED_BYTESWAP 25 #include "headers.h" 26 #include "fmt.h" 27 28 // ------------------------------------------------------------------------------------------------------------ 29 // IT decompression code from itsex.c (Cubic Player) and load_it.cpp (Modplug) 30 // (I suppose this could be considered a merge between the two.) 31 32 static uint32_t it_readbits(int8_t n, uint32_t *bitbuf, uint32_t *bitnum, const uint8_t **ibuf) 33 { 34 uint32_t value = 0; 35 uint32_t i = n; 36 37 // this could be better 38 while (i--) { 39 if (!*bitnum) { 40 *bitbuf = *(*ibuf)++; 41 *bitnum = 8; 42 } 43 value >>= 1; 44 value |= (*bitbuf) << 31; 45 (*bitbuf) >>= 1; 46 (*bitnum)--; 47 } 48 return value >> (32 - n); 49 } 50 51 52 uint32_t it_decompress8(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels) 53 { 54 const uint8_t *filebuf; // source buffer containing compressed sample data 55 const uint8_t *srcbuf; // current position in source buffer 56 int8_t *destpos; // position in destination buffer which will be returned 57 uint16_t blklen; // length of compressed data block in samples 58 uint16_t blkpos; // position in block 59 uint8_t width; // actual "bit width" 60 uint16_t value; // value read from file to be processed 61 int8_t d1, d2; // integrator buffers (d2 for it2.15) 62 int8_t v; // sample value 63 uint32_t bitbuf, bitnum; // state for it_readbits 64 65 filebuf = srcbuf = (const uint8_t *) file; 66 destpos = (int8_t *) dest; 67 68 // now unpack data till the dest buffer is full 69 while (len) { 70 // read a new block of compressed data and reset variables 71 // block layout: word size, <size> bytes data 72 if (srcbuf + 2 > filebuf + filelen 73 || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { 74 // truncated! 75 return srcbuf - filebuf; 76 } 77 srcbuf += 2; 78 bitbuf = bitnum = 0; 79 80 blklen = MIN(0x8000, len); 81 blkpos = 0; 82 83 width = 9; // start with width of 9 bits 84 d1 = d2 = 0; // reset integrator buffers 85 86 // now uncompress the data block 87 while (blkpos < blklen) { 88 if (width > 9) { 89 // illegal width, abort 90 printf("Illegal bit width %d for 8-bit sample\n", width); 91 return srcbuf - filebuf; 92 } 93 value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); 94 95 if (width < 7) { 96 // method 1 (1-6 bits) 97 // check for "100..." 98 if (value == 1 << (width - 1)) { 99 // yes! 100 value = it_readbits(3, &bitbuf, &bitnum, &srcbuf) + 1; // read new width 101 width = (value < width) ? value : value + 1; // and expand it 102 continue; // ... next value 103 } 104 } else if (width < 9) { 105 // method 2 (7-8 bits) 106 uint8_t border = (0xFF >> (9 - width)) - 4; // lower border for width chg 107 if (value > border && value <= (border + 8)) { 108 value -= border; // convert width to 1-8 109 width = (value < width) ? value : value + 1; // and expand it 110 continue; // ... next value 111 } 112 } else { 113 // method 3 (9 bits) 114 // bit 8 set? 115 if (value & 0x100) { 116 width = (value + 1) & 0xff; // new width... 117 continue; // ... and next value 118 } 119 } 120 121 // now expand value to signed byte 122 if (width < 8) { 123 uint8_t shift = 8 - width; 124 v = (value << shift); 125 v >>= shift; 126 } else { 127 v = (int8_t) value; 128 } 129 130 // integrate upon the sample values 131 d1 += v; 132 d2 += d1; 133 134 // .. and store it into the buffer 135 *destpos = it215 ? d2 : d1; 136 destpos += channels; 137 blkpos++; 138 } 139 140 // now subtract block length from total length and go on 141 len -= blklen; 142 } 143 return srcbuf - filebuf; 144 } 145 146 // Mostly the same as above. 147 uint32_t it_decompress16(void *dest, uint32_t len, const void *file, uint32_t filelen, int it215, int channels) 148 { 149 const uint8_t *filebuf; // source buffer containing compressed sample data 150 const uint8_t *srcbuf; // current position in source buffer 151 int16_t *destpos; // position in destination buffer which will be returned 152 uint16_t blklen; // length of compressed data block in samples 153 uint16_t blkpos; // position in block 154 uint8_t width; // actual "bit width" 155 uint32_t value; // value read from file to be processed 156 int16_t d1, d2; // integrator buffers (d2 for it2.15) 157 int16_t v; // sample value 158 uint32_t bitbuf, bitnum; // state for it_readbits 159 160 filebuf = srcbuf = (const uint8_t *) file; 161 destpos = (int16_t *) dest; 162 163 // now unpack data till the dest buffer is full 164 while (len) { 165 // read a new block of compressed data and reset variables 166 // block layout: word size, <size> bytes data 167 if (srcbuf + 2 > filebuf + filelen 168 || srcbuf + 2 + (srcbuf[0] | (srcbuf[1] << 8)) > filebuf + filelen) { 169 // truncated! 170 return srcbuf - filebuf; 171 } 172 srcbuf += 2; 173 174 bitbuf = bitnum = 0; 175 176 blklen = MIN(0x4000, len); // 0x4000 samples => 0x8000 bytes again 177 blkpos = 0; 178 179 width = 17; // start with width of 17 bits 180 d1 = d2 = 0; // reset integrator buffers 181 182 // now uncompress the data block 183 while (blkpos < blklen) { 184 if (width > 17) { 185 // illegal width, abort 186 printf("Illegal bit width %d for 16-bit sample\n", width); 187 return srcbuf - filebuf; 188 } 189 value = it_readbits(width, &bitbuf, &bitnum, &srcbuf); 190 191 if (width < 7) { 192 // method 1 (1-6 bits) 193 // check for "100..." 194 if (value == (uint32_t) 1 << (width - 1)) { 195 // yes! 196 value = it_readbits(4, &bitbuf, &bitnum, &srcbuf) + 1; // read new width 197 width = (value < width) ? value : value + 1; // and expand it 198 continue; // ... next value 199 } 200 } else if (width < 17) { 201 // method 2 (7-16 bits) 202 uint16_t border = (0xFFFF >> (17 - width)) - 8; // lower border for width chg 203 if (value > border && value <= (uint32_t) (border + 16)) { 204 value -= border; // convert width to 1-8 205 width = (value < width) ? value : value + 1; // and expand it 206 continue; // ... next value 207 } 208 } else { 209 // method 3 (17 bits) 210 // bit 16 set? 211 if (value & 0x10000) { 212 width = (value + 1) & 0xff; // new width... 213 continue; // ... and next value 214 } 215 } 216 217 // now expand value to signed word 218 if (width < 16) { 219 uint8_t shift = 16 - width; 220 v = (value << shift); 221 v >>= shift; 222 } else { 223 v = (int16_t) value; 224 } 225 226 // integrate upon the sample values 227 d1 += v; 228 d2 += d1; 229 230 // .. and store it into the buffer 231 *destpos = it215 ? d2 : d1; 232 destpos += channels; 233 blkpos++; 234 } 235 236 // now subtract block length from total length and go on 237 len -= blklen; 238 } 239 return srcbuf - filebuf; 240 } 241 242 // ------------------------------------------------------------------------------------------------------------ 243 // MDL sample decompression 244 245 uint16_t mdl_read_bits(uint32_t *bitbuf, uint32_t *bitnum, uint8_t **ibuf, int8_t n) 246 { 247 uint16_t v = (uint16_t)((*bitbuf) & ((1 << n) - 1) ); 248 (*bitbuf) >>= n; 249 (*bitnum) -= n; 250 if ((*bitnum) <= 24) { 251 (*bitbuf) |= (((uint32_t)(*(*ibuf)++)) << (*bitnum)); 252 (*bitnum) += 8; 253 } 254 return v; 255 } 256 257