2002-07-28 15:35:26 +00:00
|
|
|
/* ScummVM - Scumm Interpreter
|
|
|
|
* Copyright (C) 2002 The ScummVM project
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*
|
2002-08-04 17:31:20 +00:00
|
|
|
* $Header$
|
2002-07-28 15:35:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "scumm.h"
|
|
|
|
#include "scummsys.h"
|
|
|
|
#include "bundle.h"
|
2002-08-31 09:50:36 +00:00
|
|
|
#include "file.h"
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
Bundle::Bundle() {
|
2002-08-04 16:30:59 +00:00
|
|
|
_lastSong = -1;
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
Bundle::~Bundle() {
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
2002-09-15 19:28:34 +00:00
|
|
|
bool Bundle::openVoiceFile(const char *filename, const char *directory) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 tag, offset;
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_voiceFile.isOpen() == true)
|
|
|
|
return true;
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-09-15 19:28:34 +00:00
|
|
|
if (_voiceFile.open(filename, directory) == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: Can't open voice bundle file: %s", filename);
|
2002-07-28 15:35:26 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
tag = _voiceFile.readDwordBE();
|
|
|
|
offset = _voiceFile.readDwordBE();
|
|
|
|
_numVoiceFiles = _voiceFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
|
|
|
|
_bundleVoiceTable = (BundleAudioTable *) malloc(_numVoiceFiles * sizeof(BundleAudioTable));
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_voiceFile.seek(offset, SEEK_SET);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
|
|
|
for (int32 i = 0; i < _numVoiceFiles; i++) {
|
|
|
|
char name[13], c;
|
|
|
|
int32 z = 0;
|
|
|
|
int32 z2;
|
2002-08-14 09:52:43 +00:00
|
|
|
|
2002-07-28 15:35:26 +00:00
|
|
|
for (z2 = 0; z2 < 8; z2++)
|
2002-08-31 09:50:36 +00:00
|
|
|
if ((c = _voiceFile.readByte()) != 0)
|
2002-07-28 15:35:26 +00:00
|
|
|
name[z++] = c;
|
|
|
|
name[z++] = '.';
|
|
|
|
for (z2 = 0; z2 < 4; z2++)
|
2002-08-31 09:50:36 +00:00
|
|
|
if ((c = _voiceFile.readByte()) != 0)
|
2002-07-28 15:35:26 +00:00
|
|
|
name[z++] = c;
|
|
|
|
name[z] = '\0';
|
|
|
|
strcpy(_bundleVoiceTable[i].filename, name);
|
2002-08-31 09:50:36 +00:00
|
|
|
_bundleVoiceTable[i].offset = _voiceFile.readDwordBE();
|
|
|
|
_bundleVoiceTable[i].size = _voiceFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-09-15 19:28:34 +00:00
|
|
|
bool Bundle::openMusicFile(const char *filename, const char *directory) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 tag, offset;
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_musicFile.isOpen() == true)
|
|
|
|
return true;
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-09-15 19:28:34 +00:00
|
|
|
if (_musicFile.open(filename, directory) == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: Can't open music bundle file: %s", filename);
|
2002-07-28 15:35:26 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
tag = _musicFile.readDwordBE();
|
|
|
|
offset = _musicFile.readDwordBE();
|
|
|
|
_numMusicFiles = _musicFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
|
|
|
|
_bundleMusicTable = (BundleAudioTable *) malloc(_numMusicFiles * sizeof(BundleAudioTable));
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_musicFile.seek(offset, SEEK_SET);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
|
|
|
for (int32 i = 0; i < _numMusicFiles; i++) {
|
|
|
|
char name[13], c;
|
|
|
|
int z = 0;
|
|
|
|
int z2;
|
2002-08-14 09:52:43 +00:00
|
|
|
|
|
|
|
for (z2 = 0; z2 < 8; z2++)
|
2002-08-31 09:50:36 +00:00
|
|
|
if ((c = _musicFile.readByte()) != 0)
|
2002-07-28 15:35:26 +00:00
|
|
|
name[z++] = c;
|
|
|
|
name[z++] = '.';
|
2002-08-14 09:52:43 +00:00
|
|
|
for (z2 = 0; z2 < 4; z2++)
|
2002-08-31 09:50:36 +00:00
|
|
|
if ((c = _musicFile.readByte()) != 0)
|
2002-07-28 15:35:26 +00:00
|
|
|
name[z++] = c;
|
|
|
|
name[z] = '\0';
|
2002-08-04 16:30:59 +00:00
|
|
|
strcpy(_bundleMusicTable[i].filename, name);
|
2002-08-31 09:50:36 +00:00
|
|
|
_bundleMusicTable[i].offset = _musicFile.readDwordBE();
|
|
|
|
_bundleMusicTable[i].size = _musicFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::decompressVoiceSampleByIndex(int32 index, byte *comp_final) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 i, tag, num, final_size, output_size;
|
2002-08-14 09:52:43 +00:00
|
|
|
byte *comp_input, *comp_output;
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_voiceFile.isOpen() == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: voice file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_voiceFile.seek(_bundleVoiceTable[index].offset, SEEK_SET);
|
|
|
|
tag = _voiceFile.readDwordBE();
|
|
|
|
num = _voiceFile.readDwordBE();
|
|
|
|
_voiceFile.readDwordBE();
|
|
|
|
_voiceFile.readDwordBE();
|
2002-08-14 09:52:43 +00:00
|
|
|
|
2002-07-28 15:35:26 +00:00
|
|
|
if (tag != MKID_BE('COMP')) {
|
2002-08-14 09:52:43 +00:00
|
|
|
warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8,
|
|
|
|
tag);
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < num; i++) {
|
2002-08-31 09:50:36 +00:00
|
|
|
_compVoiceTable[i].offset = _voiceFile.readDwordBE();
|
|
|
|
_compVoiceTable[i].size = _voiceFile.readDwordBE();
|
|
|
|
_compVoiceTable[i].codec = _voiceFile.readDwordBE();
|
|
|
|
_voiceFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
final_size = 0;
|
|
|
|
|
|
|
|
comp_output = (byte *)malloc(10000);
|
|
|
|
for (i = 0; i < num; i++) {
|
2002-08-14 09:52:43 +00:00
|
|
|
comp_input = (byte *)malloc(_compVoiceTable[i].size);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_voiceFile.seek(_bundleVoiceTable[index].offset + _compVoiceTable[i].offset, SEEK_SET);
|
|
|
|
_voiceFile.read(comp_input, _compVoiceTable[i].size);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
output_size =
|
|
|
|
decompressCodec(_compVoiceTable[i].codec, comp_input, comp_output, _compVoiceTable[i].size);
|
2002-07-28 15:35:26 +00:00
|
|
|
memcpy((byte *)&comp_final[final_size], comp_output, output_size);
|
|
|
|
final_size += output_size;
|
|
|
|
|
|
|
|
free(comp_input);
|
|
|
|
}
|
|
|
|
free(comp_output);
|
|
|
|
|
|
|
|
return final_size;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::decompressMusicSampleByIndex(int32 index, int32 number, byte *comp_final) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 i, tag, num, final_size;
|
2002-08-14 09:52:43 +00:00
|
|
|
byte *comp_input;
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_musicFile.isOpen() == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: music file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-08-04 16:30:59 +00:00
|
|
|
if (_lastSong != index) {
|
2002-08-31 09:50:36 +00:00
|
|
|
_musicFile.seek(_bundleMusicTable[index].offset, SEEK_SET);
|
|
|
|
tag = _musicFile.readDwordBE();
|
|
|
|
num = _musicFile.readDwordBE();
|
|
|
|
_musicFile.readDwordBE();
|
|
|
|
_musicFile.readDwordBE();
|
2002-08-14 09:52:43 +00:00
|
|
|
|
2002-08-04 16:30:59 +00:00
|
|
|
if (tag != MKID_BE('COMP')) {
|
2002-08-14 09:52:43 +00:00
|
|
|
warning("Bundle: Compressed sound %d invalid (%c%c%c%c)", index, tag >> 24, tag >> 16, tag >> 8,
|
|
|
|
tag);
|
2002-08-04 16:30:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-04 16:30:59 +00:00
|
|
|
for (i = 0; i < num; i++) {
|
2002-08-31 09:50:36 +00:00
|
|
|
_compMusicTable[i].offset = _musicFile.readDwordBE();
|
|
|
|
_compMusicTable[i].size = _musicFile.readDwordBE();
|
|
|
|
_compMusicTable[i].codec = _musicFile.readDwordBE();
|
|
|
|
_musicFile.readDwordBE();
|
2002-08-04 16:30:59 +00:00
|
|
|
}
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
comp_input = (byte *)malloc(_compMusicTable[number].size);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_musicFile.seek(_bundleMusicTable[index].offset + _compMusicTable[number].offset, SEEK_SET);
|
|
|
|
_musicFile.read(comp_input, _compMusicTable[number].size);
|
2002-08-14 09:52:43 +00:00
|
|
|
final_size =
|
|
|
|
decompressCodec(_compMusicTable[number].codec, comp_input, comp_final, _compMusicTable[number].size);
|
2002-07-28 15:35:26 +00:00
|
|
|
|
|
|
|
free(comp_input);
|
|
|
|
|
2002-08-04 16:30:59 +00:00
|
|
|
_lastSong = index;
|
|
|
|
|
2002-07-28 15:35:26 +00:00
|
|
|
return final_size;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::decompressVoiceSampleByName(char *name, byte *comp_final) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 final_size = 0, i;
|
2002-08-14 09:52:43 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_voiceFile.isOpen() == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: voice file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < _numVoiceFiles; i++) {
|
|
|
|
if (!scumm_stricmp(name, _bundleVoiceTable[i].filename)) {
|
|
|
|
final_size = decompressVoiceSampleByIndex(i, comp_final);
|
|
|
|
return final_size;
|
2002-08-14 09:52:43 +00:00
|
|
|
}
|
|
|
|
}
|
2002-07-28 15:35:26 +00:00
|
|
|
return final_size;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::decompressMusicSampleByName(char *name, int32 number, byte *comp_final) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 final_size = 0, i;
|
2002-08-14 09:52:43 +00:00
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_musicFile.isOpen() == false) {
|
|
|
|
warning("Bundle: music file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < _numMusicFiles; i++) {
|
|
|
|
if (!scumm_stricmp(name, _bundleMusicTable[i].filename)) {
|
|
|
|
final_size = decompressMusicSampleByIndex(i, number, comp_final);
|
|
|
|
return final_size;
|
2002-08-14 09:52:43 +00:00
|
|
|
}
|
|
|
|
}
|
2002-07-28 15:35:26 +00:00
|
|
|
return final_size;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::getNumberOfMusicSamplesByIndex(int32 index) {
|
|
|
|
if (_musicFile.isOpen() == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: music file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
_musicFile.seek(_bundleMusicTable[index].offset, SEEK_SET);
|
|
|
|
_musicFile.readDwordBE();
|
|
|
|
return _musicFile.readDwordBE();
|
2002-07-28 15:35:26 +00:00
|
|
|
}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::getNumberOfMusicSamplesByName(char *name) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 number = 0, i;
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
if (_musicFile.isOpen() == false) {
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: music file is not open!");
|
2002-07-28 15:35:26 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < _numMusicFiles; i++) {
|
|
|
|
if (!scumm_stricmp(name, _bundleMusicTable[i].filename)) {
|
2002-08-14 09:52:43 +00:00
|
|
|
number = getNumberOfMusicSamplesByIndex(i);
|
2002-07-28 15:35:26 +00:00
|
|
|
return number;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return number;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define NextBit bit = mask & 1; mask >>= 1; if (!--bitsleft) {mask = READ_LE_UINT16(srcptr); srcptr += 2; bitsleft=16;}
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::compDecode(byte *src, byte *dst) {
|
2002-08-14 09:52:43 +00:00
|
|
|
byte *result, *srcptr = src, *dstptr = dst;
|
|
|
|
int data, size, bit, bitsleft = 16, mask = READ_LE_UINT16(srcptr);
|
2002-07-28 15:35:26 +00:00
|
|
|
srcptr += 2;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
while (1) {
|
|
|
|
NextBit if (bit) {
|
2002-07-28 15:35:26 +00:00
|
|
|
*dstptr++ = *srcptr++;
|
|
|
|
} else {
|
2002-08-14 09:52:43 +00:00
|
|
|
NextBit if (!bit) {
|
2002-07-28 15:35:26 +00:00
|
|
|
NextBit size = bit << 1;
|
|
|
|
NextBit size = (size | bit) + 3;
|
|
|
|
data = *srcptr++ | 0xffffff00;
|
|
|
|
} else {
|
|
|
|
data = *srcptr++;
|
|
|
|
size = *srcptr++;
|
|
|
|
|
|
|
|
data |= 0xfffff000 + ((size & 0xf0) << 4);
|
|
|
|
size = (size & 0x0f) + 3;
|
|
|
|
|
|
|
|
if (size == 3)
|
2002-08-14 09:52:43 +00:00
|
|
|
if (((*srcptr++) + 1) == 1)
|
2002-07-28 15:35:26 +00:00
|
|
|
return dstptr - dst;
|
|
|
|
}
|
2002-08-14 09:52:43 +00:00
|
|
|
result = dstptr + data;
|
|
|
|
while (size--)
|
2002-07-28 15:35:26 +00:00
|
|
|
*dstptr++ = *result++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#undef NextBit
|
|
|
|
|
2002-08-31 09:50:36 +00:00
|
|
|
int32 Bundle::decompressCodec(int32 codec, byte *comp_input, byte *comp_output, int32 input_size) {
|
2002-07-28 15:35:26 +00:00
|
|
|
int32 output_size = input_size;
|
|
|
|
int32 offset1, offset2, offset3, length, k, c, s, j, r, t, z;
|
2002-08-14 09:52:43 +00:00
|
|
|
byte *src, *t_table, *p, *ptr;
|
2002-07-28 15:35:26 +00:00
|
|
|
byte t_tmp1, t_tmp2;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
switch (codec) {
|
|
|
|
case 0:
|
|
|
|
memcpy(comp_output, comp_input, output_size);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 1:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 2:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 3:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 4:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memset(t_table, 0, output_size);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 0;
|
|
|
|
if (length > 0) {
|
|
|
|
c = -12;
|
|
|
|
s = 0;
|
|
|
|
j = 0;
|
|
|
|
do {
|
|
|
|
ptr = src + length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = c / 8;
|
|
|
|
*(t_table + r + 2) = ((*(src + j) & 0x0f) << 4) | ((*(ptr + 1) & 0xf0) >> 4);
|
|
|
|
*(t_table + r + 1) = (*(src + j) & 0xf0) | (*(t_table + r + 1));
|
|
|
|
} else {
|
|
|
|
r = s / 8;
|
|
|
|
*(t_table + r + 0) = ((*(src + j) & 0x0f) << 4) | (*ptr & 0x0f);
|
|
|
|
*(t_table + r + 1) = (*(src + j) & 0xf0) >> 4;
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
j++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < length);
|
|
|
|
}
|
|
|
|
offset1 = ((length - 1) * 3) / 2;
|
|
|
|
*(t_table + offset1 + 1) = (*(t_table + offset1 + 1)) | *(src + length - 1) & 0xf0;
|
|
|
|
memcpy(src, t_table, output_size);
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 5:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memset(t_table, 0, output_size);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 1;
|
|
|
|
c = 0;
|
|
|
|
s = 12;
|
|
|
|
*t_table = (*(src + length)) >> 4;
|
|
|
|
t = length + k;
|
|
|
|
j = 1;
|
|
|
|
if (t > k) {
|
|
|
|
do {
|
|
|
|
ptr = src + length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = c / 8;
|
|
|
|
*(t_table + r + 0) = (*(src + j - 1) & 0xf0) | (*(t_table + r));
|
|
|
|
*(t_table + r + 1) = ((*(src + j - 1) & 0x0f) << 4) | (*ptr & 0x0f);
|
|
|
|
} else {
|
|
|
|
r = s / 8;
|
|
|
|
*(t_table + r + 0) = (*(src + j - 1) & 0xf0) >> 4;
|
|
|
|
*(t_table + r - 1) = ((*(src + j - 1) & 0x0f) << 4) | ((*ptr & 0xf0) >> 4);
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
j++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < t);
|
|
|
|
}
|
|
|
|
memcpy(src, t_table, output_size);
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 6:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memset(t_table, 0, output_size);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 0;
|
|
|
|
c = 0;
|
|
|
|
j = 0;
|
|
|
|
s = -12;
|
|
|
|
*t_table = *(output_size + src - 1);
|
|
|
|
*(t_table + output_size - 1) = *(src + length - 1);
|
|
|
|
t = length - 1;
|
|
|
|
if (t > 0) {
|
|
|
|
do {
|
|
|
|
ptr = src + length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = s / 8;
|
|
|
|
*(t_table + r + 2) = (*(src + j) & 0xf0) | *(t_table + r + 2);
|
|
|
|
*(t_table + r + 3) = ((*(src + j) & 0x0f) << 4) | ((*ptr & 0xf0) >> 4);
|
|
|
|
} else {
|
|
|
|
r = c / 8;
|
|
|
|
*(t_table + r + 2) = (*(src + j) & 0xf0) >> 4;
|
|
|
|
*(t_table + r + 1) = ((*(src + j) & 0x0f) << 4) | (*ptr & 0x0f);
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
j++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < t);
|
|
|
|
}
|
|
|
|
memcpy(src, t_table, output_size);
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 10:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memcpy(t_table, p, output_size);
|
|
|
|
|
|
|
|
offset1 = output_size / 3;
|
|
|
|
offset2 = offset1 * 2;
|
|
|
|
offset3 = offset2;
|
|
|
|
src = comp_output;
|
|
|
|
do {
|
|
|
|
if (offset1 == 0)
|
|
|
|
break;
|
|
|
|
offset1--;
|
|
|
|
offset2 -= 2;
|
|
|
|
offset3--;
|
|
|
|
*(t_table + offset2 + 0) = *(src + offset1);
|
|
|
|
*(t_table + offset2 + 1) = *(src + offset3);
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 0;
|
|
|
|
if (length > 0) {
|
|
|
|
c = -12;
|
|
|
|
s = 0;
|
2002-07-28 15:35:26 +00:00
|
|
|
do {
|
2002-08-14 09:52:43 +00:00
|
|
|
j = length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = c / 8;
|
|
|
|
t_tmp1 = *(t_table + k);
|
|
|
|
t_tmp2 = *(t_table + j + 1);
|
|
|
|
*(src + r + 2) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
|
|
|
|
*(src + r + 1) = (*(src + r + 1)) | (t_tmp1 & 0xf0);
|
|
|
|
} else {
|
|
|
|
r = s / 8;
|
|
|
|
t_tmp1 = *(t_table + k);
|
|
|
|
t_tmp2 = *(t_table + j);
|
|
|
|
*(src + r + 0) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
|
|
|
|
*(src + r + 1) = ((t_tmp1 & 0xf0) >> 4);
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < length);
|
|
|
|
}
|
|
|
|
offset1 = ((length - 1) * 3) / 2;
|
|
|
|
*(src + offset1 + 1) = (*(t_table + length) & 0xf0) | *(src + offset1 + 1);
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 11:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memcpy(t_table, p, output_size);
|
|
|
|
|
|
|
|
offset1 = output_size / 3;
|
|
|
|
offset2 = offset1 * 2;
|
|
|
|
offset3 = offset2;
|
|
|
|
src = comp_output;
|
|
|
|
do {
|
|
|
|
if (offset1 == 0)
|
|
|
|
break;
|
|
|
|
offset1--;
|
|
|
|
offset2 -= 2;
|
|
|
|
offset3--;
|
|
|
|
*(t_table + offset2 + 0) = *(src + offset1);
|
|
|
|
*(t_table + offset2 + 1) = *(src + offset3);
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 1;
|
|
|
|
c = 0;
|
|
|
|
s = 12;
|
|
|
|
t_tmp1 = (*(t_table + length)) >> 4;
|
|
|
|
*(src) = t_tmp1;
|
|
|
|
t = length + k;
|
|
|
|
if (t > k) {
|
2002-07-28 15:35:26 +00:00
|
|
|
do {
|
2002-08-14 09:52:43 +00:00
|
|
|
j = length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = c / 8;
|
|
|
|
t_tmp1 = *(t_table + k - 1);
|
|
|
|
t_tmp2 = *(t_table + j);
|
|
|
|
*(src + r + 0) = (*(src + r)) | (t_tmp1 & 0xf0);
|
|
|
|
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
|
|
|
|
} else {
|
|
|
|
r = s / 8;
|
|
|
|
t_tmp1 = *(t_table + k - 1);
|
|
|
|
t_tmp2 = *(t_table + j);
|
|
|
|
*(src + r + 0) = (t_tmp1 & 0xf0) >> 4;
|
|
|
|
*(src + r - 1) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < t);
|
|
|
|
}
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
case 12:
|
|
|
|
output_size = compDecode(comp_input, comp_output);
|
|
|
|
p = comp_output;
|
|
|
|
for (z = 2; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
for (z = 1; z < output_size; z++)
|
|
|
|
p[z] += p[z - 1];
|
|
|
|
|
|
|
|
t_table = (byte *)malloc(output_size);
|
|
|
|
memcpy(t_table, p, output_size);
|
|
|
|
|
|
|
|
offset1 = output_size / 3;
|
|
|
|
offset2 = offset1 * 2;
|
|
|
|
offset3 = offset2;
|
|
|
|
src = comp_output;
|
|
|
|
do {
|
|
|
|
if (offset1 == 0)
|
|
|
|
break;
|
|
|
|
offset1--;
|
|
|
|
offset2 -= 2;
|
|
|
|
offset3--;
|
|
|
|
*(t_table + offset2 + 0) = *(src + offset1);
|
|
|
|
*(t_table + offset2 + 1) = *(src + offset3);
|
|
|
|
} while (1);
|
|
|
|
|
|
|
|
src = comp_output;
|
|
|
|
length = (output_size * 8) / 12;
|
|
|
|
k = 0;
|
|
|
|
c = 0;
|
|
|
|
s = -12;
|
|
|
|
*(src) = *(output_size + t_table - 1);
|
|
|
|
*(src + output_size - 1) = *(t_table + length - 1);
|
|
|
|
t = length - 1;
|
|
|
|
if (t > 0) {
|
2002-07-28 15:35:26 +00:00
|
|
|
do {
|
2002-08-14 09:52:43 +00:00
|
|
|
j = length + (k / 2);
|
|
|
|
if (k & 1) {
|
|
|
|
r = s / 8;
|
|
|
|
t_tmp1 = *(t_table + k);
|
|
|
|
t_tmp2 = *(t_table + j);
|
|
|
|
*(src + r + 2) = (*(src + r + 2)) | (t_tmp1 & 0xf0);
|
|
|
|
*(src + r + 3) = ((t_tmp1 & 0x0f) << 4) | ((t_tmp2 & 0xf0) >> 4);
|
|
|
|
} else {
|
|
|
|
r = c / 8;
|
|
|
|
t_tmp1 = *(t_table + k);
|
|
|
|
t_tmp2 = *(t_table + j);
|
|
|
|
*(src + r + 2) = (t_tmp1 & 0xf0) >> 4;
|
|
|
|
*(src + r + 1) = ((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f);
|
|
|
|
}
|
|
|
|
s += 12;
|
|
|
|
k++;
|
|
|
|
c += 12;
|
|
|
|
} while (k < t);
|
|
|
|
}
|
|
|
|
free(t_table);
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
|
2002-08-14 09:52:43 +00:00
|
|
|
default:
|
2002-08-25 10:50:18 +00:00
|
|
|
warning("Bundle: Unknown codec %d!", (int)codec);
|
2002-08-14 09:52:43 +00:00
|
|
|
output_size = 0;
|
2002-07-28 15:35:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return output_size;
|
|
|
|
}
|