mirror of
https://github.com/dyne/FreeJ.git
synced 2026-02-12 15:50:45 +01:00
flash vectorial graphics in a layer git-svn-id: svn://dyne.org/rastasoft/freej/freej@621 383723c8-4afa-0310-b8a8-b1afb83214fc
236 lines
4.5 KiB
C++
236 lines
4.5 KiB
C++
|
|
#include "swf.h"
|
|
|
|
#ifdef RCSID
|
|
static char *rcsid = "$Id: adpcm.cc,v 1.1.1.1 2004/06/04 21:16:57 tgc Exp $";
|
|
#endif
|
|
|
|
// This file has been rearranged from the code posted
|
|
// on news:forums.macromedia.com by Jonathan Gay.
|
|
// Courtesy of Macromedia
|
|
|
|
//
|
|
// ADPCM tables
|
|
//
|
|
|
|
static const int indexTable2[2] = {
|
|
-1, 2,
|
|
};
|
|
|
|
// Is this ok?
|
|
static const int indexTable3[4] = {
|
|
-1, -1, 2, 4,
|
|
};
|
|
|
|
static const int indexTable4[8] = {
|
|
-1, -1, -1, -1, 2, 4, 6, 8,
|
|
};
|
|
|
|
static const int indexTable5[16] = {
|
|
-1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
|
|
};
|
|
|
|
static const int* indexTables[] = {
|
|
indexTable2,
|
|
indexTable3,
|
|
indexTable4,
|
|
indexTable5
|
|
};
|
|
|
|
static const int stepsizeTable[89] = {
|
|
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
|
|
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
|
|
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
|
|
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
|
|
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
|
|
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
|
|
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
|
|
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
|
|
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
|
|
};
|
|
|
|
long
|
|
Adpcm::GetBits(int n)
|
|
{
|
|
if ( bitPos < n ) FillBuffer();
|
|
|
|
assert(bitPos >= n);
|
|
|
|
long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
|
|
bitPos -= n;
|
|
|
|
return v;
|
|
}
|
|
|
|
long
|
|
Adpcm::GetSBits(int n)
|
|
{
|
|
if ( bitPos < n ) FillBuffer();
|
|
|
|
assert(bitPos >= n);
|
|
|
|
long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
|
|
bitPos -= n;
|
|
|
|
return v;
|
|
}
|
|
|
|
//
|
|
// The Decompressor
|
|
//
|
|
|
|
// Constructor
|
|
Adpcm::Adpcm(unsigned char *buffer, long isStereo)
|
|
{
|
|
stereo = isStereo;
|
|
src = buffer;
|
|
|
|
nBits = 0; // flag that it is not inited
|
|
nSamples = 0;
|
|
|
|
bitPos = 0;
|
|
bitBuf = 0;
|
|
}
|
|
|
|
void
|
|
Adpcm::FillBuffer()
|
|
{
|
|
while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
|
|
bitBuf = (bitBuf<<8) | *src++;
|
|
bitPos += 8;
|
|
}
|
|
}
|
|
|
|
void
|
|
Adpcm::Decompress(short *dst, long n)
|
|
{
|
|
if ( nBits == 0 ) {
|
|
// Get the compression header
|
|
nBits = (int)GetBits(2)+2;
|
|
}
|
|
|
|
const int* indexTable = indexTables[nBits-2];
|
|
int k0 = 1 << (nBits-2);
|
|
int signmask = 1 << (nBits-1);
|
|
|
|
if ( !stereo ) {
|
|
// Optimize for mono
|
|
long vp = valpred[0]; // maybe these can get into registers...
|
|
int ind = index[0];
|
|
long ns = nSamples;
|
|
|
|
while ( n-- > 0 ) {
|
|
ns++;
|
|
|
|
if ( (ns & 0xFFF) == 1 ) {
|
|
// Get a new block header
|
|
*dst++ = (short)(vp = GetSBits(16));
|
|
|
|
ind = (int)GetBits(6); // The first sample in a block does not have a delta
|
|
} else {
|
|
// Process a delta value
|
|
int delta = (int)GetBits(nBits);
|
|
|
|
// Compute difference and new predicted value
|
|
// Computes 'vpdiff = (delta+0.5)*step/4'
|
|
int step = stepsizeTable[ind];
|
|
long vpdiff = 0;
|
|
int k = k0;
|
|
|
|
do {
|
|
if ( delta & k )
|
|
vpdiff += step;
|
|
step >>= 1;
|
|
k >>= 1;
|
|
} while ( k );
|
|
|
|
vpdiff += step; // add 0.5
|
|
|
|
if ( delta & signmask ) // the sign bit
|
|
vp -= vpdiff;
|
|
else
|
|
vp += vpdiff;
|
|
|
|
// Find new index value
|
|
ind += indexTable[delta&(~signmask)];
|
|
|
|
if ( ind < 0 )
|
|
ind = 0;
|
|
else if ( ind > 88 )
|
|
ind = 88;
|
|
|
|
// clamp output value
|
|
if ( vp != (short)vp )
|
|
vp = vp < 0 ? -32768 : 32767;
|
|
|
|
/* Step 7 - Output value */
|
|
*dst++ = (short)vp;
|
|
}
|
|
}
|
|
|
|
valpred[0] = vp;
|
|
index[0] = ind;
|
|
nSamples = ns;
|
|
|
|
} else {
|
|
int sn = stereo ? 2 : 1;
|
|
|
|
// Stereo
|
|
while ( n-- > 0 ) {
|
|
|
|
nSamples++;
|
|
|
|
if ( (nSamples & 0xFFF) == 1 ) {
|
|
// Get a new block header
|
|
for ( int i = 0; i < sn; i++ ) {
|
|
|
|
*dst++ = (short)(valpred[i] = GetSBits(16));
|
|
|
|
// The first sample in a block does not have a delta
|
|
index[i] = (int)GetBits(6);
|
|
}
|
|
} else {
|
|
// Process a delta value
|
|
for ( int i = 0; i < sn; i++ ) {
|
|
int delta = (int)GetBits(nBits);
|
|
|
|
// Compute difference and new predicted value
|
|
// Computes 'vpdiff = (delta+0.5)*step/4'
|
|
|
|
int step = stepsizeTable[index[i]];
|
|
long vpdiff = 0;
|
|
int k = k0;
|
|
|
|
do {
|
|
if ( delta & k ) vpdiff += step;
|
|
step >>= 1;
|
|
k >>= 1;
|
|
} while ( k );
|
|
vpdiff += step; // add 0.5
|
|
|
|
|
|
if ( delta & signmask ) // the sign bit
|
|
valpred[i] -= vpdiff;
|
|
else
|
|
valpred[i] += vpdiff;
|
|
|
|
// Find new index value
|
|
index[i] += indexTable[delta&(~signmask)];
|
|
|
|
if ( index[i] < 0 )
|
|
index[i] = 0;
|
|
else if ( index[i] > 88 )
|
|
index[i] = 88;
|
|
|
|
// clamp output value
|
|
if ( valpred[i] != (short)valpred[i] )
|
|
valpred[i] = valpred[i] < 0 ? -32768 : 32767;
|
|
|
|
/* Step 7 - Output value */
|
|
*dst++ = (short)valpred[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|