mirror of https://github.com/PCSX2/pcsx2.git
Re-Added eol-style:native properties to the repository. The settings got lost when we merged from Playground to Official.
Added interface.cpp (plugin/pcsx2 interface) and savestate.cpp to SPU2ghz, to help clean up SPU2.cpp. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@463 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d2ef18113c
commit
6ebfae8ef1
|
@ -1,350 +1,350 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon
|
||||
/// processors. All 3DNow! optimized functions have been gathered into this
|
||||
/// single source code file, regardless to their class or original source code
|
||||
/// file, in order to ease porting the library to other compiler and processor
|
||||
/// platforms.
|
||||
///
|
||||
/// By the way; the performance gain depends heavily on the CPU generation: On
|
||||
/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the
|
||||
/// difference to the original routines stayed at unremarkable 8%! Such a small
|
||||
/// improvement on Athlon is due to 3DNow can perform only two operations in
|
||||
/// parallel, and obviously also the Athlon FPU is doing a very good job with
|
||||
/// the standard C floating point routines! Here these routines are anyway,
|
||||
/// although it might not be worth the effort to convert these to GCC platform,
|
||||
/// for Athlon CPU at least. The situation is different regarding the SSE
|
||||
/// optimizations though, thanks to the four parallel operations of SSE that
|
||||
/// already make a difference.
|
||||
///
|
||||
/// This file is to be compiled in Windows platform with Microsoft Visual C++
|
||||
/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all
|
||||
/// GNU platforms (if file supplied).
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support 3DNow! instruction set. The update is
|
||||
/// available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
||||
/// perform a search with keywords "processor pack".
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: 3dnow_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#error "wrong platform - this source code file is exclusively for Win32 platform"
|
||||
#endif
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
// 3DNow! routines available only with float sample type
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of 3DNow! optimized functions of class 'TDStretch3DNow'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <limits.h>
|
||||
|
||||
// these are declared in 'TDStretch.cpp'
|
||||
extern int scanOffsets[4][24];
|
||||
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const
|
||||
{
|
||||
uint overlapLengthLocal = overlapLength;
|
||||
float corr;
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
/*
|
||||
c-pseudocode:
|
||||
|
||||
corr = 0;
|
||||
for (i = 0; i < overlapLength / 4; i ++)
|
||||
{
|
||||
corr += pV1[0] * pV2[0];
|
||||
pV1[1] * pV2[1];
|
||||
pV1[2] * pV2[2];
|
||||
pV1[3] * pV2[3];
|
||||
pV1[4] * pV2[4];
|
||||
pV1[5] * pV2[5];
|
||||
pV1[6] * pV2[6];
|
||||
pV1[7] * pV2[7];
|
||||
|
||||
pV1 += 8;
|
||||
pV2 += 8;
|
||||
}
|
||||
*/
|
||||
|
||||
_asm
|
||||
{
|
||||
// give prefetch hints to CPU of what data are to be needed soonish.
|
||||
// give more aggressive hints on pV1 as that changes more between different calls
|
||||
// while pV2 stays the same.
|
||||
prefetch [pV1]
|
||||
prefetch [pV2]
|
||||
prefetch [pV1 + 32]
|
||||
|
||||
mov eax, dword ptr pV2
|
||||
mov ebx, dword ptr pV1
|
||||
|
||||
pxor mm0, mm0
|
||||
|
||||
mov ecx, overlapLengthLocal
|
||||
shr ecx, 2 // div by four
|
||||
|
||||
loop1:
|
||||
movq mm1, [eax]
|
||||
prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm1, [ebx]
|
||||
prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movq mm2, [eax + 8]
|
||||
pfadd mm0, mm1
|
||||
pfmul mm2, [ebx + 8]
|
||||
|
||||
movq mm3, [eax + 16]
|
||||
pfadd mm0, mm2
|
||||
pfmul mm3, [ebx + 16]
|
||||
|
||||
movq mm4, [eax + 24]
|
||||
pfadd mm0, mm3
|
||||
pfmul mm4, [ebx + 24]
|
||||
|
||||
add eax, 32
|
||||
pfadd mm0, mm4
|
||||
add ebx, 32
|
||||
|
||||
dec ecx
|
||||
jnz loop1
|
||||
|
||||
// add halfs of mm0 together and return the result.
|
||||
// note: mm1 is used as a dummy parameter only, we actually don't care about it's value
|
||||
pfacc mm0, mm1
|
||||
movd corr, mm0
|
||||
femms
|
||||
}
|
||||
|
||||
return corr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of 3DNow! optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
FIRFilter3DNow::FIRFilter3DNow() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter3DNow::~FIRFilter3DNow()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for 3DNow! routine
|
||||
void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
float fDivider;
|
||||
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||
// also rearrange coefficients suitably for 3DNow!
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||
filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
fDivider = (float)resultDivider;
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0; i < newLength; i ++)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] =
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 3DNow!-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, const uint numSamples) const
|
||||
{
|
||||
float *filterCoeffsLocal = filterCoeffsAlign;
|
||||
uint count = (numSamples - length) & -2;
|
||||
uint lengthLocal = length / 4;
|
||||
|
||||
assert(length != 0);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
/* original code:
|
||||
|
||||
double suml1, suml2;
|
||||
double sumr1, sumr2;
|
||||
uint i, j;
|
||||
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
suml1 = sumr1 = 0.0;
|
||||
suml2 = sumr2 = 0.0;
|
||||
ptr = src;
|
||||
filterCoeffsLocal = filterCoeffs;
|
||||
for (i = 0; i < lengthLocal; i ++)
|
||||
{
|
||||
// unroll loop for efficiency.
|
||||
|
||||
suml1 += ptr[0] * filterCoeffsLocal[0] +
|
||||
ptr[2] * filterCoeffsLocal[2] +
|
||||
ptr[4] * filterCoeffsLocal[4] +
|
||||
ptr[6] * filterCoeffsLocal[6];
|
||||
|
||||
sumr1 += ptr[1] * filterCoeffsLocal[1] +
|
||||
ptr[3] * filterCoeffsLocal[3] +
|
||||
ptr[5] * filterCoeffsLocal[5] +
|
||||
ptr[7] * filterCoeffsLocal[7];
|
||||
|
||||
suml2 += ptr[8] * filterCoeffsLocal[0] +
|
||||
ptr[10] * filterCoeffsLocal[2] +
|
||||
ptr[12] * filterCoeffsLocal[4] +
|
||||
ptr[14] * filterCoeffsLocal[6];
|
||||
|
||||
sumr2 += ptr[9] * filterCoeffsLocal[1] +
|
||||
ptr[11] * filterCoeffsLocal[3] +
|
||||
ptr[13] * filterCoeffsLocal[5] +
|
||||
ptr[15] * filterCoeffsLocal[7];
|
||||
|
||||
ptr += 16;
|
||||
filterCoeffsLocal += 8;
|
||||
}
|
||||
dest[0] = (float)suml1;
|
||||
dest[1] = (float)sumr1;
|
||||
dest[2] = (float)suml2;
|
||||
dest[3] = (float)sumr2;
|
||||
|
||||
src += 4;
|
||||
dest += 4;
|
||||
}
|
||||
|
||||
*/
|
||||
_asm
|
||||
{
|
||||
mov eax, dword ptr dest
|
||||
mov ebx, dword ptr src
|
||||
mov edx, count
|
||||
shr edx, 1
|
||||
|
||||
loop1:
|
||||
// "outer loop" : during each round 2*2 output samples are calculated
|
||||
prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
mov esi, ebx
|
||||
mov edi, filterCoeffsLocal
|
||||
pxor mm0, mm0
|
||||
pxor mm1, mm1
|
||||
mov ecx, lengthLocal
|
||||
|
||||
loop2:
|
||||
// "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples
|
||||
movq mm2, [edi]
|
||||
movq mm3, mm2
|
||||
prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm2, [esi]
|
||||
prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm3, [esi + 8]
|
||||
|
||||
movq mm4, [edi + 8]
|
||||
movq mm5, mm4
|
||||
pfadd mm0, mm2
|
||||
pfmul mm4, [esi + 8]
|
||||
pfadd mm1, mm3
|
||||
pfmul mm5, [esi + 16]
|
||||
|
||||
movq mm2, [edi + 16]
|
||||
movq mm6, mm2
|
||||
pfadd mm0, mm4
|
||||
pfmul mm2, [esi + 16]
|
||||
pfadd mm1, mm5
|
||||
pfmul mm6, [esi + 24]
|
||||
|
||||
movq mm3, [edi + 24]
|
||||
movq mm7, mm3
|
||||
pfadd mm0, mm2
|
||||
pfmul mm3, [esi + 24]
|
||||
pfadd mm1, mm6
|
||||
pfmul mm7, [esi + 32]
|
||||
add esi, 32
|
||||
pfadd mm0, mm3
|
||||
add edi, 32
|
||||
pfadd mm1, mm7
|
||||
|
||||
dec ecx
|
||||
jnz loop2
|
||||
|
||||
movq [eax], mm0
|
||||
add ebx, 16
|
||||
movq [eax + 8], mm1
|
||||
add eax, 16
|
||||
|
||||
dec edx
|
||||
jnz loop1
|
||||
|
||||
femms
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#endif // ALLOW_3DNOW
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon
|
||||
/// processors. All 3DNow! optimized functions have been gathered into this
|
||||
/// single source code file, regardless to their class or original source code
|
||||
/// file, in order to ease porting the library to other compiler and processor
|
||||
/// platforms.
|
||||
///
|
||||
/// By the way; the performance gain depends heavily on the CPU generation: On
|
||||
/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the
|
||||
/// difference to the original routines stayed at unremarkable 8%! Such a small
|
||||
/// improvement on Athlon is due to 3DNow can perform only two operations in
|
||||
/// parallel, and obviously also the Athlon FPU is doing a very good job with
|
||||
/// the standard C floating point routines! Here these routines are anyway,
|
||||
/// although it might not be worth the effort to convert these to GCC platform,
|
||||
/// for Athlon CPU at least. The situation is different regarding the SSE
|
||||
/// optimizations though, thanks to the four parallel operations of SSE that
|
||||
/// already make a difference.
|
||||
///
|
||||
/// This file is to be compiled in Windows platform with Microsoft Visual C++
|
||||
/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all
|
||||
/// GNU platforms (if file supplied).
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support 3DNow! instruction set. The update is
|
||||
/// available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
||||
/// perform a search with keywords "processor pack".
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: 3dnow_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#error "wrong platform - this source code file is exclusively for Win32 platform"
|
||||
#endif
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
// 3DNow! routines available only with float sample type
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of 3DNow! optimized functions of class 'TDStretch3DNow'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <limits.h>
|
||||
|
||||
// these are declared in 'TDStretch.cpp'
|
||||
extern int scanOffsets[4][24];
|
||||
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const
|
||||
{
|
||||
uint overlapLengthLocal = overlapLength;
|
||||
float corr;
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
/*
|
||||
c-pseudocode:
|
||||
|
||||
corr = 0;
|
||||
for (i = 0; i < overlapLength / 4; i ++)
|
||||
{
|
||||
corr += pV1[0] * pV2[0];
|
||||
pV1[1] * pV2[1];
|
||||
pV1[2] * pV2[2];
|
||||
pV1[3] * pV2[3];
|
||||
pV1[4] * pV2[4];
|
||||
pV1[5] * pV2[5];
|
||||
pV1[6] * pV2[6];
|
||||
pV1[7] * pV2[7];
|
||||
|
||||
pV1 += 8;
|
||||
pV2 += 8;
|
||||
}
|
||||
*/
|
||||
|
||||
_asm
|
||||
{
|
||||
// give prefetch hints to CPU of what data are to be needed soonish.
|
||||
// give more aggressive hints on pV1 as that changes more between different calls
|
||||
// while pV2 stays the same.
|
||||
prefetch [pV1]
|
||||
prefetch [pV2]
|
||||
prefetch [pV1 + 32]
|
||||
|
||||
mov eax, dword ptr pV2
|
||||
mov ebx, dword ptr pV1
|
||||
|
||||
pxor mm0, mm0
|
||||
|
||||
mov ecx, overlapLengthLocal
|
||||
shr ecx, 2 // div by four
|
||||
|
||||
loop1:
|
||||
movq mm1, [eax]
|
||||
prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm1, [ebx]
|
||||
prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movq mm2, [eax + 8]
|
||||
pfadd mm0, mm1
|
||||
pfmul mm2, [ebx + 8]
|
||||
|
||||
movq mm3, [eax + 16]
|
||||
pfadd mm0, mm2
|
||||
pfmul mm3, [ebx + 16]
|
||||
|
||||
movq mm4, [eax + 24]
|
||||
pfadd mm0, mm3
|
||||
pfmul mm4, [ebx + 24]
|
||||
|
||||
add eax, 32
|
||||
pfadd mm0, mm4
|
||||
add ebx, 32
|
||||
|
||||
dec ecx
|
||||
jnz loop1
|
||||
|
||||
// add halfs of mm0 together and return the result.
|
||||
// note: mm1 is used as a dummy parameter only, we actually don't care about it's value
|
||||
pfacc mm0, mm1
|
||||
movd corr, mm0
|
||||
femms
|
||||
}
|
||||
|
||||
return corr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of 3DNow! optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
FIRFilter3DNow::FIRFilter3DNow() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter3DNow::~FIRFilter3DNow()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for 3DNow! routine
|
||||
void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
float fDivider;
|
||||
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||
// also rearrange coefficients suitably for 3DNow!
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||
filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
fDivider = (float)resultDivider;
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0; i < newLength; i ++)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] =
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 3DNow!-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, const uint numSamples) const
|
||||
{
|
||||
float *filterCoeffsLocal = filterCoeffsAlign;
|
||||
uint count = (numSamples - length) & -2;
|
||||
uint lengthLocal = length / 4;
|
||||
|
||||
assert(length != 0);
|
||||
assert(count % 2 == 0);
|
||||
|
||||
/* original code:
|
||||
|
||||
double suml1, suml2;
|
||||
double sumr1, sumr2;
|
||||
uint i, j;
|
||||
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *ptr;
|
||||
|
||||
suml1 = sumr1 = 0.0;
|
||||
suml2 = sumr2 = 0.0;
|
||||
ptr = src;
|
||||
filterCoeffsLocal = filterCoeffs;
|
||||
for (i = 0; i < lengthLocal; i ++)
|
||||
{
|
||||
// unroll loop for efficiency.
|
||||
|
||||
suml1 += ptr[0] * filterCoeffsLocal[0] +
|
||||
ptr[2] * filterCoeffsLocal[2] +
|
||||
ptr[4] * filterCoeffsLocal[4] +
|
||||
ptr[6] * filterCoeffsLocal[6];
|
||||
|
||||
sumr1 += ptr[1] * filterCoeffsLocal[1] +
|
||||
ptr[3] * filterCoeffsLocal[3] +
|
||||
ptr[5] * filterCoeffsLocal[5] +
|
||||
ptr[7] * filterCoeffsLocal[7];
|
||||
|
||||
suml2 += ptr[8] * filterCoeffsLocal[0] +
|
||||
ptr[10] * filterCoeffsLocal[2] +
|
||||
ptr[12] * filterCoeffsLocal[4] +
|
||||
ptr[14] * filterCoeffsLocal[6];
|
||||
|
||||
sumr2 += ptr[9] * filterCoeffsLocal[1] +
|
||||
ptr[11] * filterCoeffsLocal[3] +
|
||||
ptr[13] * filterCoeffsLocal[5] +
|
||||
ptr[15] * filterCoeffsLocal[7];
|
||||
|
||||
ptr += 16;
|
||||
filterCoeffsLocal += 8;
|
||||
}
|
||||
dest[0] = (float)suml1;
|
||||
dest[1] = (float)sumr1;
|
||||
dest[2] = (float)suml2;
|
||||
dest[3] = (float)sumr2;
|
||||
|
||||
src += 4;
|
||||
dest += 4;
|
||||
}
|
||||
|
||||
*/
|
||||
_asm
|
||||
{
|
||||
mov eax, dword ptr dest
|
||||
mov ebx, dword ptr src
|
||||
mov edx, count
|
||||
shr edx, 1
|
||||
|
||||
loop1:
|
||||
// "outer loop" : during each round 2*2 output samples are calculated
|
||||
prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
mov esi, ebx
|
||||
mov edi, filterCoeffsLocal
|
||||
pxor mm0, mm0
|
||||
pxor mm1, mm1
|
||||
mov ecx, lengthLocal
|
||||
|
||||
loop2:
|
||||
// "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples
|
||||
movq mm2, [edi]
|
||||
movq mm3, mm2
|
||||
prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm2, [esi]
|
||||
prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
pfmul mm3, [esi + 8]
|
||||
|
||||
movq mm4, [edi + 8]
|
||||
movq mm5, mm4
|
||||
pfadd mm0, mm2
|
||||
pfmul mm4, [esi + 8]
|
||||
pfadd mm1, mm3
|
||||
pfmul mm5, [esi + 16]
|
||||
|
||||
movq mm2, [edi + 16]
|
||||
movq mm6, mm2
|
||||
pfadd mm0, mm4
|
||||
pfmul mm2, [esi + 16]
|
||||
pfadd mm1, mm5
|
||||
pfmul mm6, [esi + 24]
|
||||
|
||||
movq mm3, [edi + 24]
|
||||
movq mm7, mm3
|
||||
pfadd mm0, mm2
|
||||
pfmul mm3, [esi + 24]
|
||||
pfadd mm1, mm6
|
||||
pfmul mm7, [esi + 32]
|
||||
add esi, 32
|
||||
pfadd mm0, mm3
|
||||
add edi, 32
|
||||
pfadd mm1, mm7
|
||||
|
||||
dec ecx
|
||||
jnz loop2
|
||||
|
||||
movq [eax], mm0
|
||||
add ebx, 16
|
||||
movq [eax + 8], mm1
|
||||
add eax, 16
|
||||
|
||||
dec edx
|
||||
jnz loop1
|
||||
|
||||
femms
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
#endif // ALLOW_3DNOW
|
||||
|
|
|
@ -1,184 +1,184 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
|
||||
/// MMX optimization.
|
||||
///
|
||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||
/// transposing the sample rate with interpolation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.9 $
|
||||
//
|
||||
// $Id: AAFilter.cpp,v 1.9 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "AAFilter.h"
|
||||
#include "FIRFilter.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#define PI 3.141592655357989
|
||||
#define TWOPI (2 * PI)
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Implementation of the class 'AAFilter'
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
AAFilter::AAFilter(const uint length)
|
||||
{
|
||||
pFIR = FIRFilter::newInstance();
|
||||
cutoffFreq = 0.5;
|
||||
setLength(length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AAFilter::~AAFilter()
|
||||
{
|
||||
delete pFIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new anti-alias filter cut-off edge frequency, scaled to
|
||||
// sampling frequency (nyquist frequency = 0.5).
|
||||
// The filter will cut frequencies higher than the given frequency.
|
||||
void AAFilter::setCutoffFreq(const double newCutoffFreq)
|
||||
{
|
||||
cutoffFreq = newCutoffFreq;
|
||||
calculateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets number of FIR filter taps
|
||||
void AAFilter::setLength(const uint newLength)
|
||||
{
|
||||
length = newLength;
|
||||
calculateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculates coefficients for a low-pass FIR filter using Hamming window
|
||||
void AAFilter::calculateCoeffs()
|
||||
{
|
||||
uint i;
|
||||
double cntTemp, temp, tempCoeff,h, w;
|
||||
double fc2, wc;
|
||||
double scaleCoeff, sum;
|
||||
double *work;
|
||||
SAMPLETYPE *coeffs;
|
||||
|
||||
assert(length > 0);
|
||||
assert(length % 4 == 0);
|
||||
assert(cutoffFreq >= 0);
|
||||
assert(cutoffFreq <= 0.5);
|
||||
|
||||
work = new double[length];
|
||||
coeffs = new SAMPLETYPE[length];
|
||||
|
||||
fc2 = 2.0 * cutoffFreq;
|
||||
wc = PI * fc2;
|
||||
tempCoeff = TWOPI / (double)length;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
cntTemp = (double)i - (double)(length / 2);
|
||||
|
||||
temp = cntTemp * wc;
|
||||
if (temp != 0)
|
||||
{
|
||||
h = fc2 * sin(temp) / temp; // sinc function
|
||||
}
|
||||
else
|
||||
{
|
||||
h = 1.0;
|
||||
}
|
||||
w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window
|
||||
|
||||
temp = w * h;
|
||||
work[i] = temp;
|
||||
|
||||
// calc net sum of coefficients
|
||||
sum += temp;
|
||||
}
|
||||
|
||||
// ensure the sum of coefficients is larger than zero
|
||||
assert(sum > 0);
|
||||
|
||||
// ensure we've really designed a lowpass filter...
|
||||
assert(work[length/2] > 0);
|
||||
assert(work[length/2 + 1] > -1e-6);
|
||||
assert(work[length/2 - 1] > -1e-6);
|
||||
|
||||
// Calculate a scaling coefficient in such a way that the result can be
|
||||
// divided by 16384
|
||||
scaleCoeff = 16384.0f / sum;
|
||||
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
// scale & round to nearest integer
|
||||
temp = work[i] * scaleCoeff;
|
||||
temp += (temp >= 0) ? 0.5 : -0.5;
|
||||
// ensure no overfloods
|
||||
assert(temp >= -32768 && temp <= 32767);
|
||||
coeffs[i] = (SAMPLETYPE)temp;
|
||||
}
|
||||
|
||||
// Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
|
||||
pFIR->setCoefficients(coeffs, length, 14);
|
||||
|
||||
delete[] work;
|
||||
delete[] coeffs;
|
||||
}
|
||||
|
||||
|
||||
// Applies the filter to the given sequence of samples.
|
||||
// Note : The amount of outputted samples is by value of 'filter length'
|
||||
// smaller than the amount of input samples.
|
||||
uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||
{
|
||||
return pFIR->evaluate(dest, src, numSamples, numChannels);
|
||||
}
|
||||
|
||||
|
||||
uint AAFilter::getLength() const
|
||||
{
|
||||
return pFIR->getLength();
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
|
||||
/// MMX optimization.
|
||||
///
|
||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||
/// transposing the sample rate with interpolation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.9 $
|
||||
//
|
||||
// $Id: AAFilter.cpp,v 1.9 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "AAFilter.h"
|
||||
#include "FIRFilter.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#define PI 3.141592655357989
|
||||
#define TWOPI (2 * PI)
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Implementation of the class 'AAFilter'
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
AAFilter::AAFilter(const uint length)
|
||||
{
|
||||
pFIR = FIRFilter::newInstance();
|
||||
cutoffFreq = 0.5;
|
||||
setLength(length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
AAFilter::~AAFilter()
|
||||
{
|
||||
delete pFIR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new anti-alias filter cut-off edge frequency, scaled to
|
||||
// sampling frequency (nyquist frequency = 0.5).
|
||||
// The filter will cut frequencies higher than the given frequency.
|
||||
void AAFilter::setCutoffFreq(const double newCutoffFreq)
|
||||
{
|
||||
cutoffFreq = newCutoffFreq;
|
||||
calculateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets number of FIR filter taps
|
||||
void AAFilter::setLength(const uint newLength)
|
||||
{
|
||||
length = newLength;
|
||||
calculateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Calculates coefficients for a low-pass FIR filter using Hamming window
|
||||
void AAFilter::calculateCoeffs()
|
||||
{
|
||||
uint i;
|
||||
double cntTemp, temp, tempCoeff,h, w;
|
||||
double fc2, wc;
|
||||
double scaleCoeff, sum;
|
||||
double *work;
|
||||
SAMPLETYPE *coeffs;
|
||||
|
||||
assert(length > 0);
|
||||
assert(length % 4 == 0);
|
||||
assert(cutoffFreq >= 0);
|
||||
assert(cutoffFreq <= 0.5);
|
||||
|
||||
work = new double[length];
|
||||
coeffs = new SAMPLETYPE[length];
|
||||
|
||||
fc2 = 2.0 * cutoffFreq;
|
||||
wc = PI * fc2;
|
||||
tempCoeff = TWOPI / (double)length;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
cntTemp = (double)i - (double)(length / 2);
|
||||
|
||||
temp = cntTemp * wc;
|
||||
if (temp != 0)
|
||||
{
|
||||
h = fc2 * sin(temp) / temp; // sinc function
|
||||
}
|
||||
else
|
||||
{
|
||||
h = 1.0;
|
||||
}
|
||||
w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window
|
||||
|
||||
temp = w * h;
|
||||
work[i] = temp;
|
||||
|
||||
// calc net sum of coefficients
|
||||
sum += temp;
|
||||
}
|
||||
|
||||
// ensure the sum of coefficients is larger than zero
|
||||
assert(sum > 0);
|
||||
|
||||
// ensure we've really designed a lowpass filter...
|
||||
assert(work[length/2] > 0);
|
||||
assert(work[length/2 + 1] > -1e-6);
|
||||
assert(work[length/2 - 1] > -1e-6);
|
||||
|
||||
// Calculate a scaling coefficient in such a way that the result can be
|
||||
// divided by 16384
|
||||
scaleCoeff = 16384.0f / sum;
|
||||
|
||||
for (i = 0; i < length; i ++)
|
||||
{
|
||||
// scale & round to nearest integer
|
||||
temp = work[i] * scaleCoeff;
|
||||
temp += (temp >= 0) ? 0.5 : -0.5;
|
||||
// ensure no overfloods
|
||||
assert(temp >= -32768 && temp <= 32767);
|
||||
coeffs[i] = (SAMPLETYPE)temp;
|
||||
}
|
||||
|
||||
// Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384
|
||||
pFIR->setCoefficients(coeffs, length, 14);
|
||||
|
||||
delete[] work;
|
||||
delete[] coeffs;
|
||||
}
|
||||
|
||||
|
||||
// Applies the filter to the given sequence of samples.
|
||||
// Note : The amount of outputted samples is by value of 'filter length'
|
||||
// smaller than the amount of input samples.
|
||||
uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||
{
|
||||
return pFIR->evaluate(dest, src, numSamples, numChannels);
|
||||
}
|
||||
|
||||
|
||||
uint AAFilter::getLength() const
|
||||
{
|
||||
return pFIR->getLength();
|
||||
}
|
||||
|
|
|
@ -1,91 +1,91 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||
/// with several performance-increasing tweaks.
|
||||
///
|
||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||
/// transposing the sample rate with interpolation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: AAFilter.h,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AAFilter_H
|
||||
#define AAFilter_H
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class AAFilter
|
||||
{
|
||||
protected:
|
||||
class FIRFilter *pFIR;
|
||||
|
||||
/// Low-pass filter cut-off frequency, negative = invalid
|
||||
double cutoffFreq;
|
||||
|
||||
/// num of filter taps
|
||||
uint length;
|
||||
|
||||
/// Calculate the FIR coefficients realizing the given cutoff-frequency
|
||||
void calculateCoeffs();
|
||||
public:
|
||||
AAFilter(uint length);
|
||||
|
||||
~AAFilter();
|
||||
|
||||
/// Sets new anti-alias filter cut-off edge frequency, scaled to sampling
|
||||
/// frequency (nyquist frequency = 0.5). The filter will cut off the
|
||||
/// frequencies than that.
|
||||
void setCutoffFreq(double newCutoffFreq);
|
||||
|
||||
/// Sets number of FIR filter taps, i.e. ~filter complexity
|
||||
void setLength(uint newLength);
|
||||
|
||||
uint getLength() const;
|
||||
|
||||
/// Applies the filter to the given sequence of samples.
|
||||
/// Note : The amount of outputted samples is by value of 'filter length'
|
||||
/// smaller than the amount of input samples.
|
||||
uint evaluate(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples,
|
||||
uint numChannels) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||
/// with several performance-increasing tweaks.
|
||||
///
|
||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||
/// transposing the sample rate with interpolation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: AAFilter.h,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AAFilter_H
|
||||
#define AAFilter_H
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class AAFilter
|
||||
{
|
||||
protected:
|
||||
class FIRFilter *pFIR;
|
||||
|
||||
/// Low-pass filter cut-off frequency, negative = invalid
|
||||
double cutoffFreq;
|
||||
|
||||
/// num of filter taps
|
||||
uint length;
|
||||
|
||||
/// Calculate the FIR coefficients realizing the given cutoff-frequency
|
||||
void calculateCoeffs();
|
||||
public:
|
||||
AAFilter(uint length);
|
||||
|
||||
~AAFilter();
|
||||
|
||||
/// Sets new anti-alias filter cut-off edge frequency, scaled to sampling
|
||||
/// frequency (nyquist frequency = 0.5). The filter will cut off the
|
||||
/// frequencies than that.
|
||||
void setCutoffFreq(double newCutoffFreq);
|
||||
|
||||
/// Sets number of FIR filter taps, i.e. ~filter complexity
|
||||
void setLength(uint newLength);
|
||||
|
||||
uint getLength() const;
|
||||
|
||||
/// Applies the filter to the given sequence of samples.
|
||||
/// Note : The amount of outputted samples is by value of 'filter length'
|
||||
/// smaller than the amount of input samples.
|
||||
uint evaluate(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples,
|
||||
uint numChannels) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,159 +1,159 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Beats-per-minute (BPM) detection routine.
|
||||
///
|
||||
/// The beat detection algorithm works as follows:
|
||||
/// - Use function 'inputSamples' to input a chunks of samples to the class for
|
||||
/// analysis. It's a good idea to enter a large sound file or stream in smallish
|
||||
/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
|
||||
/// - Input sound data is decimated to approx 500 Hz to reduce calculation burden,
|
||||
/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
|
||||
/// Simple averaging is used for anti-alias filtering because the resulting signal
|
||||
/// quality isn't of that high importance.
|
||||
/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
|
||||
/// taking absolute value that's smoothed by sliding average. Signal levels that
|
||||
/// are below a couple of times the general RMS amplitude level are cut away to
|
||||
/// leave only notable peaks there.
|
||||
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
|
||||
/// autocorrelation function of the enveloped signal.
|
||||
/// - After whole sound data file has been analyzed as above, the bpm level is
|
||||
/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
|
||||
/// function, calculates it's precise location and converts this reading to bpm's.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.5 $
|
||||
//
|
||||
// $Id: BPMDetect.h,v 1.5 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BPMDetect_H_
|
||||
#define _BPMDetect_H_
|
||||
|
||||
#include "STTypes.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
|
||||
#define MIN_BPM 45
|
||||
|
||||
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
|
||||
#define MAX_BPM 230
|
||||
|
||||
|
||||
/// Class for calculating BPM rate for audio data.
|
||||
class BPMDetect
|
||||
{
|
||||
protected:
|
||||
/// Auto-correlation accumulator bins.
|
||||
float *xcorr;
|
||||
|
||||
/// Amplitude envelope sliding average approximation level accumulator
|
||||
float envelopeAccu;
|
||||
|
||||
/// RMS volume sliding average approximation level accumulator
|
||||
float RMSVolumeAccu;
|
||||
|
||||
/// Sample average counter.
|
||||
int decimateCount;
|
||||
|
||||
/// Sample average accumulator for FIFO-like decimation.
|
||||
soundtouch::LONG_SAMPLETYPE decimateSum;
|
||||
|
||||
/// Decimate sound by this coefficient to reach approx. 500 Hz.
|
||||
int decimateBy;
|
||||
|
||||
/// Auto-correlation window length
|
||||
int windowLen;
|
||||
|
||||
/// Number of channels (1 = mono, 2 = stereo)
|
||||
int channels;
|
||||
|
||||
/// sample rate
|
||||
int sampleRate;
|
||||
|
||||
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
||||
/// the first these many correlation bins.
|
||||
int windowStart;
|
||||
|
||||
/// FIFO-buffer for decimated processing samples.
|
||||
soundtouch::FIFOSampleBuffer *buffer;
|
||||
|
||||
/// Initialize the class for processing.
|
||||
void init(int numChannels, int sampleRate);
|
||||
|
||||
/// Updates auto-correlation function for given number of decimated samples that
|
||||
/// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
|
||||
/// though).
|
||||
void updateXCorr(int process_samples /// How many samples are processed.
|
||||
);
|
||||
|
||||
/// Decimates samples to approx. 500 Hz.
|
||||
///
|
||||
/// \return Number of output samples.
|
||||
int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
|
||||
const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
|
||||
int numsamples ///< Number of source samples.
|
||||
);
|
||||
|
||||
/// Calculates amplitude envelope for the buffer of samples.
|
||||
/// Result is output to 'samples'.
|
||||
void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
|
||||
int numsamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
||||
int sampleRate ///< Sample rate in Hz.
|
||||
);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BPMDetect();
|
||||
|
||||
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
||||
/// updates the autocorrelation estimation. When whole song data has been input
|
||||
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
||||
/// function.
|
||||
///
|
||||
/// Notice that data in 'samples' array can be disrupted in processing.
|
||||
void inputSamples(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
||||
int numSamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
|
||||
/// Analyzes the results and returns the BPM rate. Use this function to read result
|
||||
/// after whole song data has been input to the class by consecutive calls of
|
||||
/// 'inputSamples' function.
|
||||
///
|
||||
/// \return Beats-per-minute rate, or zero if detection failed.
|
||||
float getBpm();
|
||||
};
|
||||
|
||||
#endif // _BPMDetect_H_
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Beats-per-minute (BPM) detection routine.
|
||||
///
|
||||
/// The beat detection algorithm works as follows:
|
||||
/// - Use function 'inputSamples' to input a chunks of samples to the class for
|
||||
/// analysis. It's a good idea to enter a large sound file or stream in smallish
|
||||
/// chunks of around few kilosamples in order not to extinguish too much RAM memory.
|
||||
/// - Input sound data is decimated to approx 500 Hz to reduce calculation burden,
|
||||
/// which is basically ok as low (bass) frequencies mostly determine the beat rate.
|
||||
/// Simple averaging is used for anti-alias filtering because the resulting signal
|
||||
/// quality isn't of that high importance.
|
||||
/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by
|
||||
/// taking absolute value that's smoothed by sliding average. Signal levels that
|
||||
/// are below a couple of times the general RMS amplitude level are cut away to
|
||||
/// leave only notable peaks there.
|
||||
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
|
||||
/// autocorrelation function of the enveloped signal.
|
||||
/// - After whole sound data file has been analyzed as above, the bpm level is
|
||||
/// detected by function 'getBpm' that finds the highest peak of the autocorrelation
|
||||
/// function, calculates it's precise location and converts this reading to bpm's.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.5 $
|
||||
//
|
||||
// $Id: BPMDetect.h,v 1.5 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _BPMDetect_H_
|
||||
#define _BPMDetect_H_
|
||||
|
||||
#include "STTypes.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
|
||||
#define MIN_BPM 45
|
||||
|
||||
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
|
||||
#define MAX_BPM 230
|
||||
|
||||
|
||||
/// Class for calculating BPM rate for audio data.
|
||||
class BPMDetect
|
||||
{
|
||||
protected:
|
||||
/// Auto-correlation accumulator bins.
|
||||
float *xcorr;
|
||||
|
||||
/// Amplitude envelope sliding average approximation level accumulator
|
||||
float envelopeAccu;
|
||||
|
||||
/// RMS volume sliding average approximation level accumulator
|
||||
float RMSVolumeAccu;
|
||||
|
||||
/// Sample average counter.
|
||||
int decimateCount;
|
||||
|
||||
/// Sample average accumulator for FIFO-like decimation.
|
||||
soundtouch::LONG_SAMPLETYPE decimateSum;
|
||||
|
||||
/// Decimate sound by this coefficient to reach approx. 500 Hz.
|
||||
int decimateBy;
|
||||
|
||||
/// Auto-correlation window length
|
||||
int windowLen;
|
||||
|
||||
/// Number of channels (1 = mono, 2 = stereo)
|
||||
int channels;
|
||||
|
||||
/// sample rate
|
||||
int sampleRate;
|
||||
|
||||
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
||||
/// the first these many correlation bins.
|
||||
int windowStart;
|
||||
|
||||
/// FIFO-buffer for decimated processing samples.
|
||||
soundtouch::FIFOSampleBuffer *buffer;
|
||||
|
||||
/// Initialize the class for processing.
|
||||
void init(int numChannels, int sampleRate);
|
||||
|
||||
/// Updates auto-correlation function for given number of decimated samples that
|
||||
/// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
|
||||
/// though).
|
||||
void updateXCorr(int process_samples /// How many samples are processed.
|
||||
);
|
||||
|
||||
/// Decimates samples to approx. 500 Hz.
|
||||
///
|
||||
/// \return Number of output samples.
|
||||
int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer
|
||||
const soundtouch::SAMPLETYPE *src, ///< Source sample buffer
|
||||
int numsamples ///< Number of source samples.
|
||||
);
|
||||
|
||||
/// Calculates amplitude envelope for the buffer of samples.
|
||||
/// Result is output to 'samples'.
|
||||
void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer
|
||||
int numsamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
||||
int sampleRate ///< Sample rate in Hz.
|
||||
);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~BPMDetect();
|
||||
|
||||
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
||||
/// updates the autocorrelation estimation. When whole song data has been input
|
||||
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
||||
/// function.
|
||||
///
|
||||
/// Notice that data in 'samples' array can be disrupted in processing.
|
||||
void inputSamples(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
||||
int numSamples ///< Number of samples in buffer
|
||||
);
|
||||
|
||||
|
||||
/// Analyzes the results and returns the BPM rate. Use this function to read result
|
||||
/// after whole song data has been input to the class by consecutive calls of
|
||||
/// 'inputSamples' function.
|
||||
///
|
||||
/// \return Beats-per-minute rate, or zero if detection failed.
|
||||
float getBpm();
|
||||
};
|
||||
|
||||
#endif // _BPMDetect_H_
|
||||
|
|
|
@ -1,252 +1,252 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||
/// first-in-first-out pipe.
|
||||
///
|
||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
||||
/// function, and are received from the beginning of the buffer by calling
|
||||
/// the 'receiveSamples' function. The class automatically removes the
|
||||
/// outputted samples from the buffer, as well as grows the buffer size
|
||||
/// whenever necessary.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.11 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
// Constructor
|
||||
FIFOSampleBuffer::FIFOSampleBuffer(uint numChannels)
|
||||
{
|
||||
sizeInBytes = 0; // reasonable initial value
|
||||
buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)];
|
||||
bufferUnaligned = NULL;
|
||||
samplesInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
channels = numChannels;
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
FIFOSampleBuffer::~FIFOSampleBuffer()
|
||||
{
|
||||
delete[] bufferUnaligned;
|
||||
}
|
||||
|
||||
|
||||
// Sets number of channels, 1 = mono, 2 = stereo
|
||||
void FIFOSampleBuffer::setChannels(const uint numChannels)
|
||||
{
|
||||
uint usedBytes;
|
||||
|
||||
usedBytes = channels * samplesInBuffer;
|
||||
channels = numChannels;
|
||||
samplesInBuffer = usedBytes / channels;
|
||||
}
|
||||
|
||||
|
||||
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
|
||||
// zeroes this pointer by copying samples from the 'bufferPos' pointer
|
||||
// location on to the beginning of the buffer.
|
||||
void FIFOSampleBuffer::rewind()
|
||||
{
|
||||
if (bufferPos)
|
||||
{
|
||||
memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
|
||||
bufferPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
// the sample buffer.
|
||||
void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint numSamples)
|
||||
{
|
||||
memcpy(ptrEnd(numSamples), samples, sizeof(SAMPLETYPE) * numSamples * channels);
|
||||
samplesInBuffer += numSamples;
|
||||
}
|
||||
|
||||
|
||||
// Increases the number of samples in the buffer without copying any actual
|
||||
// samples.
|
||||
//
|
||||
// This function is used to update the number of samples in the sample buffer
|
||||
// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||
// careful though!
|
||||
void FIFOSampleBuffer::putSamples(uint numSamples)
|
||||
{
|
||||
uint req;
|
||||
|
||||
req = samplesInBuffer + numSamples;
|
||||
ensureCapacity(req);
|
||||
samplesInBuffer += numSamples;
|
||||
}
|
||||
|
||||
|
||||
// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
||||
// where the new samples are to be inserted). This function may be used for
|
||||
// inserting new samples into the sample buffer directly. Please be careful!
|
||||
//
|
||||
// Parameter 'slackCapacity' tells the function how much free capacity (in
|
||||
// terms of samples) there _at least_ should be, in order to the caller to
|
||||
// succesfully insert all the required samples to the buffer. When necessary,
|
||||
// the function grows the buffer size to comply with this requirement.
|
||||
//
|
||||
// When using this function as means for inserting new samples, also remember
|
||||
// to increase the sample count afterwards, by calling the
|
||||
// 'putSamples(numSamples)' function.
|
||||
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
|
||||
{
|
||||
ensureCapacity(samplesInBuffer + slackCapacity);
|
||||
return buffer + samplesInBuffer * channels;
|
||||
}
|
||||
|
||||
|
||||
// Returns a pointer to the beginning of the currently non-outputted samples.
|
||||
// This function is provided for accessing the output samples directly.
|
||||
// Please be careful!
|
||||
//
|
||||
// When using this function to output samples, also remember to 'remove' the
|
||||
// outputted samples from the buffer by calling the
|
||||
// 'receiveSamples(numSamples)' function
|
||||
SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const
|
||||
{
|
||||
return buffer + bufferPos * channels;
|
||||
}
|
||||
|
||||
|
||||
// Ensures that the buffer has enought capacity, i.e. space for _at least_
|
||||
// 'capacityRequirement' number of samples. The buffer is grown in steps of
|
||||
// 4 kilobytes to eliminate the need for frequently growing up the buffer,
|
||||
// as well as to round the buffer size up to the virtual memory page size.
|
||||
void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||
{
|
||||
SAMPLETYPE *tempUnaligned, *temp;
|
||||
|
||||
if (capacityRequirement > getCapacity())
|
||||
{
|
||||
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
|
||||
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096;
|
||||
assert(sizeInBytes % 2 == 0);
|
||||
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
||||
if (tempUnaligned == NULL)
|
||||
{
|
||||
throw std::runtime_error("Couldn't allocate memory!\n");
|
||||
}
|
||||
temp = (SAMPLETYPE *)(((ulongptr)tempUnaligned + 15) & -16);
|
||||
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
|
||||
delete[] bufferUnaligned;
|
||||
buffer = temp;
|
||||
bufferUnaligned = tempUnaligned;
|
||||
bufferPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// simply rewind the buffer (if necessary)
|
||||
rewind();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns the current buffer capacity in terms of samples
|
||||
uint FIFOSampleBuffer::getCapacity() const
|
||||
{
|
||||
return sizeInBytes / (channels * sizeof(SAMPLETYPE));
|
||||
}
|
||||
|
||||
|
||||
// Returns the number of samples currently in the buffer
|
||||
uint FIFOSampleBuffer::numSamples() const
|
||||
{
|
||||
return samplesInBuffer;
|
||||
}
|
||||
|
||||
|
||||
// Output samples from beginning of the sample buffer. Copies demanded number
|
||||
// of samples to output and removes them from the sample buffer. If there
|
||||
// are less than 'numsample' samples in the buffer, returns all available.
|
||||
//
|
||||
// Returns number of samples copied.
|
||||
uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
|
||||
{
|
||||
uint num;
|
||||
|
||||
num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
|
||||
|
||||
memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
|
||||
return receiveSamples(num);
|
||||
}
|
||||
|
||||
|
||||
// Removes samples from the beginning of the sample buffer without copying them
|
||||
// anywhere. Used to reduce the number of samples in the buffer, when accessing
|
||||
// the sample buffer with the 'ptrBegin' function.
|
||||
uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
|
||||
{
|
||||
if (maxSamples >= samplesInBuffer)
|
||||
{
|
||||
uint temp;
|
||||
|
||||
temp = samplesInBuffer;
|
||||
samplesInBuffer = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
samplesInBuffer -= maxSamples;
|
||||
bufferPos += maxSamples;
|
||||
|
||||
return maxSamples;
|
||||
}
|
||||
|
||||
|
||||
// Returns nonzero if the sample buffer is empty
|
||||
int FIFOSampleBuffer::isEmpty() const
|
||||
{
|
||||
return (samplesInBuffer == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
// Clears the sample buffer
|
||||
void FIFOSampleBuffer::clear()
|
||||
{
|
||||
samplesInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||
/// first-in-first-out pipe.
|
||||
///
|
||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
||||
/// function, and are received from the beginning of the buffer by calling
|
||||
/// the 'receiveSamples' function. The class automatically removes the
|
||||
/// outputted samples from the buffer, as well as grows the buffer size
|
||||
/// whenever necessary.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.11 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
// Constructor
|
||||
FIFOSampleBuffer::FIFOSampleBuffer(uint numChannels)
|
||||
{
|
||||
sizeInBytes = 0; // reasonable initial value
|
||||
buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)];
|
||||
bufferUnaligned = NULL;
|
||||
samplesInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
channels = numChannels;
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
FIFOSampleBuffer::~FIFOSampleBuffer()
|
||||
{
|
||||
delete[] bufferUnaligned;
|
||||
}
|
||||
|
||||
|
||||
// Sets number of channels, 1 = mono, 2 = stereo
|
||||
void FIFOSampleBuffer::setChannels(const uint numChannels)
|
||||
{
|
||||
uint usedBytes;
|
||||
|
||||
usedBytes = channels * samplesInBuffer;
|
||||
channels = numChannels;
|
||||
samplesInBuffer = usedBytes / channels;
|
||||
}
|
||||
|
||||
|
||||
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
|
||||
// zeroes this pointer by copying samples from the 'bufferPos' pointer
|
||||
// location on to the beginning of the buffer.
|
||||
void FIFOSampleBuffer::rewind()
|
||||
{
|
||||
if (bufferPos)
|
||||
{
|
||||
memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
|
||||
bufferPos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
// the sample buffer.
|
||||
void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint numSamples)
|
||||
{
|
||||
memcpy(ptrEnd(numSamples), samples, sizeof(SAMPLETYPE) * numSamples * channels);
|
||||
samplesInBuffer += numSamples;
|
||||
}
|
||||
|
||||
|
||||
// Increases the number of samples in the buffer without copying any actual
|
||||
// samples.
|
||||
//
|
||||
// This function is used to update the number of samples in the sample buffer
|
||||
// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||
// careful though!
|
||||
void FIFOSampleBuffer::putSamples(uint numSamples)
|
||||
{
|
||||
uint req;
|
||||
|
||||
req = samplesInBuffer + numSamples;
|
||||
ensureCapacity(req);
|
||||
samplesInBuffer += numSamples;
|
||||
}
|
||||
|
||||
|
||||
// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
||||
// where the new samples are to be inserted). This function may be used for
|
||||
// inserting new samples into the sample buffer directly. Please be careful!
|
||||
//
|
||||
// Parameter 'slackCapacity' tells the function how much free capacity (in
|
||||
// terms of samples) there _at least_ should be, in order to the caller to
|
||||
// succesfully insert all the required samples to the buffer. When necessary,
|
||||
// the function grows the buffer size to comply with this requirement.
|
||||
//
|
||||
// When using this function as means for inserting new samples, also remember
|
||||
// to increase the sample count afterwards, by calling the
|
||||
// 'putSamples(numSamples)' function.
|
||||
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
|
||||
{
|
||||
ensureCapacity(samplesInBuffer + slackCapacity);
|
||||
return buffer + samplesInBuffer * channels;
|
||||
}
|
||||
|
||||
|
||||
// Returns a pointer to the beginning of the currently non-outputted samples.
|
||||
// This function is provided for accessing the output samples directly.
|
||||
// Please be careful!
|
||||
//
|
||||
// When using this function to output samples, also remember to 'remove' the
|
||||
// outputted samples from the buffer by calling the
|
||||
// 'receiveSamples(numSamples)' function
|
||||
SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const
|
||||
{
|
||||
return buffer + bufferPos * channels;
|
||||
}
|
||||
|
||||
|
||||
// Ensures that the buffer has enought capacity, i.e. space for _at least_
|
||||
// 'capacityRequirement' number of samples. The buffer is grown in steps of
|
||||
// 4 kilobytes to eliminate the need for frequently growing up the buffer,
|
||||
// as well as to round the buffer size up to the virtual memory page size.
|
||||
void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||
{
|
||||
SAMPLETYPE *tempUnaligned, *temp;
|
||||
|
||||
if (capacityRequirement > getCapacity())
|
||||
{
|
||||
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
|
||||
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096;
|
||||
assert(sizeInBytes % 2 == 0);
|
||||
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
||||
if (tempUnaligned == NULL)
|
||||
{
|
||||
throw std::runtime_error("Couldn't allocate memory!\n");
|
||||
}
|
||||
temp = (SAMPLETYPE *)(((ulongptr)tempUnaligned + 15) & -16);
|
||||
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
|
||||
delete[] bufferUnaligned;
|
||||
buffer = temp;
|
||||
bufferUnaligned = tempUnaligned;
|
||||
bufferPos = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// simply rewind the buffer (if necessary)
|
||||
rewind();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns the current buffer capacity in terms of samples
|
||||
uint FIFOSampleBuffer::getCapacity() const
|
||||
{
|
||||
return sizeInBytes / (channels * sizeof(SAMPLETYPE));
|
||||
}
|
||||
|
||||
|
||||
// Returns the number of samples currently in the buffer
|
||||
uint FIFOSampleBuffer::numSamples() const
|
||||
{
|
||||
return samplesInBuffer;
|
||||
}
|
||||
|
||||
|
||||
// Output samples from beginning of the sample buffer. Copies demanded number
|
||||
// of samples to output and removes them from the sample buffer. If there
|
||||
// are less than 'numsample' samples in the buffer, returns all available.
|
||||
//
|
||||
// Returns number of samples copied.
|
||||
uint FIFOSampleBuffer::receiveSamples(SAMPLETYPE *output, uint maxSamples)
|
||||
{
|
||||
uint num;
|
||||
|
||||
num = (maxSamples > samplesInBuffer) ? samplesInBuffer : maxSamples;
|
||||
|
||||
memcpy(output, ptrBegin(), channels * sizeof(SAMPLETYPE) * num);
|
||||
return receiveSamples(num);
|
||||
}
|
||||
|
||||
|
||||
// Removes samples from the beginning of the sample buffer without copying them
|
||||
// anywhere. Used to reduce the number of samples in the buffer, when accessing
|
||||
// the sample buffer with the 'ptrBegin' function.
|
||||
uint FIFOSampleBuffer::receiveSamples(uint maxSamples)
|
||||
{
|
||||
if (maxSamples >= samplesInBuffer)
|
||||
{
|
||||
uint temp;
|
||||
|
||||
temp = samplesInBuffer;
|
||||
samplesInBuffer = 0;
|
||||
return temp;
|
||||
}
|
||||
|
||||
samplesInBuffer -= maxSamples;
|
||||
bufferPos += maxSamples;
|
||||
|
||||
return maxSamples;
|
||||
}
|
||||
|
||||
|
||||
// Returns nonzero if the sample buffer is empty
|
||||
int FIFOSampleBuffer::isEmpty() const
|
||||
{
|
||||
return (samplesInBuffer == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
// Clears the sample buffer
|
||||
void FIFOSampleBuffer::clear()
|
||||
{
|
||||
samplesInBuffer = 0;
|
||||
bufferPos = 0;
|
||||
}
|
||||
|
|
|
@ -1,174 +1,174 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||
/// first-in-first-out pipe.
|
||||
///
|
||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
||||
/// function, and are received from the beginning of the buffer by calling
|
||||
/// the 'receiveSamples' function. The class automatically removes the
|
||||
/// output samples from the buffer as well as grows the storage size
|
||||
/// whenever necessary.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.9 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.h,v 1.9 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIFOSampleBuffer_H
|
||||
#define FIFOSampleBuffer_H
|
||||
|
||||
#include "FIFOSamplePipe.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Sample buffer working in FIFO (first-in-first-out) principle. The class takes
|
||||
/// care of storage size adjustment and data moving during input/output operations.
|
||||
///
|
||||
/// Notice that in case of stereo audio, one sample is considered to consist of
|
||||
/// both channel data.
|
||||
class FIFOSampleBuffer : public FIFOSamplePipe
|
||||
{
|
||||
private:
|
||||
/// Sample buffer.
|
||||
SAMPLETYPE *buffer;
|
||||
|
||||
// Raw unaligned buffer memory. 'buffer' is made aligned by pointing it to first
|
||||
// 16-byte aligned location of this buffer
|
||||
SAMPLETYPE *bufferUnaligned;
|
||||
|
||||
/// Sample buffer size in bytes
|
||||
uint sizeInBytes;
|
||||
|
||||
/// How many samples are currently in buffer.
|
||||
uint samplesInBuffer;
|
||||
|
||||
/// Channels, 1=mono, 2=stereo.
|
||||
uint channels;
|
||||
|
||||
/// Current position pointer to the buffer. This pointer is increased when samples are
|
||||
/// removed from the pipe so that it's necessary to actually rewind buffer (move data)
|
||||
/// only new data when is put to the pipe.
|
||||
uint bufferPos;
|
||||
|
||||
/// Rewind the buffer by moving data from position pointed by 'bufferPos' to real
|
||||
/// beginning of the buffer.
|
||||
void rewind();
|
||||
|
||||
/// Ensures that the buffer has capacity for at least this many samples.
|
||||
void ensureCapacity(const uint capacityRequirement);
|
||||
|
||||
/// Returns current capacity.
|
||||
uint getCapacity() const;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FIFOSampleBuffer(uint numChannels = 2 ///< Number of channels, 1=mono, 2=stereo.
|
||||
///< Default is stereo.
|
||||
);
|
||||
|
||||
/// destructor
|
||||
~FIFOSampleBuffer();
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const;
|
||||
|
||||
/// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
||||
/// where the new samples are to be inserted). This function may be used for
|
||||
/// inserting new samples into the sample buffer directly. Please be careful
|
||||
/// not corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function as means for inserting new samples, also remember
|
||||
/// to increase the sample count afterwards, by calling the
|
||||
/// 'putSamples(numSamples)' function.
|
||||
SAMPLETYPE *ptrEnd(
|
||||
uint slackCapacity ///< How much free capacity (in samples) there _at least_
|
||||
///< should be so that the caller can succesfully insert the
|
||||
///< desired samples to the buffer. If necessary, the function
|
||||
///< grows the buffer size to comply with this requirement.
|
||||
);
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
/// the sample buffer.
|
||||
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
|
||||
uint numSamples ///< Number of samples to insert.
|
||||
);
|
||||
|
||||
/// Adjusts the book-keeping to increase number of samples in the buffer without
|
||||
/// copying any actual samples.
|
||||
///
|
||||
/// This function is used to update the number of samples in the sample buffer
|
||||
/// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||
/// careful though!
|
||||
virtual void putSamples(uint numSamples ///< Number of samples been inserted.
|
||||
);
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
);
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
);
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const;
|
||||
|
||||
/// Sets number of channels, 1 = mono, 2 = stereo.
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const;
|
||||
|
||||
/// Clears all the samples.
|
||||
virtual void clear();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||
/// first-in-first-out pipe.
|
||||
///
|
||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
||||
/// function, and are received from the beginning of the buffer by calling
|
||||
/// the 'receiveSamples' function. The class automatically removes the
|
||||
/// output samples from the buffer as well as grows the storage size
|
||||
/// whenever necessary.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.9 $
|
||||
//
|
||||
// $Id: FIFOSampleBuffer.h,v 1.9 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIFOSampleBuffer_H
|
||||
#define FIFOSampleBuffer_H
|
||||
|
||||
#include "FIFOSamplePipe.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Sample buffer working in FIFO (first-in-first-out) principle. The class takes
|
||||
/// care of storage size adjustment and data moving during input/output operations.
|
||||
///
|
||||
/// Notice that in case of stereo audio, one sample is considered to consist of
|
||||
/// both channel data.
|
||||
class FIFOSampleBuffer : public FIFOSamplePipe
|
||||
{
|
||||
private:
|
||||
/// Sample buffer.
|
||||
SAMPLETYPE *buffer;
|
||||
|
||||
// Raw unaligned buffer memory. 'buffer' is made aligned by pointing it to first
|
||||
// 16-byte aligned location of this buffer
|
||||
SAMPLETYPE *bufferUnaligned;
|
||||
|
||||
/// Sample buffer size in bytes
|
||||
uint sizeInBytes;
|
||||
|
||||
/// How many samples are currently in buffer.
|
||||
uint samplesInBuffer;
|
||||
|
||||
/// Channels, 1=mono, 2=stereo.
|
||||
uint channels;
|
||||
|
||||
/// Current position pointer to the buffer. This pointer is increased when samples are
|
||||
/// removed from the pipe so that it's necessary to actually rewind buffer (move data)
|
||||
/// only new data when is put to the pipe.
|
||||
uint bufferPos;
|
||||
|
||||
/// Rewind the buffer by moving data from position pointed by 'bufferPos' to real
|
||||
/// beginning of the buffer.
|
||||
void rewind();
|
||||
|
||||
/// Ensures that the buffer has capacity for at least this many samples.
|
||||
void ensureCapacity(const uint capacityRequirement);
|
||||
|
||||
/// Returns current capacity.
|
||||
uint getCapacity() const;
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor
|
||||
FIFOSampleBuffer(uint numChannels = 2 ///< Number of channels, 1=mono, 2=stereo.
|
||||
///< Default is stereo.
|
||||
);
|
||||
|
||||
/// destructor
|
||||
~FIFOSampleBuffer();
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const;
|
||||
|
||||
/// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
||||
/// where the new samples are to be inserted). This function may be used for
|
||||
/// inserting new samples into the sample buffer directly. Please be careful
|
||||
/// not corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function as means for inserting new samples, also remember
|
||||
/// to increase the sample count afterwards, by calling the
|
||||
/// 'putSamples(numSamples)' function.
|
||||
SAMPLETYPE *ptrEnd(
|
||||
uint slackCapacity ///< How much free capacity (in samples) there _at least_
|
||||
///< should be so that the caller can succesfully insert the
|
||||
///< desired samples to the buffer. If necessary, the function
|
||||
///< grows the buffer size to comply with this requirement.
|
||||
);
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
/// the sample buffer.
|
||||
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
|
||||
uint numSamples ///< Number of samples to insert.
|
||||
);
|
||||
|
||||
/// Adjusts the book-keeping to increase number of samples in the buffer without
|
||||
/// copying any actual samples.
|
||||
///
|
||||
/// This function is used to update the number of samples in the sample buffer
|
||||
/// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||
/// careful though!
|
||||
virtual void putSamples(uint numSamples ///< Number of samples been inserted.
|
||||
);
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
);
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
);
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const;
|
||||
|
||||
/// Sets number of channels, 1 = mono, 2 = stereo.
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const;
|
||||
|
||||
/// Clears all the samples.
|
||||
virtual void clear();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,217 +1,217 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// 'FIFOSamplePipe' : An abstract base class for classes that manipulate sound
|
||||
/// samples by operating like a first-in-first-out pipe: New samples are fed
|
||||
/// into one end of the pipe with the 'putSamples' function, and the processed
|
||||
/// samples are received from the other end with the 'receiveSamples' function.
|
||||
///
|
||||
/// 'FIFOProcessor' : A base class for classes the do signal processing with
|
||||
/// the samples while operating like a first-in-first-out pipe. When samples
|
||||
/// are input with the 'putSamples' function, the class processes them
|
||||
/// and moves the processed samples to the given 'output' pipe object, which
|
||||
/// may be either another processing stage, or a fifo sample buffer object.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.8 $
|
||||
//
|
||||
// $Id: FIFOSamplePipe.h,v 1.8 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIFOSamplePipe_H
|
||||
#define FIFOSamplePipe_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Abstract base class for FIFO (first-in-first-out) sample processing classes.
|
||||
class FIFOSamplePipe
|
||||
{
|
||||
public:
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const = 0;
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
/// the sample buffer.
|
||||
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
|
||||
uint numSamples ///< Number of samples to insert.
|
||||
) = 0;
|
||||
|
||||
|
||||
// Moves samples from the 'other' pipe instance to this instance.
|
||||
void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data.
|
||||
)
|
||||
{
|
||||
int oNumSamples = other.numSamples();
|
||||
|
||||
putSamples(other.ptrBegin(), oNumSamples);
|
||||
other.receiveSamples(oNumSamples);
|
||||
};
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
) = 0;
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
) = 0;
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const = 0;
|
||||
|
||||
// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const = 0;
|
||||
|
||||
/// Clears all the samples.
|
||||
virtual void clear() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Base-class for sound processing routines working in FIFO principle. With this base
|
||||
/// class it's easy to implement sound processing stages that can be chained together,
|
||||
/// so that samples that are fed into beginning of the pipe automatically go through
|
||||
/// all the processing stages.
|
||||
///
|
||||
/// When samples are input to this class, they're first processed and then put to
|
||||
/// the FIFO pipe that's defined as output of this class. This output pipe can be
|
||||
/// either other processing stage or a FIFO sample buffer.
|
||||
class FIFOProcessor :public FIFOSamplePipe
|
||||
{
|
||||
protected:
|
||||
/// Internal pipe where processed samples are put.
|
||||
FIFOSamplePipe *output;
|
||||
|
||||
/// Sets output pipe.
|
||||
void setOutPipe(FIFOSamplePipe *pOutput)
|
||||
{
|
||||
assert(output == NULL);
|
||||
assert(pOutput != NULL);
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Doesn't define output pipe; it has to be set be
|
||||
/// 'setOutPipe' function.
|
||||
FIFOProcessor()
|
||||
{
|
||||
output = NULL;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Configures output pipe.
|
||||
FIFOProcessor(FIFOSamplePipe *pOutput ///< Output pipe.
|
||||
)
|
||||
{
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Destructor.
|
||||
virtual ~FIFOProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const
|
||||
{
|
||||
return output->ptrBegin();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
)
|
||||
{
|
||||
return output->receiveSamples(outBuffer, maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
)
|
||||
{
|
||||
return output->receiveSamples(maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const
|
||||
{
|
||||
return output->numSamples();
|
||||
}
|
||||
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const
|
||||
{
|
||||
return output->isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// 'FIFOSamplePipe' : An abstract base class for classes that manipulate sound
|
||||
/// samples by operating like a first-in-first-out pipe: New samples are fed
|
||||
/// into one end of the pipe with the 'putSamples' function, and the processed
|
||||
/// samples are received from the other end with the 'receiveSamples' function.
|
||||
///
|
||||
/// 'FIFOProcessor' : A base class for classes the do signal processing with
|
||||
/// the samples while operating like a first-in-first-out pipe. When samples
|
||||
/// are input with the 'putSamples' function, the class processes them
|
||||
/// and moves the processed samples to the given 'output' pipe object, which
|
||||
/// may be either another processing stage, or a fifo sample buffer object.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.8 $
|
||||
//
|
||||
// $Id: FIFOSamplePipe.h,v 1.8 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIFOSamplePipe_H
|
||||
#define FIFOSamplePipe_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Abstract base class for FIFO (first-in-first-out) sample processing classes.
|
||||
class FIFOSamplePipe
|
||||
{
|
||||
public:
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const = 0;
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||
/// the sample buffer.
|
||||
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
|
||||
uint numSamples ///< Number of samples to insert.
|
||||
) = 0;
|
||||
|
||||
|
||||
// Moves samples from the 'other' pipe instance to this instance.
|
||||
void moveSamples(FIFOSamplePipe &other ///< Other pipe instance where from the receive the data.
|
||||
)
|
||||
{
|
||||
int oNumSamples = other.numSamples();
|
||||
|
||||
putSamples(other.ptrBegin(), oNumSamples);
|
||||
other.receiveSamples(oNumSamples);
|
||||
};
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *output, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
) = 0;
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
) = 0;
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const = 0;
|
||||
|
||||
// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const = 0;
|
||||
|
||||
/// Clears all the samples.
|
||||
virtual void clear() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Base-class for sound processing routines working in FIFO principle. With this base
|
||||
/// class it's easy to implement sound processing stages that can be chained together,
|
||||
/// so that samples that are fed into beginning of the pipe automatically go through
|
||||
/// all the processing stages.
|
||||
///
|
||||
/// When samples are input to this class, they're first processed and then put to
|
||||
/// the FIFO pipe that's defined as output of this class. This output pipe can be
|
||||
/// either other processing stage or a FIFO sample buffer.
|
||||
class FIFOProcessor :public FIFOSamplePipe
|
||||
{
|
||||
protected:
|
||||
/// Internal pipe where processed samples are put.
|
||||
FIFOSamplePipe *output;
|
||||
|
||||
/// Sets output pipe.
|
||||
void setOutPipe(FIFOSamplePipe *pOutput)
|
||||
{
|
||||
assert(output == NULL);
|
||||
assert(pOutput != NULL);
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Doesn't define output pipe; it has to be set be
|
||||
/// 'setOutPipe' function.
|
||||
FIFOProcessor()
|
||||
{
|
||||
output = NULL;
|
||||
}
|
||||
|
||||
|
||||
/// Constructor. Configures output pipe.
|
||||
FIFOProcessor(FIFOSamplePipe *pOutput ///< Output pipe.
|
||||
)
|
||||
{
|
||||
output = pOutput;
|
||||
}
|
||||
|
||||
|
||||
/// Destructor.
|
||||
virtual ~FIFOProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Returns a pointer to the beginning of the output samples.
|
||||
/// This function is provided for accessing the output samples directly.
|
||||
/// Please be careful for not to corrupt the book-keeping!
|
||||
///
|
||||
/// When using this function to output samples, also remember to 'remove' the
|
||||
/// output samples from the buffer by calling the
|
||||
/// 'receiveSamples(numSamples)' function
|
||||
virtual SAMPLETYPE *ptrBegin() const
|
||||
{
|
||||
return output->ptrBegin();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
||||
/// output buffer and removes them from the sample buffer. If there are less than
|
||||
/// 'numsample' samples in the buffer, returns all that available.
|
||||
///
|
||||
/// \return Number of samples returned.
|
||||
virtual uint receiveSamples(SAMPLETYPE *outBuffer, ///< Buffer where to copy output samples.
|
||||
uint maxSamples ///< How many samples to receive at max.
|
||||
)
|
||||
{
|
||||
return output->receiveSamples(outBuffer, maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||
/// sample buffer without copying them anywhere.
|
||||
///
|
||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||
/// with 'ptrBegin' function.
|
||||
virtual uint receiveSamples(uint maxSamples ///< Remove this many samples from the beginning of pipe.
|
||||
)
|
||||
{
|
||||
return output->receiveSamples(maxSamples);
|
||||
}
|
||||
|
||||
|
||||
/// Returns number of samples currently available.
|
||||
virtual uint numSamples() const
|
||||
{
|
||||
return output->numSamples();
|
||||
}
|
||||
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual int isEmpty() const
|
||||
{
|
||||
return output->isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,272 +1,272 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// General FIR digital filter routines with MMX optimization.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: FIRFilter.cpp,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdexcept>
|
||||
#include "FIRFilter.h"
|
||||
#include "cpu_detect.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Implementation of the class 'FIRFilter'
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FIRFilter::FIRFilter()
|
||||
{
|
||||
resultDivFactor = 0;
|
||||
length = 0;
|
||||
lengthDiv8 = 0;
|
||||
filterCoeffs = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter::~FIRFilter()
|
||||
{
|
||||
delete[] filterCoeffs;
|
||||
}
|
||||
|
||||
// Usual C-version of the filter routine for stereo sound
|
||||
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
uint i, j, end;
|
||||
LONG_SAMPLETYPE suml, sumr;
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
assert(length != 0);
|
||||
|
||||
end = 2 * (numSamples - length);
|
||||
|
||||
for (j = 0; j < end; j += 2)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
|
||||
suml = sumr = 0;
|
||||
ptr = src + j;
|
||||
|
||||
for (i = 0; i < length; i += 4)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 2] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 4] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 6] * filterCoeffs[i + 3];
|
||||
sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 3] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 5] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 7] * filterCoeffs[i + 3];
|
||||
}
|
||||
|
||||
#ifdef INTEGER_SAMPLES
|
||||
suml >>= resultDivFactor;
|
||||
sumr >>= resultDivFactor;
|
||||
// saturate to 16 bit integer limits
|
||||
suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
|
||||
// saturate to 16 bit integer limits
|
||||
sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
|
||||
#else
|
||||
suml *= dScaler;
|
||||
sumr *= dScaler;
|
||||
#endif // INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)suml;
|
||||
dest[j + 1] = (SAMPLETYPE)sumr;
|
||||
}
|
||||
return numSamples - length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Usual C-version of the filter routine for mono sound
|
||||
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
uint i, j, end;
|
||||
LONG_SAMPLETYPE sum;
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
|
||||
assert(length != 0);
|
||||
|
||||
end = numSamples - length;
|
||||
for (j = 0; j < end; j ++)
|
||||
{
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i += 4)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
sum += src[i + 0] * filterCoeffs[i + 0] +
|
||||
src[i + 1] * filterCoeffs[i + 1] +
|
||||
src[i + 2] * filterCoeffs[i + 2] +
|
||||
src[i + 3] * filterCoeffs[i + 3];
|
||||
}
|
||||
#ifdef INTEGER_SAMPLES
|
||||
sum >>= resultDivFactor;
|
||||
// saturate to 16 bit integer limits
|
||||
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
|
||||
#else
|
||||
sum *= dScaler;
|
||||
#endif // INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)sum;
|
||||
src ++;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
// Set filter coeffiecients and length.
|
||||
//
|
||||
// Throws an exception if filter length isn't divisible by 8
|
||||
void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
assert(newLength > 0);
|
||||
if (newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8");
|
||||
|
||||
lengthDiv8 = newLength / 8;
|
||||
length = lengthDiv8 * 8;
|
||||
assert(length == newLength);
|
||||
|
||||
resultDivFactor = uResultDivFactor;
|
||||
#ifdef INTEGER_SAMPLES
|
||||
resultDivider = (SAMPLETYPE)(1<<resultDivFactor);
|
||||
#else
|
||||
resultDivider = (SAMPLETYPE)powf(2, (SAMPLETYPE)resultDivFactor);
|
||||
#endif
|
||||
|
||||
delete[] filterCoeffs;
|
||||
filterCoeffs = new SAMPLETYPE[length];
|
||||
memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
|
||||
}
|
||||
|
||||
|
||||
uint FIRFilter::getLength() const
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Applies the filter to the given sequence of samples.
|
||||
//
|
||||
// Note : The amount of outputted samples is by value of 'filter_length'
|
||||
// smaller than the amount of input samples.
|
||||
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||
{
|
||||
assert(numChannels == 1 || numChannels == 2);
|
||||
|
||||
assert(length > 0);
|
||||
assert(lengthDiv8 * 8 == length);
|
||||
if (numSamples < length) return 0;
|
||||
assert(resultDivFactor >= 0);
|
||||
if (numChannels == 2)
|
||||
{
|
||||
return evaluateFilterStereo(dest, src, numSamples);
|
||||
} else {
|
||||
return evaluateFilterMono(dest, src, numSamples);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
// depending on if we've a MMX-capable CPU available or not.
|
||||
void * FIRFilter::operator new(size_t s)
|
||||
{
|
||||
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
||||
throw std::runtime_error("Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter * FIRFilter::newInstance()
|
||||
{
|
||||
uint uExtensions = 0;
|
||||
|
||||
#if !defined(_MSC_VER) || !defined(__x86_64__)
|
||||
uExtensions = detectCPUextensions();
|
||||
#endif
|
||||
|
||||
// Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
// MMX routines available only with integer sample types
|
||||
if (uExtensions & SUPPORT_MMX)
|
||||
{
|
||||
return ::new FIRFilterMMX;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_MMX
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
if (uExtensions & SUPPORT_SSE)
|
||||
{
|
||||
// SSE support
|
||||
return ::new FIRFilterSSE;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_SSE
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
if (uExtensions & SUPPORT_3DNOW)
|
||||
{
|
||||
// 3DNow! support
|
||||
return ::new FIRFilter3DNow;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_3DNOW
|
||||
|
||||
{
|
||||
// ISA optimizations not supported, use plain C version
|
||||
return ::new FIRFilter;
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// General FIR digital filter routines with MMX optimization.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: FIRFilter.cpp,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdexcept>
|
||||
#include "FIRFilter.h"
|
||||
#include "cpu_detect.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
* Implementation of the class 'FIRFilter'
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FIRFilter::FIRFilter()
|
||||
{
|
||||
resultDivFactor = 0;
|
||||
length = 0;
|
||||
lengthDiv8 = 0;
|
||||
filterCoeffs = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter::~FIRFilter()
|
||||
{
|
||||
delete[] filterCoeffs;
|
||||
}
|
||||
|
||||
// Usual C-version of the filter routine for stereo sound
|
||||
uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
uint i, j, end;
|
||||
LONG_SAMPLETYPE suml, sumr;
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
assert(length != 0);
|
||||
|
||||
end = 2 * (numSamples - length);
|
||||
|
||||
for (j = 0; j < end; j += 2)
|
||||
{
|
||||
const SAMPLETYPE *ptr;
|
||||
|
||||
suml = sumr = 0;
|
||||
ptr = src + j;
|
||||
|
||||
for (i = 0; i < length; i += 4)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 2] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 4] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 6] * filterCoeffs[i + 3];
|
||||
sumr += ptr[2 * i + 1] * filterCoeffs[i + 0] +
|
||||
ptr[2 * i + 3] * filterCoeffs[i + 1] +
|
||||
ptr[2 * i + 5] * filterCoeffs[i + 2] +
|
||||
ptr[2 * i + 7] * filterCoeffs[i + 3];
|
||||
}
|
||||
|
||||
#ifdef INTEGER_SAMPLES
|
||||
suml >>= resultDivFactor;
|
||||
sumr >>= resultDivFactor;
|
||||
// saturate to 16 bit integer limits
|
||||
suml = (suml < -32768) ? -32768 : (suml > 32767) ? 32767 : suml;
|
||||
// saturate to 16 bit integer limits
|
||||
sumr = (sumr < -32768) ? -32768 : (sumr > 32767) ? 32767 : sumr;
|
||||
#else
|
||||
suml *= dScaler;
|
||||
sumr *= dScaler;
|
||||
#endif // INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)suml;
|
||||
dest[j + 1] = (SAMPLETYPE)sumr;
|
||||
}
|
||||
return numSamples - length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Usual C-version of the filter routine for mono sound
|
||||
uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples) const
|
||||
{
|
||||
uint i, j, end;
|
||||
LONG_SAMPLETYPE sum;
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// when using floating point samples, use a scaler instead of a divider
|
||||
// because division is much slower operation than multiplying.
|
||||
double dScaler = 1.0 / (double)resultDivider;
|
||||
#endif
|
||||
|
||||
|
||||
assert(length != 0);
|
||||
|
||||
end = numSamples - length;
|
||||
for (j = 0; j < end; j ++)
|
||||
{
|
||||
sum = 0;
|
||||
for (i = 0; i < length; i += 4)
|
||||
{
|
||||
// loop is unrolled by factor of 4 here for efficiency
|
||||
sum += src[i + 0] * filterCoeffs[i + 0] +
|
||||
src[i + 1] * filterCoeffs[i + 1] +
|
||||
src[i + 2] * filterCoeffs[i + 2] +
|
||||
src[i + 3] * filterCoeffs[i + 3];
|
||||
}
|
||||
#ifdef INTEGER_SAMPLES
|
||||
sum >>= resultDivFactor;
|
||||
// saturate to 16 bit integer limits
|
||||
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
|
||||
#else
|
||||
sum *= dScaler;
|
||||
#endif // INTEGER_SAMPLES
|
||||
dest[j] = (SAMPLETYPE)sum;
|
||||
src ++;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
|
||||
|
||||
// Set filter coeffiecients and length.
|
||||
//
|
||||
// Throws an exception if filter length isn't divisible by 8
|
||||
void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
assert(newLength > 0);
|
||||
if (newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8");
|
||||
|
||||
lengthDiv8 = newLength / 8;
|
||||
length = lengthDiv8 * 8;
|
||||
assert(length == newLength);
|
||||
|
||||
resultDivFactor = uResultDivFactor;
|
||||
#ifdef INTEGER_SAMPLES
|
||||
resultDivider = (SAMPLETYPE)(1<<resultDivFactor);
|
||||
#else
|
||||
resultDivider = (SAMPLETYPE)powf(2, (SAMPLETYPE)resultDivFactor);
|
||||
#endif
|
||||
|
||||
delete[] filterCoeffs;
|
||||
filterCoeffs = new SAMPLETYPE[length];
|
||||
memcpy(filterCoeffs, coeffs, length * sizeof(SAMPLETYPE));
|
||||
}
|
||||
|
||||
|
||||
uint FIRFilter::getLength() const
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Applies the filter to the given sequence of samples.
|
||||
//
|
||||
// Note : The amount of outputted samples is by value of 'filter_length'
|
||||
// smaller than the amount of input samples.
|
||||
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||
{
|
||||
assert(numChannels == 1 || numChannels == 2);
|
||||
|
||||
assert(length > 0);
|
||||
assert(lengthDiv8 * 8 == length);
|
||||
if (numSamples < length) return 0;
|
||||
assert(resultDivFactor >= 0);
|
||||
if (numChannels == 2)
|
||||
{
|
||||
return evaluateFilterStereo(dest, src, numSamples);
|
||||
} else {
|
||||
return evaluateFilterMono(dest, src, numSamples);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
// depending on if we've a MMX-capable CPU available or not.
|
||||
void * FIRFilter::operator new(size_t s)
|
||||
{
|
||||
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
||||
throw std::runtime_error("Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilter * FIRFilter::newInstance()
|
||||
{
|
||||
uint uExtensions = 0;
|
||||
|
||||
#if !defined(_MSC_VER) || !defined(__x86_64__)
|
||||
uExtensions = detectCPUextensions();
|
||||
#endif
|
||||
|
||||
// Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
// MMX routines available only with integer sample types
|
||||
if (uExtensions & SUPPORT_MMX)
|
||||
{
|
||||
return ::new FIRFilterMMX;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_MMX
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
if (uExtensions & SUPPORT_SSE)
|
||||
{
|
||||
// SSE support
|
||||
return ::new FIRFilterSSE;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_SSE
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
if (uExtensions & SUPPORT_3DNOW)
|
||||
{
|
||||
// 3DNow! support
|
||||
return ::new FIRFilter3DNow;
|
||||
}
|
||||
else
|
||||
#endif // ALLOW_3DNOW
|
||||
|
||||
{
|
||||
// ISA optimizations not supported, use plain C version
|
||||
return ::new FIRFilter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,163 +1,163 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// General FIR digital filter routines with MMX optimization.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.17 $
|
||||
//
|
||||
// $Id: FIRFilter.h,v 1.17 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIRFilter_H
|
||||
#define FIRFilter_H
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class FIRFilter
|
||||
{
|
||||
protected:
|
||||
// Number of FIR filter taps
|
||||
uint length;
|
||||
// Number of FIR filter taps divided by 8
|
||||
uint lengthDiv8;
|
||||
|
||||
// Result divider factor in 2^k format
|
||||
uint resultDivFactor;
|
||||
|
||||
// Result divider value.
|
||||
SAMPLETYPE resultDivider;
|
||||
|
||||
// Memory for filter coefficients
|
||||
SAMPLETYPE *filterCoeffs;
|
||||
|
||||
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) const;
|
||||
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) const;
|
||||
|
||||
public:
|
||||
FIRFilter();
|
||||
virtual ~FIRFilter();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we've a MMX-capable CPU available or not.
|
||||
void * operator new(size_t s);
|
||||
|
||||
static FIRFilter *newInstance();
|
||||
|
||||
/// Applies the filter to the given sequence of samples.
|
||||
/// Note : The amount of outputted samples is by value of 'filter_length'
|
||||
/// smaller than the amount of input samples.
|
||||
///
|
||||
/// \return Number of samples copied to 'dest'.
|
||||
uint evaluate(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples,
|
||||
uint numChannels) const;
|
||||
|
||||
uint getLength() const;
|
||||
|
||||
virtual void setCoefficients(const SAMPLETYPE *coeffs,
|
||||
uint newLength,
|
||||
uint uResultDivFactor);
|
||||
};
|
||||
|
||||
|
||||
// Optional subclasses that implement CPU-specific optimizations:
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
|
||||
/// Class that implements MMX optimized functions exclusive for 16bit integer samples type.
|
||||
class FIRFilterMMX : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
short *filterCoeffsUnalign;
|
||||
short *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilterMMX();
|
||||
~FIRFilterMMX();
|
||||
|
||||
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_MMX
|
||||
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
|
||||
/// Class that implements 3DNow! optimized functions exclusive for floating point samples type.
|
||||
class FIRFilter3DNow : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
float *filterCoeffsUnalign;
|
||||
float *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilter3DNow();
|
||||
~FIRFilter3DNow();
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_3DNOW
|
||||
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
/// Class that implements SSE optimized functions exclusive for floating point samples type.
|
||||
class FIRFilterSSE : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
float *filterCoeffsUnalign;
|
||||
float *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilterSSE();
|
||||
~FIRFilterSSE();
|
||||
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_SSE
|
||||
|
||||
}
|
||||
|
||||
#endif // FIRFilter_H
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// General FIR digital filter routines with MMX optimization.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.17 $
|
||||
//
|
||||
// $Id: FIRFilter.h,v 1.17 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FIRFilter_H
|
||||
#define FIRFilter_H
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
class FIRFilter
|
||||
{
|
||||
protected:
|
||||
// Number of FIR filter taps
|
||||
uint length;
|
||||
// Number of FIR filter taps divided by 8
|
||||
uint lengthDiv8;
|
||||
|
||||
// Result divider factor in 2^k format
|
||||
uint resultDivFactor;
|
||||
|
||||
// Result divider value.
|
||||
SAMPLETYPE resultDivider;
|
||||
|
||||
// Memory for filter coefficients
|
||||
SAMPLETYPE *filterCoeffs;
|
||||
|
||||
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) const;
|
||||
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) const;
|
||||
|
||||
public:
|
||||
FIRFilter();
|
||||
virtual ~FIRFilter();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we've a MMX-capable CPU available or not.
|
||||
void * operator new(size_t s);
|
||||
|
||||
static FIRFilter *newInstance();
|
||||
|
||||
/// Applies the filter to the given sequence of samples.
|
||||
/// Note : The amount of outputted samples is by value of 'filter_length'
|
||||
/// smaller than the amount of input samples.
|
||||
///
|
||||
/// \return Number of samples copied to 'dest'.
|
||||
uint evaluate(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples,
|
||||
uint numChannels) const;
|
||||
|
||||
uint getLength() const;
|
||||
|
||||
virtual void setCoefficients(const SAMPLETYPE *coeffs,
|
||||
uint newLength,
|
||||
uint uResultDivFactor);
|
||||
};
|
||||
|
||||
|
||||
// Optional subclasses that implement CPU-specific optimizations:
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
|
||||
/// Class that implements MMX optimized functions exclusive for 16bit integer samples type.
|
||||
class FIRFilterMMX : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
short *filterCoeffsUnalign;
|
||||
short *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(short *dest, const short *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilterMMX();
|
||||
~FIRFilterMMX();
|
||||
|
||||
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_MMX
|
||||
|
||||
|
||||
#ifdef ALLOW_3DNOW
|
||||
|
||||
/// Class that implements 3DNow! optimized functions exclusive for floating point samples type.
|
||||
class FIRFilter3DNow : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
float *filterCoeffsUnalign;
|
||||
float *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilter3DNow();
|
||||
~FIRFilter3DNow();
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_3DNOW
|
||||
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
/// Class that implements SSE optimized functions exclusive for floating point samples type.
|
||||
class FIRFilterSSE : public FIRFilter
|
||||
{
|
||||
protected:
|
||||
float *filterCoeffsUnalign;
|
||||
float *filterCoeffsAlign;
|
||||
|
||||
virtual uint evaluateFilterStereo(float *dest, const float *src, uint numSamples) const;
|
||||
public:
|
||||
FIRFilterSSE();
|
||||
~FIRFilterSSE();
|
||||
|
||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||
};
|
||||
|
||||
#endif // ALLOW_SSE
|
||||
|
||||
}
|
||||
|
||||
#endif // FIRFilter_H
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
## Process this file with automake to create Makefile.in
|
||||
##
|
||||
## $Id: Makefile.am,v 1.3 2006/02/05 18:33:34 Olli Exp $
|
||||
##
|
||||
## Copyright (C) 2003 - David W. Durham
|
||||
##
|
||||
## This file is part of SoundTouch, an audio processing library for pitch/time adjustments
|
||||
##
|
||||
## SoundTouch 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.
|
||||
##
|
||||
## SoundTouch 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
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
noinst_HEADERS=AAFilter.h cpu_detect.h FIRFilter.h RateTransposer.h TDStretch.h cpu_detect_x86_gcc.cpp
|
||||
noinst_LIBRARIES = libSoundTouch.a
|
||||
|
||||
if X86_64
|
||||
libSoundTouch_a_CXXFLAGS = -fPIC
|
||||
libSoundTouch_a_CFLAGS = -fPIC
|
||||
else
|
||||
libSoundTouch_a_CXXFLAGS = -msse -mmmx
|
||||
libSoundTouch_a_CFLAGS = -msse -mmmx
|
||||
endif
|
||||
|
||||
#lib_LTLIBRARIES=libSoundTouch.la
|
||||
# the mmx_gcc.cpp and cpu_detect_x86_gcc.cpp may need to be conditionally included here from things discovered in configure.ac
|
||||
libSoundTouch_a_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp mmx_optimized.cpp sse_optimized.cpp \
|
||||
RateTransposer.cpp SoundTouch.cpp TDStretch.cpp WavFile.cpp cpu_detect_x86_gcc.cpp
|
||||
|
||||
# ??? test for -fcheck-new in configure.ac
|
||||
# other compiler flags to add
|
||||
AM_CXXFLAGS=-O3 -msse -fcheck-new -I../../include
|
||||
|
||||
# other linking flags to add
|
||||
#libSoundTouch_la_LIBADD=
|
||||
|
||||
## Process this file with automake to create Makefile.in
|
||||
##
|
||||
## $Id: Makefile.am,v 1.3 2006/02/05 18:33:34 Olli Exp $
|
||||
##
|
||||
## Copyright (C) 2003 - David W. Durham
|
||||
##
|
||||
## This file is part of SoundTouch, an audio processing library for pitch/time adjustments
|
||||
##
|
||||
## SoundTouch 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.
|
||||
##
|
||||
## SoundTouch 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
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
noinst_HEADERS=AAFilter.h cpu_detect.h FIRFilter.h RateTransposer.h TDStretch.h cpu_detect_x86_gcc.cpp
|
||||
noinst_LIBRARIES = libSoundTouch.a
|
||||
|
||||
if X86_64
|
||||
libSoundTouch_a_CXXFLAGS = -fPIC
|
||||
libSoundTouch_a_CFLAGS = -fPIC
|
||||
else
|
||||
libSoundTouch_a_CXXFLAGS = -msse -mmmx
|
||||
libSoundTouch_a_CFLAGS = -msse -mmmx
|
||||
endif
|
||||
|
||||
#lib_LTLIBRARIES=libSoundTouch.la
|
||||
# the mmx_gcc.cpp and cpu_detect_x86_gcc.cpp may need to be conditionally included here from things discovered in configure.ac
|
||||
libSoundTouch_a_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp mmx_optimized.cpp sse_optimized.cpp \
|
||||
RateTransposer.cpp SoundTouch.cpp TDStretch.cpp WavFile.cpp cpu_detect_x86_gcc.cpp
|
||||
|
||||
# ??? test for -fcheck-new in configure.ac
|
||||
# other compiler flags to add
|
||||
AM_CXXFLAGS=-O3 -msse -fcheck-new -I../../include
|
||||
|
||||
# other linking flags to add
|
||||
#libSoundTouch_la_LIBADD=
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,162 +1,162 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
||||
/// together with anti-alias filtering (first order interpolation with anti-
|
||||
/// alias filtering should be quite adequate for this application).
|
||||
///
|
||||
/// Use either of the derived classes of 'RateTransposerInteger' or
|
||||
/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
|
||||
/// algorithm implementation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: RateTransposer.h,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef RateTransposer_H
|
||||
#define RateTransposer_H
|
||||
|
||||
#include "AAFilter.h"
|
||||
#include "FIFOSamplePipe.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// A common linear samplerate transposer class.
|
||||
///
|
||||
/// Note: Use function "RateTransposer::newInstance()" to create a new class
|
||||
/// instance instead of the "new" operator; that function automatically
|
||||
/// chooses a correct implementation depending on if integer or floating
|
||||
/// arithmetics are to be used.
|
||||
class RateTransposer : public FIFOProcessor
|
||||
{
|
||||
protected:
|
||||
/// Anti-alias filter object
|
||||
AAFilter *pAAFilter;
|
||||
|
||||
float fRate;
|
||||
|
||||
uint uChannels;
|
||||
|
||||
/// Buffer for collecting samples to feed the anti-alias filter between
|
||||
/// two batches
|
||||
FIFOSampleBuffer storeBuffer;
|
||||
|
||||
/// Buffer for keeping samples between transposing & anti-alias filter
|
||||
FIFOSampleBuffer tempBuffer;
|
||||
|
||||
/// Output sample buffer
|
||||
FIFOSampleBuffer outputBuffer;
|
||||
|
||||
BOOL bUseAAFilter;
|
||||
|
||||
void init();
|
||||
|
||||
virtual void resetRegisters() = 0;
|
||||
|
||||
virtual uint transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) = 0;
|
||||
virtual uint transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) = 0;
|
||||
uint transpose(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
void flushStoreBuffer();
|
||||
|
||||
void downsample(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
void upsample(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
/// Transposes sample rate by applying anti-alias filter to prevent folding.
|
||||
/// Returns amount of samples returned in the "dest" buffer.
|
||||
/// The maximum amount of samples that can be returned at a time is set by
|
||||
/// the 'set_returnBuffer_size' function.
|
||||
void processSamples(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
|
||||
public:
|
||||
RateTransposer();
|
||||
virtual ~RateTransposer();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we're to use integer or floating point arithmetics.
|
||||
void *operator new(size_t s);
|
||||
|
||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
||||
/// This function automatically chooses a correct implementation, depending on if
|
||||
/// integer ot floating point arithmetics are to be used.
|
||||
static RateTransposer *newInstance();
|
||||
|
||||
/// Returns the output buffer object
|
||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||
|
||||
/// Returns the store buffer object
|
||||
FIFOSamplePipe *getStore() { return &storeBuffer; };
|
||||
|
||||
/// Return anti-alias filter object
|
||||
AAFilter *getAAFilter() const;
|
||||
|
||||
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
|
||||
void enableAAFilter(BOOL newMode);
|
||||
|
||||
/// Returns nonzero if anti-alias filter is enabled.
|
||||
BOOL isAAFilterEnabled() const;
|
||||
|
||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||
/// rate, larger faster rates.
|
||||
virtual void setRate(float newRate);
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint channels);
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object.
|
||||
void putSamples(const SAMPLETYPE *samples, uint numSamples);
|
||||
|
||||
/// Clears all the samples in the object
|
||||
void clear();
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
uint isEmpty();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
||||
/// together with anti-alias filtering (first order interpolation with anti-
|
||||
/// alias filtering should be quite adequate for this application).
|
||||
///
|
||||
/// Use either of the derived classes of 'RateTransposerInteger' or
|
||||
/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
|
||||
/// algorithm implementation.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: RateTransposer.h,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef RateTransposer_H
|
||||
#define RateTransposer_H
|
||||
|
||||
#include "AAFilter.h"
|
||||
#include "FIFOSamplePipe.h"
|
||||
#include "FIFOSampleBuffer.h"
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// A common linear samplerate transposer class.
|
||||
///
|
||||
/// Note: Use function "RateTransposer::newInstance()" to create a new class
|
||||
/// instance instead of the "new" operator; that function automatically
|
||||
/// chooses a correct implementation depending on if integer or floating
|
||||
/// arithmetics are to be used.
|
||||
class RateTransposer : public FIFOProcessor
|
||||
{
|
||||
protected:
|
||||
/// Anti-alias filter object
|
||||
AAFilter *pAAFilter;
|
||||
|
||||
float fRate;
|
||||
|
||||
uint uChannels;
|
||||
|
||||
/// Buffer for collecting samples to feed the anti-alias filter between
|
||||
/// two batches
|
||||
FIFOSampleBuffer storeBuffer;
|
||||
|
||||
/// Buffer for keeping samples between transposing & anti-alias filter
|
||||
FIFOSampleBuffer tempBuffer;
|
||||
|
||||
/// Output sample buffer
|
||||
FIFOSampleBuffer outputBuffer;
|
||||
|
||||
BOOL bUseAAFilter;
|
||||
|
||||
void init();
|
||||
|
||||
virtual void resetRegisters() = 0;
|
||||
|
||||
virtual uint transposeStereo(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) = 0;
|
||||
virtual uint transposeMono(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples) = 0;
|
||||
uint transpose(SAMPLETYPE *dest,
|
||||
const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
void flushStoreBuffer();
|
||||
|
||||
void downsample(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
void upsample(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
/// Transposes sample rate by applying anti-alias filter to prevent folding.
|
||||
/// Returns amount of samples returned in the "dest" buffer.
|
||||
/// The maximum amount of samples that can be returned at a time is set by
|
||||
/// the 'set_returnBuffer_size' function.
|
||||
void processSamples(const SAMPLETYPE *src,
|
||||
uint numSamples);
|
||||
|
||||
|
||||
public:
|
||||
RateTransposer();
|
||||
virtual ~RateTransposer();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we're to use integer or floating point arithmetics.
|
||||
void *operator new(size_t s);
|
||||
|
||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
||||
/// This function automatically chooses a correct implementation, depending on if
|
||||
/// integer ot floating point arithmetics are to be used.
|
||||
static RateTransposer *newInstance();
|
||||
|
||||
/// Returns the output buffer object
|
||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||
|
||||
/// Returns the store buffer object
|
||||
FIFOSamplePipe *getStore() { return &storeBuffer; };
|
||||
|
||||
/// Return anti-alias filter object
|
||||
AAFilter *getAAFilter() const;
|
||||
|
||||
/// Enables/disables the anti-alias filter. Zero to disable, nonzero to enable
|
||||
void enableAAFilter(BOOL newMode);
|
||||
|
||||
/// Returns nonzero if anti-alias filter is enabled.
|
||||
BOOL isAAFilterEnabled() const;
|
||||
|
||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||
/// rate, larger faster rates.
|
||||
virtual void setRate(float newRate);
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint channels);
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object.
|
||||
void putSamples(const SAMPLETYPE *samples, uint numSamples);
|
||||
|
||||
/// Clears all the samples in the object
|
||||
void clear();
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
uint isEmpty();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,202 +1,202 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Common type definitions for SoundTouch audio processing library.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: STTypes.h,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef STTypes_H
|
||||
#define STTypes_H
|
||||
|
||||
//#define INTEGER_SAMPLES 1
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long long ulongptr;
|
||||
#else
|
||||
typedef unsigned long ulongptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
// In GCC, include soundtouch_config.h made by config scritps
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#define HAVE_LIBM 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Use Integer as Sample type */
|
||||
//#define INTEGER_SAMPLES 1
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _WINDEF_
|
||||
// if these aren't defined already by Windows headers, define now
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif // _WINDEF_
|
||||
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
/// Activate these undef's to overrule the possible sampletype
|
||||
/// setting inherited from some other header file:
|
||||
//#undef INTEGER_SAMPLES
|
||||
//#undef FLOAT_SAMPLES
|
||||
|
||||
#if !(INTEGER_SAMPLES || FLOAT_SAMPLES)
|
||||
|
||||
/// Choose either 32bit floating point or 16bit integer sampletype
|
||||
/// by choosing one of the following defines, unless this selection
|
||||
/// has already been done in some other file.
|
||||
////
|
||||
/// Notes:
|
||||
/// - In Windows environment, choose the sample format with the
|
||||
/// following defines.
|
||||
/// - In GNU environment, the floating point samples are used by
|
||||
/// default, but integer samples can be chosen by giving the
|
||||
/// following switch to the configure script:
|
||||
/// ./configure --enable-integer-samples
|
||||
/// However, if you still prefer to select the sample format here
|
||||
/// also in GNU environment, then please #undef the INTEGER_SAMPLE
|
||||
/// and FLOAT_SAMPLE defines first as in comments above.
|
||||
//#define INTEGER_SAMPLES 1 //< 16bit integer samples
|
||||
#define FLOAT_SAMPLES 1 //< 32bit float samples
|
||||
|
||||
#endif
|
||||
|
||||
/// Define this to allow CPU-specific assembler optimizations. Notice that
|
||||
/// having this enabled on non-x86 platforms doesn't matter; the compiler can
|
||||
/// drop unsupported extensions on different platforms automatically.
|
||||
/// However, if you're having difficulties getting the optimized routines
|
||||
/// compiled with your compler (e.g. some gcc compiler versions may be picky),
|
||||
/// you may wish to disable the optimizations to make the library compile.
|
||||
#if !defined(_MSC_VER) || !defined(__x86_64__)
|
||||
#define ALLOW_OPTIMIZATIONS 1
|
||||
#define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
|
||||
#endif
|
||||
|
||||
|
||||
// If defined, allows the SIMD-optimized routines to take minor shortcuts
|
||||
// for improved performance. Undefine to require faithfully similar SIMD
|
||||
// calculations as in normal C implementation.
|
||||
|
||||
|
||||
|
||||
#ifdef INTEGER_SAMPLES
|
||||
// 16bit integer sample type
|
||||
typedef short SAMPLETYPE;
|
||||
// data type for sample accumulation: Use 32bit integer to prevent overflows
|
||||
typedef long LONG_SAMPLETYPE;
|
||||
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// check that only one sample type is defined
|
||||
#error "conflicting sample types defined"
|
||||
#endif // FLOAT_SAMPLES
|
||||
|
||||
#ifdef ALLOW_OPTIMIZATIONS
|
||||
#if (_WIN32 || __i386__ || __x86_64__)
|
||||
// Allow MMX optimizations
|
||||
#define ALLOW_MMX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// floating point samples
|
||||
typedef float SAMPLETYPE;
|
||||
// data type for sample accumulation: Use double to utilize full precision.
|
||||
typedef double LONG_SAMPLETYPE;
|
||||
|
||||
#ifdef ALLOW_OPTIMIZATIONS
|
||||
// Allow 3DNow! and SSE optimizations
|
||||
#if _WIN32
|
||||
// #define ALLOW_3DNOW 1
|
||||
#endif
|
||||
|
||||
#if (_WIN32 || __i386__ || __x86_64__)
|
||||
#define ALLOW_SSE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // INTEGER_SAMPLES
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Common type definitions for SoundTouch audio processing library.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: STTypes.h,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef STTypes_H
|
||||
#define STTypes_H
|
||||
|
||||
//#define INTEGER_SAMPLES 1
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned long ulong;
|
||||
|
||||
#ifdef __x86_64__
|
||||
typedef unsigned long long ulongptr;
|
||||
#else
|
||||
typedef unsigned long ulongptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
// In GCC, include soundtouch_config.h made by config scritps
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#define HAVE_LIBM 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Use Integer as Sample type */
|
||||
//#define INTEGER_SAMPLES 1
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef _WINDEF_
|
||||
// if these aren't defined already by Windows headers, define now
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#endif // _WINDEF_
|
||||
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
/// Activate these undef's to overrule the possible sampletype
|
||||
/// setting inherited from some other header file:
|
||||
//#undef INTEGER_SAMPLES
|
||||
//#undef FLOAT_SAMPLES
|
||||
|
||||
#if !(INTEGER_SAMPLES || FLOAT_SAMPLES)
|
||||
|
||||
/// Choose either 32bit floating point or 16bit integer sampletype
|
||||
/// by choosing one of the following defines, unless this selection
|
||||
/// has already been done in some other file.
|
||||
////
|
||||
/// Notes:
|
||||
/// - In Windows environment, choose the sample format with the
|
||||
/// following defines.
|
||||
/// - In GNU environment, the floating point samples are used by
|
||||
/// default, but integer samples can be chosen by giving the
|
||||
/// following switch to the configure script:
|
||||
/// ./configure --enable-integer-samples
|
||||
/// However, if you still prefer to select the sample format here
|
||||
/// also in GNU environment, then please #undef the INTEGER_SAMPLE
|
||||
/// and FLOAT_SAMPLE defines first as in comments above.
|
||||
//#define INTEGER_SAMPLES 1 //< 16bit integer samples
|
||||
#define FLOAT_SAMPLES 1 //< 32bit float samples
|
||||
|
||||
#endif
|
||||
|
||||
/// Define this to allow CPU-specific assembler optimizations. Notice that
|
||||
/// having this enabled on non-x86 platforms doesn't matter; the compiler can
|
||||
/// drop unsupported extensions on different platforms automatically.
|
||||
/// However, if you're having difficulties getting the optimized routines
|
||||
/// compiled with your compler (e.g. some gcc compiler versions may be picky),
|
||||
/// you may wish to disable the optimizations to make the library compile.
|
||||
#if !defined(_MSC_VER) || !defined(__x86_64__)
|
||||
#define ALLOW_OPTIMIZATIONS 1
|
||||
#define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
|
||||
#endif
|
||||
|
||||
|
||||
// If defined, allows the SIMD-optimized routines to take minor shortcuts
|
||||
// for improved performance. Undefine to require faithfully similar SIMD
|
||||
// calculations as in normal C implementation.
|
||||
|
||||
|
||||
|
||||
#ifdef INTEGER_SAMPLES
|
||||
// 16bit integer sample type
|
||||
typedef short SAMPLETYPE;
|
||||
// data type for sample accumulation: Use 32bit integer to prevent overflows
|
||||
typedef long LONG_SAMPLETYPE;
|
||||
|
||||
#ifdef FLOAT_SAMPLES
|
||||
// check that only one sample type is defined
|
||||
#error "conflicting sample types defined"
|
||||
#endif // FLOAT_SAMPLES
|
||||
|
||||
#ifdef ALLOW_OPTIMIZATIONS
|
||||
#if (_WIN32 || __i386__ || __x86_64__)
|
||||
// Allow MMX optimizations
|
||||
#define ALLOW_MMX 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// floating point samples
|
||||
typedef float SAMPLETYPE;
|
||||
// data type for sample accumulation: Use double to utilize full precision.
|
||||
typedef double LONG_SAMPLETYPE;
|
||||
|
||||
#ifdef ALLOW_OPTIMIZATIONS
|
||||
// Allow 3DNow! and SSE optimizations
|
||||
#if _WIN32
|
||||
// #define ALLOW_3DNOW 1
|
||||
#endif
|
||||
|
||||
#if (_WIN32 || __i386__ || __x86_64__)
|
||||
#define ALLOW_SSE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // INTEGER_SAMPLES
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,474 +1,474 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||
///
|
||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
||||
/// samples that are to be processed are fed into one of the pipe by calling
|
||||
/// function 'putSamples', while the ready processed samples can be read
|
||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||
///
|
||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||
/// samples in order to process the sound. For this reason the classes buffer
|
||||
/// incoming samples until there are enough of samples available for
|
||||
/// processing, then they carry out the processing step and consequently
|
||||
/// make the processed samples available for outputting.
|
||||
///
|
||||
/// - For the above reason, the processing routines introduce a certain
|
||||
/// 'latency' between the input and output, so that the samples input to
|
||||
/// SoundTouch may not be immediately available in the output, and neither
|
||||
/// the amount of outputtable samples may not immediately be in direct
|
||||
/// relationship with the amount of previously input samples.
|
||||
///
|
||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||
/// Please notice though that they aren't currently protected by semaphores,
|
||||
/// so in multi-thread application external semaphore protection may be
|
||||
/// required.
|
||||
///
|
||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
||||
/// tempo and pitch in the same ratio) of the sound. The third available control
|
||||
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||
/// combining the two other controls.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.13 $
|
||||
//
|
||||
// $Id: SoundTouch.cpp,v 1.13 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SoundTouch.h"
|
||||
#include "TDStretch.h"
|
||||
#include "RateTransposer.h"
|
||||
#include "cpu_detect.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
/// Print library version string
|
||||
extern "C" void soundtouch_ac_test()
|
||||
{
|
||||
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
|
||||
}
|
||||
|
||||
|
||||
SoundTouch::SoundTouch()
|
||||
{
|
||||
// Initialize rate transposer and tempo changer instances
|
||||
|
||||
pRateTransposer = RateTransposer::newInstance();
|
||||
pTDStretch = TDStretch::newInstance();
|
||||
|
||||
setOutPipe(pTDStretch);
|
||||
|
||||
rate = tempo = 0;
|
||||
|
||||
virtualPitch =
|
||||
virtualRate =
|
||||
virtualTempo = 1.0;
|
||||
|
||||
calcEffectiveRateAndTempo();
|
||||
|
||||
channels = 0;
|
||||
bSrateSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SoundTouch::~SoundTouch()
|
||||
{
|
||||
delete pRateTransposer;
|
||||
delete pTDStretch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Get SoundTouch library version string
|
||||
const char *SoundTouch::getVersionString()
|
||||
{
|
||||
static const char *_version = SOUNDTOUCH_VERSION;
|
||||
|
||||
return _version;
|
||||
}
|
||||
|
||||
|
||||
/// Get SoundTouch library version Id
|
||||
uint SoundTouch::getVersionId()
|
||||
{
|
||||
return SOUNDTOUCH_VERSION_ID;
|
||||
}
|
||||
|
||||
|
||||
// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void SoundTouch::setChannels(uint numChannels)
|
||||
{
|
||||
if (numChannels != 1 && numChannels != 2)
|
||||
{
|
||||
throw std::runtime_error("Illegal number of channels");
|
||||
}
|
||||
channels = numChannels;
|
||||
pRateTransposer->setChannels(numChannels);
|
||||
pTDStretch->setChannels(numChannels);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
// represent slower rate, larger faster rates.
|
||||
void SoundTouch::setRate(float newRate)
|
||||
{
|
||||
virtualRate = newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new rate control value as a difference in percents compared
|
||||
// to the original rate (-50 .. +100 %)
|
||||
void SoundTouch::setRateChange(float newRate)
|
||||
{
|
||||
virtualRate = 1.0f + 0.01f * newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
// represent slower tempo, larger faster tempo.
|
||||
void SoundTouch::setTempo(float newTempo)
|
||||
{
|
||||
virtualTempo = newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new tempo control value as a difference in percents compared
|
||||
// to the original tempo (-50 .. +100 %)
|
||||
void SoundTouch::setTempoChange(float newTempo)
|
||||
{
|
||||
virtualTempo = 1.0f + 0.01f * newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
// represent lower pitches, larger values higher pitch.
|
||||
void SoundTouch::setPitch(float newPitch)
|
||||
{
|
||||
virtualPitch = newPitch;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets pitch change in octaves compared to the original pitch
|
||||
// (-1.00 .. +1.00)
|
||||
void SoundTouch::setPitchOctaves(float newPitch)
|
||||
{
|
||||
virtualPitch = (float)exp(0.69314718056f * newPitch);
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets pitch change in semi-tones compared to the original pitch
|
||||
// (-12 .. +12)
|
||||
void SoundTouch::setPitchSemiTones(int newPitch)
|
||||
{
|
||||
setPitchOctaves((float)newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SoundTouch::setPitchSemiTones(float newPitch)
|
||||
{
|
||||
setPitchOctaves(newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
// Calculates 'effective' rate and tempo values from the
|
||||
// nominal control values.
|
||||
void SoundTouch::calcEffectiveRateAndTempo()
|
||||
{
|
||||
float oldTempo = tempo;
|
||||
float oldRate = rate;
|
||||
|
||||
tempo = virtualTempo / virtualPitch;
|
||||
rate = virtualPitch * virtualRate;
|
||||
|
||||
if (rate != oldRate) pRateTransposer->setRate(rate);
|
||||
if (tempo != oldTempo) pTDStretch->setTempo(tempo);
|
||||
|
||||
if (rate > 1.0f)
|
||||
{
|
||||
if (output != pRateTransposer)
|
||||
{
|
||||
FIFOSamplePipe *transOut;
|
||||
|
||||
assert(output == pTDStretch);
|
||||
// move samples in the current output buffer to the output of pRateTransposer
|
||||
transOut = pRateTransposer->getOutput();
|
||||
transOut->moveSamples(*output);
|
||||
// move samples in tempo changer's input to pitch transposer's input
|
||||
pRateTransposer->moveSamples(*pTDStretch->getInput());
|
||||
|
||||
output = pRateTransposer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output != pTDStretch)
|
||||
{
|
||||
FIFOSamplePipe *tempoOut;
|
||||
|
||||
assert(output == pRateTransposer);
|
||||
// move samples in the current output buffer to the output of pTDStretch
|
||||
tempoOut = pTDStretch->getOutput();
|
||||
tempoOut->moveSamples(*output);
|
||||
// move samples in pitch transposer's store buffer to tempo changer's input
|
||||
pTDStretch->moveSamples(*pRateTransposer->getStore());
|
||||
|
||||
output = pTDStretch;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets sample rate.
|
||||
void SoundTouch::setSampleRate(uint srate)
|
||||
{
|
||||
bSrateSet = TRUE;
|
||||
// set sample rate, leave other tempo changer parameters as they are.
|
||||
pTDStretch->setParameters(srate);
|
||||
}
|
||||
|
||||
|
||||
// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
// the input of the object.
|
||||
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint numSamples)
|
||||
{
|
||||
if (bSrateSet == FALSE)
|
||||
{
|
||||
throw std::runtime_error("SoundTouch : Sample rate not defined");
|
||||
}
|
||||
else if (channels == 0)
|
||||
{
|
||||
throw std::runtime_error("SoundTouch : Number of channels not defined");
|
||||
}
|
||||
|
||||
// Transpose the rate of the new samples if necessary
|
||||
/* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
|
||||
if (rate == 1.0f)
|
||||
{
|
||||
// The rate value is same as the original, simply evaluate the tempo changer.
|
||||
assert(output == pTDStretch);
|
||||
if (pRateTransposer->isEmpty() == 0)
|
||||
{
|
||||
// yet flush the last samples in the pitch transposer buffer
|
||||
// (may happen if 'rate' changes from a non-zero value to zero)
|
||||
pTDStretch->moveSamples(*pRateTransposer);
|
||||
}
|
||||
pTDStretch->putSamples(samples, numSamples);
|
||||
}
|
||||
*/
|
||||
else if (rate <= 1.0f)
|
||||
{
|
||||
// transpose the rate down, output the transposed sound to tempo changer buffer
|
||||
assert(output == pTDStretch);
|
||||
pRateTransposer->putSamples(samples, numSamples);
|
||||
pTDStretch->moveSamples(*pRateTransposer);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(rate > 1.0f);
|
||||
// evaluate the tempo changer, then transpose the rate up,
|
||||
assert(output == pRateTransposer);
|
||||
pTDStretch->putSamples(samples, numSamples);
|
||||
pRateTransposer->moveSamples(*pTDStretch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Flushes the last samples from the processing pipeline to the output.
|
||||
// Clears also the internal processing buffers.
|
||||
//
|
||||
// Note: This function is meant for extracting the last samples of a sound
|
||||
// stream. This function may introduce additional blank samples in the end
|
||||
// of the sound stream, and thus it's not recommended to call this function
|
||||
// in the middle of a sound stream.
|
||||
void SoundTouch::flush()
|
||||
{
|
||||
int i;
|
||||
uint nOut;
|
||||
SAMPLETYPE buff[128];
|
||||
|
||||
nOut = numSamples();
|
||||
|
||||
memset(buff, 0, 128 * sizeof(SAMPLETYPE));
|
||||
// "Push" the last active samples out from the processing pipeline by
|
||||
// feeding blank samples into the processing pipeline until new,
|
||||
// processed samples appear in the output (not however, more than
|
||||
// 8ksamples in any case)
|
||||
for (i = 0; i < 128; i ++)
|
||||
{
|
||||
putSamples(buff, 64);
|
||||
if (numSamples() != nOut) break; // new samples have appeared in the output!
|
||||
}
|
||||
|
||||
// Clear working buffers
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clearInput();
|
||||
// yet leave the 'tempoChanger' output intouched as that's where the
|
||||
// flushed samples are!
|
||||
}
|
||||
|
||||
|
||||
// Changes a setting controlling the processing system behaviour. See the
|
||||
// 'SETTING_...' defines for available setting ID's.
|
||||
BOOL SoundTouch::setSetting(uint settingId, uint value)
|
||||
{
|
||||
uint sampleRate, sequenceMs, seekWindowMs, overlapMs;
|
||||
|
||||
// read current tdstretch routine parameters
|
||||
pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
|
||||
|
||||
switch (settingId)
|
||||
{
|
||||
case SETTING_USE_AA_FILTER :
|
||||
// enables / disabless anti-alias filter
|
||||
pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_AA_FILTER_LENGTH :
|
||||
// sets anti-alias filter length
|
||||
pRateTransposer->getAAFilter()->setLength(value);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
// enables / disables tempo routine quick seeking algorithm
|
||||
pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_SEQUENCE_MS:
|
||||
// change time-stretch sequence duration parameter
|
||||
pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_SEEKWINDOW_MS:
|
||||
// change time-stretch seek window length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_OVERLAP_MS:
|
||||
// change time-stretch overlap length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
|
||||
return TRUE;
|
||||
|
||||
default :
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reads a setting controlling the processing system behaviour. See the
|
||||
// 'SETTING_...' defines for available setting ID's.
|
||||
//
|
||||
// Returns the setting value.
|
||||
uint SoundTouch::getSetting(uint settingId) const
|
||||
{
|
||||
uint temp;
|
||||
|
||||
switch (settingId)
|
||||
{
|
||||
case SETTING_USE_AA_FILTER :
|
||||
return pRateTransposer->isAAFilterEnabled();
|
||||
|
||||
case SETTING_AA_FILTER_LENGTH :
|
||||
return pRateTransposer->getAAFilter()->getLength();
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
return pTDStretch->isQuickSeekEnabled();
|
||||
|
||||
case SETTING_SEQUENCE_MS:
|
||||
pTDStretch->getParameters(NULL, &temp, NULL, NULL);
|
||||
return temp;
|
||||
|
||||
case SETTING_SEEKWINDOW_MS:
|
||||
pTDStretch->getParameters(NULL, NULL, &temp, NULL);
|
||||
return temp;
|
||||
|
||||
case SETTING_OVERLAP_MS:
|
||||
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
|
||||
return temp;
|
||||
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clears all the samples in the object's output and internal processing
|
||||
// buffers.
|
||||
void SoundTouch::clear()
|
||||
{
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Returns number of samples currently unprocessed.
|
||||
uint SoundTouch::numUnprocessedSamples() const
|
||||
{
|
||||
FIFOSamplePipe * psp;
|
||||
if (pTDStretch)
|
||||
{
|
||||
psp = pTDStretch->getInput();
|
||||
if (psp)
|
||||
{
|
||||
return psp->numSamples();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||
///
|
||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
||||
/// samples that are to be processed are fed into one of the pipe by calling
|
||||
/// function 'putSamples', while the ready processed samples can be read
|
||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||
///
|
||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||
/// samples in order to process the sound. For this reason the classes buffer
|
||||
/// incoming samples until there are enough of samples available for
|
||||
/// processing, then they carry out the processing step and consequently
|
||||
/// make the processed samples available for outputting.
|
||||
///
|
||||
/// - For the above reason, the processing routines introduce a certain
|
||||
/// 'latency' between the input and output, so that the samples input to
|
||||
/// SoundTouch may not be immediately available in the output, and neither
|
||||
/// the amount of outputtable samples may not immediately be in direct
|
||||
/// relationship with the amount of previously input samples.
|
||||
///
|
||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||
/// Please notice though that they aren't currently protected by semaphores,
|
||||
/// so in multi-thread application external semaphore protection may be
|
||||
/// required.
|
||||
///
|
||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
||||
/// tempo and pitch in the same ratio) of the sound. The third available control
|
||||
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||
/// combining the two other controls.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.13 $
|
||||
//
|
||||
// $Id: SoundTouch.cpp,v 1.13 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "SoundTouch.h"
|
||||
#include "TDStretch.h"
|
||||
#include "RateTransposer.h"
|
||||
#include "cpu_detect.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
/// Print library version string
|
||||
extern "C" void soundtouch_ac_test()
|
||||
{
|
||||
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
|
||||
}
|
||||
|
||||
|
||||
SoundTouch::SoundTouch()
|
||||
{
|
||||
// Initialize rate transposer and tempo changer instances
|
||||
|
||||
pRateTransposer = RateTransposer::newInstance();
|
||||
pTDStretch = TDStretch::newInstance();
|
||||
|
||||
setOutPipe(pTDStretch);
|
||||
|
||||
rate = tempo = 0;
|
||||
|
||||
virtualPitch =
|
||||
virtualRate =
|
||||
virtualTempo = 1.0;
|
||||
|
||||
calcEffectiveRateAndTempo();
|
||||
|
||||
channels = 0;
|
||||
bSrateSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SoundTouch::~SoundTouch()
|
||||
{
|
||||
delete pRateTransposer;
|
||||
delete pTDStretch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Get SoundTouch library version string
|
||||
const char *SoundTouch::getVersionString()
|
||||
{
|
||||
static const char *_version = SOUNDTOUCH_VERSION;
|
||||
|
||||
return _version;
|
||||
}
|
||||
|
||||
|
||||
/// Get SoundTouch library version Id
|
||||
uint SoundTouch::getVersionId()
|
||||
{
|
||||
return SOUNDTOUCH_VERSION_ID;
|
||||
}
|
||||
|
||||
|
||||
// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void SoundTouch::setChannels(uint numChannels)
|
||||
{
|
||||
if (numChannels != 1 && numChannels != 2)
|
||||
{
|
||||
throw std::runtime_error("Illegal number of channels");
|
||||
}
|
||||
channels = numChannels;
|
||||
pRateTransposer->setChannels(numChannels);
|
||||
pTDStretch->setChannels(numChannels);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
// represent slower rate, larger faster rates.
|
||||
void SoundTouch::setRate(float newRate)
|
||||
{
|
||||
virtualRate = newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new rate control value as a difference in percents compared
|
||||
// to the original rate (-50 .. +100 %)
|
||||
void SoundTouch::setRateChange(float newRate)
|
||||
{
|
||||
virtualRate = 1.0f + 0.01f * newRate;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
// represent slower tempo, larger faster tempo.
|
||||
void SoundTouch::setTempo(float newTempo)
|
||||
{
|
||||
virtualTempo = newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new tempo control value as a difference in percents compared
|
||||
// to the original tempo (-50 .. +100 %)
|
||||
void SoundTouch::setTempoChange(float newTempo)
|
||||
{
|
||||
virtualTempo = 1.0f + 0.01f * newTempo;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
// represent lower pitches, larger values higher pitch.
|
||||
void SoundTouch::setPitch(float newPitch)
|
||||
{
|
||||
virtualPitch = newPitch;
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets pitch change in octaves compared to the original pitch
|
||||
// (-1.00 .. +1.00)
|
||||
void SoundTouch::setPitchOctaves(float newPitch)
|
||||
{
|
||||
virtualPitch = (float)exp(0.69314718056f * newPitch);
|
||||
calcEffectiveRateAndTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Sets pitch change in semi-tones compared to the original pitch
|
||||
// (-12 .. +12)
|
||||
void SoundTouch::setPitchSemiTones(int newPitch)
|
||||
{
|
||||
setPitchOctaves((float)newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SoundTouch::setPitchSemiTones(float newPitch)
|
||||
{
|
||||
setPitchOctaves(newPitch / 12.0f);
|
||||
}
|
||||
|
||||
|
||||
// Calculates 'effective' rate and tempo values from the
|
||||
// nominal control values.
|
||||
void SoundTouch::calcEffectiveRateAndTempo()
|
||||
{
|
||||
float oldTempo = tempo;
|
||||
float oldRate = rate;
|
||||
|
||||
tempo = virtualTempo / virtualPitch;
|
||||
rate = virtualPitch * virtualRate;
|
||||
|
||||
if (rate != oldRate) pRateTransposer->setRate(rate);
|
||||
if (tempo != oldTempo) pTDStretch->setTempo(tempo);
|
||||
|
||||
if (rate > 1.0f)
|
||||
{
|
||||
if (output != pRateTransposer)
|
||||
{
|
||||
FIFOSamplePipe *transOut;
|
||||
|
||||
assert(output == pTDStretch);
|
||||
// move samples in the current output buffer to the output of pRateTransposer
|
||||
transOut = pRateTransposer->getOutput();
|
||||
transOut->moveSamples(*output);
|
||||
// move samples in tempo changer's input to pitch transposer's input
|
||||
pRateTransposer->moveSamples(*pTDStretch->getInput());
|
||||
|
||||
output = pRateTransposer;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output != pTDStretch)
|
||||
{
|
||||
FIFOSamplePipe *tempoOut;
|
||||
|
||||
assert(output == pRateTransposer);
|
||||
// move samples in the current output buffer to the output of pTDStretch
|
||||
tempoOut = pTDStretch->getOutput();
|
||||
tempoOut->moveSamples(*output);
|
||||
// move samples in pitch transposer's store buffer to tempo changer's input
|
||||
pTDStretch->moveSamples(*pRateTransposer->getStore());
|
||||
|
||||
output = pTDStretch;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sets sample rate.
|
||||
void SoundTouch::setSampleRate(uint srate)
|
||||
{
|
||||
bSrateSet = TRUE;
|
||||
// set sample rate, leave other tempo changer parameters as they are.
|
||||
pTDStretch->setParameters(srate);
|
||||
}
|
||||
|
||||
|
||||
// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
// the input of the object.
|
||||
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint numSamples)
|
||||
{
|
||||
if (bSrateSet == FALSE)
|
||||
{
|
||||
throw std::runtime_error("SoundTouch : Sample rate not defined");
|
||||
}
|
||||
else if (channels == 0)
|
||||
{
|
||||
throw std::runtime_error("SoundTouch : Number of channels not defined");
|
||||
}
|
||||
|
||||
// Transpose the rate of the new samples if necessary
|
||||
/* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
|
||||
if (rate == 1.0f)
|
||||
{
|
||||
// The rate value is same as the original, simply evaluate the tempo changer.
|
||||
assert(output == pTDStretch);
|
||||
if (pRateTransposer->isEmpty() == 0)
|
||||
{
|
||||
// yet flush the last samples in the pitch transposer buffer
|
||||
// (may happen if 'rate' changes from a non-zero value to zero)
|
||||
pTDStretch->moveSamples(*pRateTransposer);
|
||||
}
|
||||
pTDStretch->putSamples(samples, numSamples);
|
||||
}
|
||||
*/
|
||||
else if (rate <= 1.0f)
|
||||
{
|
||||
// transpose the rate down, output the transposed sound to tempo changer buffer
|
||||
assert(output == pTDStretch);
|
||||
pRateTransposer->putSamples(samples, numSamples);
|
||||
pTDStretch->moveSamples(*pRateTransposer);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(rate > 1.0f);
|
||||
// evaluate the tempo changer, then transpose the rate up,
|
||||
assert(output == pRateTransposer);
|
||||
pTDStretch->putSamples(samples, numSamples);
|
||||
pRateTransposer->moveSamples(*pTDStretch);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Flushes the last samples from the processing pipeline to the output.
|
||||
// Clears also the internal processing buffers.
|
||||
//
|
||||
// Note: This function is meant for extracting the last samples of a sound
|
||||
// stream. This function may introduce additional blank samples in the end
|
||||
// of the sound stream, and thus it's not recommended to call this function
|
||||
// in the middle of a sound stream.
|
||||
void SoundTouch::flush()
|
||||
{
|
||||
int i;
|
||||
uint nOut;
|
||||
SAMPLETYPE buff[128];
|
||||
|
||||
nOut = numSamples();
|
||||
|
||||
memset(buff, 0, 128 * sizeof(SAMPLETYPE));
|
||||
// "Push" the last active samples out from the processing pipeline by
|
||||
// feeding blank samples into the processing pipeline until new,
|
||||
// processed samples appear in the output (not however, more than
|
||||
// 8ksamples in any case)
|
||||
for (i = 0; i < 128; i ++)
|
||||
{
|
||||
putSamples(buff, 64);
|
||||
if (numSamples() != nOut) break; // new samples have appeared in the output!
|
||||
}
|
||||
|
||||
// Clear working buffers
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clearInput();
|
||||
// yet leave the 'tempoChanger' output intouched as that's where the
|
||||
// flushed samples are!
|
||||
}
|
||||
|
||||
|
||||
// Changes a setting controlling the processing system behaviour. See the
|
||||
// 'SETTING_...' defines for available setting ID's.
|
||||
BOOL SoundTouch::setSetting(uint settingId, uint value)
|
||||
{
|
||||
uint sampleRate, sequenceMs, seekWindowMs, overlapMs;
|
||||
|
||||
// read current tdstretch routine parameters
|
||||
pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
|
||||
|
||||
switch (settingId)
|
||||
{
|
||||
case SETTING_USE_AA_FILTER :
|
||||
// enables / disabless anti-alias filter
|
||||
pRateTransposer->enableAAFilter((value != 0) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_AA_FILTER_LENGTH :
|
||||
// sets anti-alias filter length
|
||||
pRateTransposer->getAAFilter()->setLength(value);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
// enables / disables tempo routine quick seeking algorithm
|
||||
pTDStretch->enableQuickSeek((value != 0) ? TRUE : FALSE);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_SEQUENCE_MS:
|
||||
// change time-stretch sequence duration parameter
|
||||
pTDStretch->setParameters(sampleRate, value, seekWindowMs, overlapMs);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_SEEKWINDOW_MS:
|
||||
// change time-stretch seek window length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, value, overlapMs);
|
||||
return TRUE;
|
||||
|
||||
case SETTING_OVERLAP_MS:
|
||||
// change time-stretch overlap length parameter
|
||||
pTDStretch->setParameters(sampleRate, sequenceMs, seekWindowMs, value);
|
||||
return TRUE;
|
||||
|
||||
default :
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Reads a setting controlling the processing system behaviour. See the
|
||||
// 'SETTING_...' defines for available setting ID's.
|
||||
//
|
||||
// Returns the setting value.
|
||||
uint SoundTouch::getSetting(uint settingId) const
|
||||
{
|
||||
uint temp;
|
||||
|
||||
switch (settingId)
|
||||
{
|
||||
case SETTING_USE_AA_FILTER :
|
||||
return pRateTransposer->isAAFilterEnabled();
|
||||
|
||||
case SETTING_AA_FILTER_LENGTH :
|
||||
return pRateTransposer->getAAFilter()->getLength();
|
||||
|
||||
case SETTING_USE_QUICKSEEK :
|
||||
return pTDStretch->isQuickSeekEnabled();
|
||||
|
||||
case SETTING_SEQUENCE_MS:
|
||||
pTDStretch->getParameters(NULL, &temp, NULL, NULL);
|
||||
return temp;
|
||||
|
||||
case SETTING_SEEKWINDOW_MS:
|
||||
pTDStretch->getParameters(NULL, NULL, &temp, NULL);
|
||||
return temp;
|
||||
|
||||
case SETTING_OVERLAP_MS:
|
||||
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
|
||||
return temp;
|
||||
|
||||
default :
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Clears all the samples in the object's output and internal processing
|
||||
// buffers.
|
||||
void SoundTouch::clear()
|
||||
{
|
||||
pRateTransposer->clear();
|
||||
pTDStretch->clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Returns number of samples currently unprocessed.
|
||||
uint SoundTouch::numUnprocessedSamples() const
|
||||
{
|
||||
FIFOSamplePipe * psp;
|
||||
if (pTDStretch)
|
||||
{
|
||||
psp = pTDStretch->getInput();
|
||||
if (psp)
|
||||
{
|
||||
return psp->numSamples();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,252 +1,252 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||
///
|
||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
||||
/// samples that are to be processed are fed into one of the pipe by calling
|
||||
/// function 'putSamples', while the ready processed samples can be read
|
||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||
///
|
||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||
/// samples in order to process the sound. For this reason the classes buffer
|
||||
/// incoming samples until there are enough of samples available for
|
||||
/// processing, then they carry out the processing step and consequently
|
||||
/// make the processed samples available for outputting.
|
||||
///
|
||||
/// - For the above reason, the processing routines introduce a certain
|
||||
/// 'latency' between the input and output, so that the samples input to
|
||||
/// SoundTouch may not be immediately available in the output, and neither
|
||||
/// the amount of outputtable samples may not immediately be in direct
|
||||
/// relationship with the amount of previously input samples.
|
||||
///
|
||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||
/// Please notice though that they aren't currently protected by semaphores,
|
||||
/// so in multi-thread application external semaphore protection may be
|
||||
/// required.
|
||||
///
|
||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
||||
/// tempo and pitch in the same ratio) of the sound. The third available control
|
||||
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||
/// combining the two other controls.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.14 $
|
||||
//
|
||||
// $Id: SoundTouch.h,v 1.14 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SoundTouch_H
|
||||
#define SoundTouch_H
|
||||
|
||||
#include "FIFOSamplePipe.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Soundtouch library version string
|
||||
#define SOUNDTOUCH_VERSION "1.3.1"
|
||||
|
||||
/// SoundTouch library version id
|
||||
#define SOUNDTOUCH_VERSION_ID 010301
|
||||
|
||||
//
|
||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||
|
||||
/// Enable/disable anti-alias filter in pitch transposer (0 = disable)
|
||||
#define SETTING_USE_AA_FILTER 0
|
||||
|
||||
/// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
|
||||
#define SETTING_AA_FILTER_LENGTH 1
|
||||
|
||||
/// Enable/disable quick seeking algorithm in tempo changer routine
|
||||
/// (enabling quick seeking lowers CPU utilization but causes a minor sound
|
||||
/// quality compromising)
|
||||
#define SETTING_USE_QUICKSEEK 2
|
||||
|
||||
/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
|
||||
/// to how long sequences the original sound is chopped in the time-stretch algorithm.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_SEQUENCE_MS 3
|
||||
|
||||
/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
|
||||
/// best possible overlapping location. This determines from how wide window the algorithm
|
||||
/// may look for an optimal joining location when mixing the sound sequences back together.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_SEEKWINDOW_MS 4
|
||||
|
||||
/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
|
||||
/// are mixed back together, to form a continuous sound stream, this parameter defines over
|
||||
/// how long period the two consecutive sequences are let to overlap each other.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_OVERLAP_MS 5
|
||||
|
||||
|
||||
class SoundTouch : public FIFOProcessor
|
||||
{
|
||||
private:
|
||||
/// Rate transposer class instance
|
||||
class RateTransposer *pRateTransposer;
|
||||
|
||||
/// Time-stretch class instance
|
||||
class TDStretch *pTDStretch;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualRate;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualTempo;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualPitch;
|
||||
|
||||
/// Flag: Has sample rate been set?
|
||||
BOOL bSrateSet;
|
||||
|
||||
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
|
||||
/// 'virtualPitch' parameters.
|
||||
void calcEffectiveRateAndTempo();
|
||||
|
||||
protected :
|
||||
/// Number of channels
|
||||
uint channels;
|
||||
|
||||
/// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
float rate;
|
||||
|
||||
/// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
float tempo;
|
||||
|
||||
public:
|
||||
SoundTouch();
|
||||
virtual ~SoundTouch();
|
||||
|
||||
/// Get SoundTouch library version string
|
||||
static const char *getVersionString();
|
||||
|
||||
/// Get SoundTouch library version Id
|
||||
static uint getVersionId();
|
||||
|
||||
/// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
/// represent slower rate, larger faster rates.
|
||||
void setRate(float newRate);
|
||||
|
||||
/// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
/// represent slower tempo, larger faster tempo.
|
||||
void setTempo(float newTempo);
|
||||
|
||||
/// Sets new rate control value as a difference in percents compared
|
||||
/// to the original rate (-50 .. +100 %)
|
||||
void setRateChange(float newRate);
|
||||
|
||||
/// Sets new tempo control value as a difference in percents compared
|
||||
/// to the original tempo (-50 .. +100 %)
|
||||
void setTempoChange(float newTempo);
|
||||
|
||||
/// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
/// represent lower pitches, larger values higher pitch.
|
||||
void setPitch(float newPitch);
|
||||
|
||||
/// Sets pitch change in octaves compared to the original pitch
|
||||
/// (-1.00 .. +1.00)
|
||||
void setPitchOctaves(float newPitch);
|
||||
|
||||
/// Sets pitch change in semi-tones compared to the original pitch
|
||||
/// (-12 .. +12)
|
||||
void setPitchSemiTones(int newPitch);
|
||||
void setPitchSemiTones(float newPitch);
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Sets sample rate.
|
||||
void setSampleRate(uint srate);
|
||||
|
||||
/// Flushes the last samples from the processing pipeline to the output.
|
||||
/// Clears also the internal processing buffers.
|
||||
//
|
||||
/// Note: This function is meant for extracting the last samples of a sound
|
||||
/// stream. This function may introduce additional blank samples in the end
|
||||
/// of the sound stream, and thus it's not recommended to call this function
|
||||
/// in the middle of a sound stream.
|
||||
void flush();
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object. Notice that sample rate _has_to_ be set before
|
||||
/// calling this function, otherwise throws a runtime_error exception.
|
||||
virtual void putSamples(
|
||||
const SAMPLETYPE *samples, ///< Pointer to sample buffer.
|
||||
uint numSamples ///< Number of samples in buffer. Notice
|
||||
///< that in case of stereo-sound a single sample
|
||||
///< contains data for both channels.
|
||||
);
|
||||
|
||||
/// Clears all the samples in the object's output and internal processing
|
||||
/// buffers.
|
||||
virtual void clear();
|
||||
|
||||
/// Changes a setting controlling the processing system behaviour. See the
|
||||
/// 'SETTING_...' defines for available setting ID's.
|
||||
///
|
||||
/// \return 'TRUE' if the setting was succesfully changed
|
||||
BOOL setSetting(uint settingId, ///< Setting ID number. see SETTING_... defines.
|
||||
uint value ///< New setting value.
|
||||
);
|
||||
|
||||
/// Reads a setting controlling the processing system behaviour. See the
|
||||
/// 'SETTING_...' defines for available setting ID's.
|
||||
///
|
||||
/// \return the setting value.
|
||||
uint getSetting(uint settingId ///< Setting ID number, see SETTING_... defines.
|
||||
) const;
|
||||
|
||||
/// Returns number of samples currently unprocessed.
|
||||
virtual uint numUnprocessedSamples() const;
|
||||
|
||||
|
||||
/// Other handy functions that are implemented in the ancestor classes (see
|
||||
/// classes 'FIFOProcessor' and 'FIFOSamplePipe')
|
||||
///
|
||||
/// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
|
||||
/// - numSamples() : Get number of 'ready' samples that can be received with
|
||||
/// function 'receiveSamples()'
|
||||
/// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
|
||||
/// - clear() : Clears all samples from ready/processing buffers.
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||
///
|
||||
/// Notes:
|
||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||
///
|
||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
||||
/// samples that are to be processed are fed into one of the pipe by calling
|
||||
/// function 'putSamples', while the ready processed samples can be read
|
||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||
///
|
||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||
/// samples in order to process the sound. For this reason the classes buffer
|
||||
/// incoming samples until there are enough of samples available for
|
||||
/// processing, then they carry out the processing step and consequently
|
||||
/// make the processed samples available for outputting.
|
||||
///
|
||||
/// - For the above reason, the processing routines introduce a certain
|
||||
/// 'latency' between the input and output, so that the samples input to
|
||||
/// SoundTouch may not be immediately available in the output, and neither
|
||||
/// the amount of outputtable samples may not immediately be in direct
|
||||
/// relationship with the amount of previously input samples.
|
||||
///
|
||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||
/// Please notice though that they aren't currently protected by semaphores,
|
||||
/// so in multi-thread application external semaphore protection may be
|
||||
/// required.
|
||||
///
|
||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
||||
/// tempo and pitch in the same ratio) of the sound. The third available control
|
||||
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||
/// combining the two other controls.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.14 $
|
||||
//
|
||||
// $Id: SoundTouch.h,v 1.14 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SoundTouch_H
|
||||
#define SoundTouch_H
|
||||
|
||||
#include "FIFOSamplePipe.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
/// Soundtouch library version string
|
||||
#define SOUNDTOUCH_VERSION "1.3.1"
|
||||
|
||||
/// SoundTouch library version id
|
||||
#define SOUNDTOUCH_VERSION_ID 010301
|
||||
|
||||
//
|
||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||
|
||||
/// Enable/disable anti-alias filter in pitch transposer (0 = disable)
|
||||
#define SETTING_USE_AA_FILTER 0
|
||||
|
||||
/// Pitch transposer anti-alias filter length (8 .. 128 taps, default = 32)
|
||||
#define SETTING_AA_FILTER_LENGTH 1
|
||||
|
||||
/// Enable/disable quick seeking algorithm in tempo changer routine
|
||||
/// (enabling quick seeking lowers CPU utilization but causes a minor sound
|
||||
/// quality compromising)
|
||||
#define SETTING_USE_QUICKSEEK 2
|
||||
|
||||
/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
|
||||
/// to how long sequences the original sound is chopped in the time-stretch algorithm.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_SEQUENCE_MS 3
|
||||
|
||||
/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
|
||||
/// best possible overlapping location. This determines from how wide window the algorithm
|
||||
/// may look for an optimal joining location when mixing the sound sequences back together.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_SEEKWINDOW_MS 4
|
||||
|
||||
/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
|
||||
/// are mixed back together, to form a continuous sound stream, this parameter defines over
|
||||
/// how long period the two consecutive sequences are let to overlap each other.
|
||||
/// See "STTypes.h" or README for more information.
|
||||
#define SETTING_OVERLAP_MS 5
|
||||
|
||||
|
||||
class SoundTouch : public FIFOProcessor
|
||||
{
|
||||
private:
|
||||
/// Rate transposer class instance
|
||||
class RateTransposer *pRateTransposer;
|
||||
|
||||
/// Time-stretch class instance
|
||||
class TDStretch *pTDStretch;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualRate;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualTempo;
|
||||
|
||||
/// Virtual pitch parameter. Effective rate & tempo are calculated from these parameters.
|
||||
float virtualPitch;
|
||||
|
||||
/// Flag: Has sample rate been set?
|
||||
BOOL bSrateSet;
|
||||
|
||||
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
|
||||
/// 'virtualPitch' parameters.
|
||||
void calcEffectiveRateAndTempo();
|
||||
|
||||
protected :
|
||||
/// Number of channels
|
||||
uint channels;
|
||||
|
||||
/// Effective 'rate' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
float rate;
|
||||
|
||||
/// Effective 'tempo' value calculated from 'virtualRate', 'virtualTempo' and 'virtualPitch'
|
||||
float tempo;
|
||||
|
||||
public:
|
||||
SoundTouch();
|
||||
virtual ~SoundTouch();
|
||||
|
||||
/// Get SoundTouch library version string
|
||||
static const char *getVersionString();
|
||||
|
||||
/// Get SoundTouch library version Id
|
||||
static uint getVersionId();
|
||||
|
||||
/// Sets new rate control value. Normal rate = 1.0, smaller values
|
||||
/// represent slower rate, larger faster rates.
|
||||
void setRate(float newRate);
|
||||
|
||||
/// Sets new tempo control value. Normal tempo = 1.0, smaller values
|
||||
/// represent slower tempo, larger faster tempo.
|
||||
void setTempo(float newTempo);
|
||||
|
||||
/// Sets new rate control value as a difference in percents compared
|
||||
/// to the original rate (-50 .. +100 %)
|
||||
void setRateChange(float newRate);
|
||||
|
||||
/// Sets new tempo control value as a difference in percents compared
|
||||
/// to the original tempo (-50 .. +100 %)
|
||||
void setTempoChange(float newTempo);
|
||||
|
||||
/// Sets new pitch control value. Original pitch = 1.0, smaller values
|
||||
/// represent lower pitches, larger values higher pitch.
|
||||
void setPitch(float newPitch);
|
||||
|
||||
/// Sets pitch change in octaves compared to the original pitch
|
||||
/// (-1.00 .. +1.00)
|
||||
void setPitchOctaves(float newPitch);
|
||||
|
||||
/// Sets pitch change in semi-tones compared to the original pitch
|
||||
/// (-12 .. +12)
|
||||
void setPitchSemiTones(int newPitch);
|
||||
void setPitchSemiTones(float newPitch);
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Sets sample rate.
|
||||
void setSampleRate(uint srate);
|
||||
|
||||
/// Flushes the last samples from the processing pipeline to the output.
|
||||
/// Clears also the internal processing buffers.
|
||||
//
|
||||
/// Note: This function is meant for extracting the last samples of a sound
|
||||
/// stream. This function may introduce additional blank samples in the end
|
||||
/// of the sound stream, and thus it's not recommended to call this function
|
||||
/// in the middle of a sound stream.
|
||||
void flush();
|
||||
|
||||
/// Adds 'numSamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object. Notice that sample rate _has_to_ be set before
|
||||
/// calling this function, otherwise throws a runtime_error exception.
|
||||
virtual void putSamples(
|
||||
const SAMPLETYPE *samples, ///< Pointer to sample buffer.
|
||||
uint numSamples ///< Number of samples in buffer. Notice
|
||||
///< that in case of stereo-sound a single sample
|
||||
///< contains data for both channels.
|
||||
);
|
||||
|
||||
/// Clears all the samples in the object's output and internal processing
|
||||
/// buffers.
|
||||
virtual void clear();
|
||||
|
||||
/// Changes a setting controlling the processing system behaviour. See the
|
||||
/// 'SETTING_...' defines for available setting ID's.
|
||||
///
|
||||
/// \return 'TRUE' if the setting was succesfully changed
|
||||
BOOL setSetting(uint settingId, ///< Setting ID number. see SETTING_... defines.
|
||||
uint value ///< New setting value.
|
||||
);
|
||||
|
||||
/// Reads a setting controlling the processing system behaviour. See the
|
||||
/// 'SETTING_...' defines for available setting ID's.
|
||||
///
|
||||
/// \return the setting value.
|
||||
uint getSetting(uint settingId ///< Setting ID number, see SETTING_... defines.
|
||||
) const;
|
||||
|
||||
/// Returns number of samples currently unprocessed.
|
||||
virtual uint numUnprocessedSamples() const;
|
||||
|
||||
|
||||
/// Other handy functions that are implemented in the ancestor classes (see
|
||||
/// classes 'FIFOProcessor' and 'FIFOSamplePipe')
|
||||
///
|
||||
/// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
|
||||
/// - numSamples() : Get number of 'ready' samples that can be received with
|
||||
/// function 'receiveSamples()'
|
||||
/// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
|
||||
/// - clear() : Clears all samples from ready/processing buffers.
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,236 +1,236 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||
/// with several performance-increasing tweaks.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: TDStretch.h,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TDStretch_H
|
||||
#define TDStretch_H
|
||||
|
||||
#include "STTypes.h"
|
||||
#include "RateTransposer.h"
|
||||
#include "FIFOSamplePipe.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
// Default values for sound processing parameters:
|
||||
|
||||
/// Default length of a single processing sequence, in milliseconds. This determines to how
|
||||
/// long sequences the original sound is chopped in the time-stretch algorithm.
|
||||
///
|
||||
/// The larger this value is, the lesser sequences are used in processing. In principle
|
||||
/// a bigger value sounds better when slowing down tempo, but worse when increasing tempo
|
||||
/// and vice versa.
|
||||
///
|
||||
/// Increasing this value reduces computational burden & vice versa.
|
||||
#define DEFAULT_SEQUENCE_MS 61
|
||||
|
||||
#define DEFAULT_SEEKWINDOW_MS 18
|
||||
|
||||
#define DEFAULT_OVERLAP_MS 7
|
||||
|
||||
|
||||
/// Class that does the time-stretch (tempo change) effect for the processed
|
||||
/// sound.
|
||||
class TDStretch : public FIFOProcessor
|
||||
{
|
||||
protected:
|
||||
uint channels;
|
||||
uint sampleReq;
|
||||
float tempo;
|
||||
|
||||
SAMPLETYPE *pMidBuffer;
|
||||
SAMPLETYPE *pRefMidBuffer;
|
||||
SAMPLETYPE *pRefMidBufferUnaligned;
|
||||
uint overlapLength;
|
||||
uint overlapDividerBits;
|
||||
uint slopingDivider;
|
||||
uint seekLength;
|
||||
uint seekWindowLength;
|
||||
uint maxOffset;
|
||||
float nominalSkip;
|
||||
float skipFract;
|
||||
FIFOSampleBuffer outputBuffer;
|
||||
FIFOSampleBuffer inputBuffer;
|
||||
BOOL bQuickseek;
|
||||
BOOL bMidBufferDirty;
|
||||
|
||||
uint sampleRate;
|
||||
uint sequenceMs;
|
||||
uint seekWindowMs;
|
||||
uint overlapMs;
|
||||
|
||||
void acceptNewOverlapLength(uint newOverlapLength);
|
||||
|
||||
virtual void clearCrossCorrState();
|
||||
void calculateOverlapLength(uint overlapMs);
|
||||
|
||||
virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
||||
virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
||||
|
||||
virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
|
||||
uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
|
||||
|
||||
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
||||
virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
||||
|
||||
void clearMidBuffer();
|
||||
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
|
||||
|
||||
void precalcCorrReferenceMono();
|
||||
void precalcCorrReferenceStereo();
|
||||
|
||||
void processNominalTempo();
|
||||
|
||||
/// Changes the tempo of the given sound samples.
|
||||
/// Returns amount of samples returned in the "output" buffer.
|
||||
/// The maximum amount of samples that can be returned at a time is set by
|
||||
/// the 'set_returnBuffer_size' function.
|
||||
void processSamples();
|
||||
|
||||
public:
|
||||
TDStretch();
|
||||
virtual ~TDStretch();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||
void *operator new(size_t s);
|
||||
|
||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
||||
/// This function automatically chooses a correct feature set depending on if the CPU
|
||||
/// supports MMX/SSE/etc extensions.
|
||||
static TDStretch *newInstance();
|
||||
|
||||
/// Returns the output buffer object
|
||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||
|
||||
/// Returns the input buffer object
|
||||
FIFOSamplePipe *getInput() { return &inputBuffer; };
|
||||
|
||||
/// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
||||
/// tempo, larger faster tempo.
|
||||
void setTempo(float newTempo);
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual void clear();
|
||||
|
||||
/// Clears the input buffer
|
||||
void clearInput();
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Enables/disables the quick position seeking algorithm. Zero to disable,
|
||||
/// nonzero to enable
|
||||
void enableQuickSeek(BOOL enable);
|
||||
|
||||
/// Returns nonzero if the quick seeking algorithm is enabled.
|
||||
BOOL isQuickSeekEnabled() const;
|
||||
|
||||
/// Sets routine control parameters. These control are certain time constants
|
||||
/// defining how the sound is stretched to the desired duration.
|
||||
//
|
||||
/// 'sampleRate' = sample rate of the sound
|
||||
/// 'sequenceMS' = one processing sequence length in milliseconds
|
||||
/// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
||||
/// position
|
||||
/// 'overlapMS' = overlapping length
|
||||
void setParameters(uint sampleRate, ///< Samplerate of sound being processed (Hz)
|
||||
uint sequenceMS = DEFAULT_SEQUENCE_MS, ///< Single processing sequence length (ms)
|
||||
uint seekwindowMS = DEFAULT_SEEKWINDOW_MS, ///< Offset seeking window length (ms)
|
||||
uint overlapMS = DEFAULT_OVERLAP_MS ///< Sequence overlapping length (ms)
|
||||
);
|
||||
|
||||
/// Get routine control parameters, see setParameters() function.
|
||||
/// Any of the parameters to this function can be NULL, in such case corresponding parameter
|
||||
/// value isn't returned.
|
||||
void getParameters(uint *pSampleRate, uint *pSequenceMs, uint *pSeekWindowMs, uint *pOverlapMs);
|
||||
|
||||
/// Adds 'numsamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object.
|
||||
virtual void putSamples(
|
||||
const SAMPLETYPE *samples, ///< Input sample data
|
||||
uint numSamples ///< Number of samples in 'samples' so that one sample
|
||||
///< contains both channels if stereo
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Implementation-specific class declarations:
|
||||
|
||||
//#ifdef ALLOW_MMX
|
||||
// /// Class that implements MMX optimized routines for 16bit integer samples type.
|
||||
// class TDStretchMMX : public TDStretch
|
||||
// {
|
||||
// protected:
|
||||
// long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
|
||||
// virtual void overlapStereo(short *output, const short *input) const;
|
||||
// virtual void clearCrossCorrState();
|
||||
// };
|
||||
//#endif /// ALLOW_MMX
|
||||
//
|
||||
//
|
||||
//#ifdef ALLOW_3DNOW
|
||||
// /// Class that implements 3DNow! optimized routines for floating point samples type.
|
||||
// class TDStretch3DNow : public TDStretch
|
||||
// {
|
||||
// protected:
|
||||
// double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
|
||||
// };
|
||||
//#endif /// ALLOW_3DNOW
|
||||
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
/// Class that implements SSE optimized routines for floating point samples type.
|
||||
class TDStretchSSE : public TDStretch
|
||||
{
|
||||
protected:
|
||||
double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
|
||||
};
|
||||
|
||||
#endif /// ALLOW_SSE
|
||||
|
||||
}
|
||||
#endif /// TDStretch_H
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||
/// with several performance-increasing tweaks.
|
||||
///
|
||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.16 $
|
||||
//
|
||||
// $Id: TDStretch.h,v 1.16 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TDStretch_H
|
||||
#define TDStretch_H
|
||||
|
||||
#include "STTypes.h"
|
||||
#include "RateTransposer.h"
|
||||
#include "FIFOSamplePipe.h"
|
||||
|
||||
namespace soundtouch
|
||||
{
|
||||
|
||||
// Default values for sound processing parameters:
|
||||
|
||||
/// Default length of a single processing sequence, in milliseconds. This determines to how
|
||||
/// long sequences the original sound is chopped in the time-stretch algorithm.
|
||||
///
|
||||
/// The larger this value is, the lesser sequences are used in processing. In principle
|
||||
/// a bigger value sounds better when slowing down tempo, but worse when increasing tempo
|
||||
/// and vice versa.
|
||||
///
|
||||
/// Increasing this value reduces computational burden & vice versa.
|
||||
#define DEFAULT_SEQUENCE_MS 61
|
||||
|
||||
#define DEFAULT_SEEKWINDOW_MS 18
|
||||
|
||||
#define DEFAULT_OVERLAP_MS 7
|
||||
|
||||
|
||||
/// Class that does the time-stretch (tempo change) effect for the processed
|
||||
/// sound.
|
||||
class TDStretch : public FIFOProcessor
|
||||
{
|
||||
protected:
|
||||
uint channels;
|
||||
uint sampleReq;
|
||||
float tempo;
|
||||
|
||||
SAMPLETYPE *pMidBuffer;
|
||||
SAMPLETYPE *pRefMidBuffer;
|
||||
SAMPLETYPE *pRefMidBufferUnaligned;
|
||||
uint overlapLength;
|
||||
uint overlapDividerBits;
|
||||
uint slopingDivider;
|
||||
uint seekLength;
|
||||
uint seekWindowLength;
|
||||
uint maxOffset;
|
||||
float nominalSkip;
|
||||
float skipFract;
|
||||
FIFOSampleBuffer outputBuffer;
|
||||
FIFOSampleBuffer inputBuffer;
|
||||
BOOL bQuickseek;
|
||||
BOOL bMidBufferDirty;
|
||||
|
||||
uint sampleRate;
|
||||
uint sequenceMs;
|
||||
uint seekWindowMs;
|
||||
uint overlapMs;
|
||||
|
||||
void acceptNewOverlapLength(uint newOverlapLength);
|
||||
|
||||
virtual void clearCrossCorrState();
|
||||
void calculateOverlapLength(uint overlapMs);
|
||||
|
||||
virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
||||
virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
||||
|
||||
virtual uint seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
|
||||
virtual uint seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
|
||||
uint seekBestOverlapPosition(const SAMPLETYPE *refPos);
|
||||
|
||||
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
||||
virtual void overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
||||
|
||||
void clearMidBuffer();
|
||||
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
|
||||
|
||||
void precalcCorrReferenceMono();
|
||||
void precalcCorrReferenceStereo();
|
||||
|
||||
void processNominalTempo();
|
||||
|
||||
/// Changes the tempo of the given sound samples.
|
||||
/// Returns amount of samples returned in the "output" buffer.
|
||||
/// The maximum amount of samples that can be returned at a time is set by
|
||||
/// the 'set_returnBuffer_size' function.
|
||||
void processSamples();
|
||||
|
||||
public:
|
||||
TDStretch();
|
||||
virtual ~TDStretch();
|
||||
|
||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||
void *operator new(size_t s);
|
||||
|
||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
||||
/// This function automatically chooses a correct feature set depending on if the CPU
|
||||
/// supports MMX/SSE/etc extensions.
|
||||
static TDStretch *newInstance();
|
||||
|
||||
/// Returns the output buffer object
|
||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||
|
||||
/// Returns the input buffer object
|
||||
FIFOSamplePipe *getInput() { return &inputBuffer; };
|
||||
|
||||
/// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
||||
/// tempo, larger faster tempo.
|
||||
void setTempo(float newTempo);
|
||||
|
||||
/// Returns nonzero if there aren't any samples available for outputting.
|
||||
virtual void clear();
|
||||
|
||||
/// Clears the input buffer
|
||||
void clearInput();
|
||||
|
||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||
void setChannels(uint numChannels);
|
||||
|
||||
/// Enables/disables the quick position seeking algorithm. Zero to disable,
|
||||
/// nonzero to enable
|
||||
void enableQuickSeek(BOOL enable);
|
||||
|
||||
/// Returns nonzero if the quick seeking algorithm is enabled.
|
||||
BOOL isQuickSeekEnabled() const;
|
||||
|
||||
/// Sets routine control parameters. These control are certain time constants
|
||||
/// defining how the sound is stretched to the desired duration.
|
||||
//
|
||||
/// 'sampleRate' = sample rate of the sound
|
||||
/// 'sequenceMS' = one processing sequence length in milliseconds
|
||||
/// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
||||
/// position
|
||||
/// 'overlapMS' = overlapping length
|
||||
void setParameters(uint sampleRate, ///< Samplerate of sound being processed (Hz)
|
||||
uint sequenceMS = DEFAULT_SEQUENCE_MS, ///< Single processing sequence length (ms)
|
||||
uint seekwindowMS = DEFAULT_SEEKWINDOW_MS, ///< Offset seeking window length (ms)
|
||||
uint overlapMS = DEFAULT_OVERLAP_MS ///< Sequence overlapping length (ms)
|
||||
);
|
||||
|
||||
/// Get routine control parameters, see setParameters() function.
|
||||
/// Any of the parameters to this function can be NULL, in such case corresponding parameter
|
||||
/// value isn't returned.
|
||||
void getParameters(uint *pSampleRate, uint *pSequenceMs, uint *pSeekWindowMs, uint *pOverlapMs);
|
||||
|
||||
/// Adds 'numsamples' pcs of samples from the 'samples' memory position into
|
||||
/// the input of the object.
|
||||
virtual void putSamples(
|
||||
const SAMPLETYPE *samples, ///< Input sample data
|
||||
uint numSamples ///< Number of samples in 'samples' so that one sample
|
||||
///< contains both channels if stereo
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Implementation-specific class declarations:
|
||||
|
||||
//#ifdef ALLOW_MMX
|
||||
// /// Class that implements MMX optimized routines for 16bit integer samples type.
|
||||
// class TDStretchMMX : public TDStretch
|
||||
// {
|
||||
// protected:
|
||||
// long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
|
||||
// virtual void overlapStereo(short *output, const short *input) const;
|
||||
// virtual void clearCrossCorrState();
|
||||
// };
|
||||
//#endif /// ALLOW_MMX
|
||||
//
|
||||
//
|
||||
//#ifdef ALLOW_3DNOW
|
||||
// /// Class that implements 3DNow! optimized routines for floating point samples type.
|
||||
// class TDStretch3DNow : public TDStretch
|
||||
// {
|
||||
// protected:
|
||||
// double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
|
||||
// };
|
||||
//#endif /// ALLOW_3DNOW
|
||||
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
/// Class that implements SSE optimized routines for floating point samples type.
|
||||
class TDStretchSSE : public TDStretch
|
||||
{
|
||||
protected:
|
||||
double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
|
||||
};
|
||||
|
||||
#endif /// ALLOW_SSE
|
||||
|
||||
}
|
||||
#endif /// TDStretch_H
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,253 +1,253 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Classes for easy reading & writing of WAV sound files.
|
||||
///
|
||||
/// For big-endian CPU, define BIG_ENDIAN during compile-time to correctly
|
||||
/// parse the WAV files with such processors.
|
||||
///
|
||||
/// Admittingly, more complete WAV reader routines may exist in public domain, but
|
||||
/// the reason for 'yet another' one is that those generic WAV reader libraries are
|
||||
/// exhaustingly large and cumbersome! Wanted to have something simpler here, i.e.
|
||||
/// something that's not already larger than rest of the SoundTouch/SoundStretch program...
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.7 $
|
||||
//
|
||||
// $Id: WavFile.h,v 1.7 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for reading WAV audio files.
|
||||
class WavInFile
|
||||
{
|
||||
private:
|
||||
/// File pointer.
|
||||
FILE *fptr;
|
||||
|
||||
/// Counter of how many bytes of sample data have been read from the file.
|
||||
uint dataRead;
|
||||
|
||||
/// WAV header information
|
||||
WavHeader header;
|
||||
|
||||
/// Read WAV file headers.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int readWavHeaders();
|
||||
|
||||
/// Checks WAV file header tags.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int checkCharTags();
|
||||
|
||||
/// Reads a single WAV file header block.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int readHeaderBlock();
|
||||
|
||||
/// Reads WAV file 'riff' block
|
||||
int readRIFFBlock();
|
||||
|
||||
public:
|
||||
/// Constructor: Opens the given WAV file. If the file can't be opened,
|
||||
/// throws 'runtime_error' exception.
|
||||
WavInFile(const char *filename);
|
||||
|
||||
/// Destructor: Closes the file.
|
||||
~WavInFile();
|
||||
|
||||
/// Close the file. Notice that file is automatically closed also when the
|
||||
/// class instance is deleted.
|
||||
void close();
|
||||
|
||||
/// Rewind to beginning of the file
|
||||
void rewind();
|
||||
|
||||
/// Get sample rate.
|
||||
uint getSampleRate() const;
|
||||
|
||||
/// Get number of bits per sample, i.e. 8 or 16.
|
||||
uint getNumBits() const;
|
||||
|
||||
/// Get sample data size in bytes. Ahem, this should return same information as
|
||||
/// 'getBytesPerSample'...
|
||||
uint getDataSizeInBytes() const;
|
||||
|
||||
/// Get total number of samples in file.
|
||||
uint getNumSamples() const;
|
||||
|
||||
/// Get number of bytes per audio sample (e.g. 16bit stereo = 4 bytes/sample)
|
||||
uint getBytesPerSample() const;
|
||||
|
||||
/// Get number of audio channels in the file (1=mono, 2=stereo)
|
||||
uint getNumChannels() const;
|
||||
|
||||
/// Get the audio file length in milliseconds
|
||||
uint getLengthMS() const;
|
||||
|
||||
/// Reads audio samples from the WAV file. This routine works only for 8 bit samples.
|
||||
/// Reads given number of elements from the file or if end-of-file reached, as many
|
||||
/// elements as are left in the file.
|
||||
///
|
||||
/// \return Number of 8-bit integers read from the file.
|
||||
int read(char *buffer, int maxElems);
|
||||
|
||||
/// Reads audio samples from the WAV file to 16 bit integer format. Reads given number
|
||||
/// of elements from the file or if end-of-file reached, as many elements as are
|
||||
/// left in the file.
|
||||
///
|
||||
/// \return Number of 16-bit integers read from the file.
|
||||
int read(short *buffer, ///< Pointer to buffer where to read data.
|
||||
int maxElems ///< Size of 'buffer' array (number of array elements).
|
||||
);
|
||||
|
||||
/// Reads audio samples from the WAV file to floating point format, converting
|
||||
/// sample values to range [-1,1[. Reads given number of elements from the file
|
||||
/// or if end-of-file reached, as many elements as are left in the file.
|
||||
///
|
||||
/// \return Number of elements read from the file.
|
||||
int read(float *buffer, ///< Pointer to buffer where to read data.
|
||||
int maxElems ///< Size of 'buffer' array (number of array elements).
|
||||
);
|
||||
|
||||
/// Check end-of-file.
|
||||
///
|
||||
/// \return Nonzero if end-of-file reached.
|
||||
int eof() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. This function works only with 8bit samples.
|
||||
/// Throws a 'runtime_error' exception if writing to file fails.
|
||||
void write(const char *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Write data to WAV file in floating point format, saturating sample values to range
|
||||
/// [-1..+1[. Throws a 'runtime_error' exception if writing to file fails.
|
||||
void write(const float *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Finalize & close the WAV file. Automatically supplements the WAV file header
|
||||
/// information according to written data etc.
|
||||
///
|
||||
/// Notice that file is automatically closed also when the class instance is deleted.
|
||||
void close();
|
||||
};
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Classes for easy reading & writing of WAV sound files.
|
||||
///
|
||||
/// For big-endian CPU, define BIG_ENDIAN during compile-time to correctly
|
||||
/// parse the WAV files with such processors.
|
||||
///
|
||||
/// Admittingly, more complete WAV reader routines may exist in public domain, but
|
||||
/// the reason for 'yet another' one is that those generic WAV reader libraries are
|
||||
/// exhaustingly large and cumbersome! Wanted to have something simpler here, i.e.
|
||||
/// something that's not already larger than rest of the SoundTouch/SoundStretch program...
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.7 $
|
||||
//
|
||||
// $Id: WavFile.h,v 1.7 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef WAVFILE_H
|
||||
#define WAVFILE_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef uint
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
|
||||
|
||||
/// WAV audio file 'riff' section header
|
||||
typedef struct
|
||||
{
|
||||
char riff_char[4];
|
||||
int package_len;
|
||||
char wave[4];
|
||||
} WavRiff;
|
||||
|
||||
/// WAV audio file 'format' section header
|
||||
typedef struct
|
||||
{
|
||||
char fmt[4];
|
||||
int format_len;
|
||||
short fixed;
|
||||
short channel_number;
|
||||
int sample_rate;
|
||||
int byte_rate;
|
||||
short byte_per_sample;
|
||||
short bits_per_sample;
|
||||
} WavFormat;
|
||||
|
||||
/// WAV audio file 'data' section header
|
||||
typedef struct
|
||||
{
|
||||
char data_field[4];
|
||||
uint data_len;
|
||||
} WavData;
|
||||
|
||||
|
||||
/// WAV audio file header
|
||||
typedef struct
|
||||
{
|
||||
WavRiff riff;
|
||||
WavFormat format;
|
||||
WavData data;
|
||||
} WavHeader;
|
||||
|
||||
|
||||
/// Class for reading WAV audio files.
|
||||
class WavInFile
|
||||
{
|
||||
private:
|
||||
/// File pointer.
|
||||
FILE *fptr;
|
||||
|
||||
/// Counter of how many bytes of sample data have been read from the file.
|
||||
uint dataRead;
|
||||
|
||||
/// WAV header information
|
||||
WavHeader header;
|
||||
|
||||
/// Read WAV file headers.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int readWavHeaders();
|
||||
|
||||
/// Checks WAV file header tags.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int checkCharTags();
|
||||
|
||||
/// Reads a single WAV file header block.
|
||||
/// \return zero if all ok, nonzero if file format is invalid.
|
||||
int readHeaderBlock();
|
||||
|
||||
/// Reads WAV file 'riff' block
|
||||
int readRIFFBlock();
|
||||
|
||||
public:
|
||||
/// Constructor: Opens the given WAV file. If the file can't be opened,
|
||||
/// throws 'runtime_error' exception.
|
||||
WavInFile(const char *filename);
|
||||
|
||||
/// Destructor: Closes the file.
|
||||
~WavInFile();
|
||||
|
||||
/// Close the file. Notice that file is automatically closed also when the
|
||||
/// class instance is deleted.
|
||||
void close();
|
||||
|
||||
/// Rewind to beginning of the file
|
||||
void rewind();
|
||||
|
||||
/// Get sample rate.
|
||||
uint getSampleRate() const;
|
||||
|
||||
/// Get number of bits per sample, i.e. 8 or 16.
|
||||
uint getNumBits() const;
|
||||
|
||||
/// Get sample data size in bytes. Ahem, this should return same information as
|
||||
/// 'getBytesPerSample'...
|
||||
uint getDataSizeInBytes() const;
|
||||
|
||||
/// Get total number of samples in file.
|
||||
uint getNumSamples() const;
|
||||
|
||||
/// Get number of bytes per audio sample (e.g. 16bit stereo = 4 bytes/sample)
|
||||
uint getBytesPerSample() const;
|
||||
|
||||
/// Get number of audio channels in the file (1=mono, 2=stereo)
|
||||
uint getNumChannels() const;
|
||||
|
||||
/// Get the audio file length in milliseconds
|
||||
uint getLengthMS() const;
|
||||
|
||||
/// Reads audio samples from the WAV file. This routine works only for 8 bit samples.
|
||||
/// Reads given number of elements from the file or if end-of-file reached, as many
|
||||
/// elements as are left in the file.
|
||||
///
|
||||
/// \return Number of 8-bit integers read from the file.
|
||||
int read(char *buffer, int maxElems);
|
||||
|
||||
/// Reads audio samples from the WAV file to 16 bit integer format. Reads given number
|
||||
/// of elements from the file or if end-of-file reached, as many elements as are
|
||||
/// left in the file.
|
||||
///
|
||||
/// \return Number of 16-bit integers read from the file.
|
||||
int read(short *buffer, ///< Pointer to buffer where to read data.
|
||||
int maxElems ///< Size of 'buffer' array (number of array elements).
|
||||
);
|
||||
|
||||
/// Reads audio samples from the WAV file to floating point format, converting
|
||||
/// sample values to range [-1,1[. Reads given number of elements from the file
|
||||
/// or if end-of-file reached, as many elements as are left in the file.
|
||||
///
|
||||
/// \return Number of elements read from the file.
|
||||
int read(float *buffer, ///< Pointer to buffer where to read data.
|
||||
int maxElems ///< Size of 'buffer' array (number of array elements).
|
||||
);
|
||||
|
||||
/// Check end-of-file.
|
||||
///
|
||||
/// \return Nonzero if end-of-file reached.
|
||||
int eof() const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// Class for writing WAV audio files.
|
||||
class WavOutFile
|
||||
{
|
||||
private:
|
||||
/// Pointer to the WAV file
|
||||
FILE *fptr;
|
||||
|
||||
/// WAV file header data.
|
||||
WavHeader header;
|
||||
|
||||
/// Counter of how many bytes have been written to the file so far.
|
||||
int bytesWritten;
|
||||
|
||||
/// Fills in WAV file header information.
|
||||
void fillInHeader(const uint sampleRate, const uint bits, const uint channels);
|
||||
|
||||
/// Finishes the WAV file header by supplementing information of amount of
|
||||
/// data written to file etc
|
||||
void finishHeader();
|
||||
|
||||
/// Writes the WAV file header.
|
||||
void writeHeader();
|
||||
|
||||
public:
|
||||
/// Constructor: Creates a new WAV file. Throws a 'runtime_error' exception
|
||||
/// if file creation fails.
|
||||
WavOutFile(const char *fileName, ///< Filename
|
||||
int sampleRate, ///< Sample rate (e.g. 44100 etc)
|
||||
int bits, ///< Bits per sample (8 or 16 bits)
|
||||
int channels ///< Number of channels (1=mono, 2=stereo)
|
||||
);
|
||||
|
||||
/// Destructor: Finalizes & closes the WAV file.
|
||||
~WavOutFile();
|
||||
|
||||
/// Write data to WAV file. This function works only with 8bit samples.
|
||||
/// Throws a 'runtime_error' exception if writing to file fails.
|
||||
void write(const char *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Write data to WAV file. Throws a 'runtime_error' exception if writing to
|
||||
/// file fails.
|
||||
void write(const short *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Write data to WAV file in floating point format, saturating sample values to range
|
||||
/// [-1..+1[. Throws a 'runtime_error' exception if writing to file fails.
|
||||
void write(const float *buffer, ///< Pointer to sample data buffer.
|
||||
int numElems ///< How many array items are to be written to file.
|
||||
);
|
||||
|
||||
/// Finalize & close the WAV file. Automatically supplements the WAV file header
|
||||
/// information according to written data etc.
|
||||
///
|
||||
/// Notice that file is automatically closed also when the class instance is deleted.
|
||||
void close();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,62 +1,62 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A header file for detecting the Intel MMX instructions set extension.
|
||||
///
|
||||
/// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the
|
||||
/// routine implementations for x86 Windows, x86 gnu version and non-x86
|
||||
/// platforms, respectively.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.4 $
|
||||
//
|
||||
// $Id: cpu_detect.h,v 1.4 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CPU_DETECT_H_
|
||||
#define _CPU_DETECT_H_
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
#define SUPPORT_MMX 0x0001
|
||||
#define SUPPORT_3DNOW 0x0002
|
||||
#define SUPPORT_ALTIVEC 0x0004
|
||||
#define SUPPORT_SSE 0x0008
|
||||
#define SUPPORT_SSE2 0x0010
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
///
|
||||
/// \return A bitmask of supported extensions, see SUPPORT_... defines.
|
||||
uint detectCPUextensions(void);
|
||||
|
||||
/// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint wDisableMask);
|
||||
|
||||
#endif // _CPU_DETECT_H_
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// A header file for detecting the Intel MMX instructions set extension.
|
||||
///
|
||||
/// Please see 'mmx_win.cpp', 'mmx_cpp.cpp' and 'mmx_non_x86.cpp' for the
|
||||
/// routine implementations for x86 Windows, x86 gnu version and non-x86
|
||||
/// platforms, respectively.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.4 $
|
||||
//
|
||||
// $Id: cpu_detect.h,v 1.4 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _CPU_DETECT_H_
|
||||
#define _CPU_DETECT_H_
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
#define SUPPORT_MMX 0x0001
|
||||
#define SUPPORT_3DNOW 0x0002
|
||||
#define SUPPORT_ALTIVEC 0x0004
|
||||
#define SUPPORT_SSE 0x0008
|
||||
#define SUPPORT_SSE2 0x0010
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
///
|
||||
/// \return A bitmask of supported extensions, see SUPPORT_... defines.
|
||||
uint detectCPUextensions(void);
|
||||
|
||||
/// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint wDisableMask);
|
||||
|
||||
#endif // _CPU_DETECT_H_
|
||||
|
|
|
@ -1,138 +1,138 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// gcc version of the x86 CPU detect routine.
|
||||
///
|
||||
/// This file is to be compiled on any platform with the GNU C compiler.
|
||||
/// Compiler. Please see 'cpu_detect_x86_win.cpp' for the x86 Windows version
|
||||
/// of this file.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.6 $
|
||||
//
|
||||
// $Id: cpu_detect_x86_gcc.cpp,v 1.6 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "cpu_detect.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error wrong platform - this source code file is for the GNU C compiler.
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdio.h>
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// processor instructions extension detection routines
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Flag variable indicating whick ISA extensions are disabled (for debugging)
|
||||
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
|
||||
|
||||
// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint dwDisableMask)
|
||||
{
|
||||
_dwDisabledISA = dwDisableMask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
uint detectCPUextensions(void)
|
||||
{
|
||||
#ifndef __i386__
|
||||
return 0; // always disable extensions on non-x86 platforms.
|
||||
#else
|
||||
uint res = 0;
|
||||
|
||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||
|
||||
asm volatile(
|
||||
"\n\txor %%esi, %%esi" // clear %%esi = result register
|
||||
// check if 'cpuid' instructions is available by toggling eflags bit 21
|
||||
|
||||
"\n\tpushf" // save eflags to stack
|
||||
"\n\tpop %%eax" // load eax from stack (with eflags)
|
||||
"\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx
|
||||
"\n\txor $0x00200000, %%eax" // toggle bit 21
|
||||
"\n\tpush %%eax" // store toggled eflags to stack
|
||||
"\n\tpopf" // load eflags from stack
|
||||
"\n\tpushf" // save updated eflags to stack
|
||||
"\n\tpop %%eax" // load from stack
|
||||
"\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
|
||||
"\n\tcmp %%ecx, %%eax" // compare to original eflags values
|
||||
"\n\tjz end" // jumps to 'end' if cpuid not present
|
||||
|
||||
// cpuid instruction available, test for presence of mmx instructions
|
||||
|
||||
"\n\tmovl $1, %%eax"
|
||||
"\n\tcpuid"
|
||||
// movl $0x00800000, %edx // force enable MMX
|
||||
"\n\ttest $0x00800000, %%edx"
|
||||
"\n\tjz end" // branch if MMX not available
|
||||
|
||||
"\n\tor $0x01, %%esi" // otherwise add MMX support bit
|
||||
|
||||
"\n\ttest $0x02000000, %%edx"
|
||||
"\n\tjz test3DNow" // branch if SSE not available
|
||||
|
||||
"\n\tor $0x08, %%esi" // otherwise add SSE support bit
|
||||
|
||||
"\n\ttest3DNow:"
|
||||
// test for precense of AMD extensions
|
||||
"\n\tmov $0x80000000, %%eax"
|
||||
"\n\tcpuid"
|
||||
"\n\tcmp $0x80000000, %%eax"
|
||||
"\n\tjbe end" // branch if no AMD extensions detected
|
||||
|
||||
// test for precense of 3DNow! extension
|
||||
"\n\tmov $0x80000001, %%eax"
|
||||
"\n\tcpuid"
|
||||
"\n\ttest $0x80000000, %%edx"
|
||||
"\n\tjz end" // branch if 3DNow! not detected
|
||||
|
||||
"\n\tor $0x02, %%esi" // otherwise add 3DNow support bit
|
||||
|
||||
"\n\tend:"
|
||||
|
||||
"\n\tmov %%esi, %0"
|
||||
|
||||
: "=r" (res)
|
||||
: /* no inputs */
|
||||
: "%edx", "%eax", "%ecx", "%esi" );
|
||||
|
||||
return res & ~_dwDisabledISA;
|
||||
#endif
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// gcc version of the x86 CPU detect routine.
|
||||
///
|
||||
/// This file is to be compiled on any platform with the GNU C compiler.
|
||||
/// Compiler. Please see 'cpu_detect_x86_win.cpp' for the x86 Windows version
|
||||
/// of this file.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.6 $
|
||||
//
|
||||
// $Id: cpu_detect_x86_gcc.cpp,v 1.6 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include "cpu_detect.h"
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error wrong platform - this source code file is for the GNU C compiler.
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdio.h>
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// processor instructions extension detection routines
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// Flag variable indicating whick ISA extensions are disabled (for debugging)
|
||||
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
|
||||
|
||||
// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint dwDisableMask)
|
||||
{
|
||||
_dwDisabledISA = dwDisableMask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
uint detectCPUextensions(void)
|
||||
{
|
||||
#ifndef __i386__
|
||||
return 0; // always disable extensions on non-x86 platforms.
|
||||
#else
|
||||
uint res = 0;
|
||||
|
||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||
|
||||
asm volatile(
|
||||
"\n\txor %%esi, %%esi" // clear %%esi = result register
|
||||
// check if 'cpuid' instructions is available by toggling eflags bit 21
|
||||
|
||||
"\n\tpushf" // save eflags to stack
|
||||
"\n\tpop %%eax" // load eax from stack (with eflags)
|
||||
"\n\tmovl %%eax, %%ecx" // save the original eflags values to ecx
|
||||
"\n\txor $0x00200000, %%eax" // toggle bit 21
|
||||
"\n\tpush %%eax" // store toggled eflags to stack
|
||||
"\n\tpopf" // load eflags from stack
|
||||
"\n\tpushf" // save updated eflags to stack
|
||||
"\n\tpop %%eax" // load from stack
|
||||
"\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
|
||||
"\n\tcmp %%ecx, %%eax" // compare to original eflags values
|
||||
"\n\tjz end" // jumps to 'end' if cpuid not present
|
||||
|
||||
// cpuid instruction available, test for presence of mmx instructions
|
||||
|
||||
"\n\tmovl $1, %%eax"
|
||||
"\n\tcpuid"
|
||||
// movl $0x00800000, %edx // force enable MMX
|
||||
"\n\ttest $0x00800000, %%edx"
|
||||
"\n\tjz end" // branch if MMX not available
|
||||
|
||||
"\n\tor $0x01, %%esi" // otherwise add MMX support bit
|
||||
|
||||
"\n\ttest $0x02000000, %%edx"
|
||||
"\n\tjz test3DNow" // branch if SSE not available
|
||||
|
||||
"\n\tor $0x08, %%esi" // otherwise add SSE support bit
|
||||
|
||||
"\n\ttest3DNow:"
|
||||
// test for precense of AMD extensions
|
||||
"\n\tmov $0x80000000, %%eax"
|
||||
"\n\tcpuid"
|
||||
"\n\tcmp $0x80000000, %%eax"
|
||||
"\n\tjbe end" // branch if no AMD extensions detected
|
||||
|
||||
// test for precense of 3DNow! extension
|
||||
"\n\tmov $0x80000001, %%eax"
|
||||
"\n\tcpuid"
|
||||
"\n\ttest $0x80000000, %%edx"
|
||||
"\n\tjz end" // branch if 3DNow! not detected
|
||||
|
||||
"\n\tor $0x02, %%esi" // otherwise add 3DNow support bit
|
||||
|
||||
"\n\tend:"
|
||||
|
||||
"\n\tmov %%esi, %0"
|
||||
|
||||
: "=r" (res)
|
||||
: /* no inputs */
|
||||
: "%edx", "%eax", "%ecx", "%esi" );
|
||||
|
||||
return res & ~_dwDisabledISA;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,126 +1,126 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Win32 version of the x86 CPU detect routine.
|
||||
///
|
||||
/// This file is to be compiled in Windows platform with Microsoft Visual C++
|
||||
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
|
||||
/// for all GNU platforms.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: cpu_detect_x86_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#error wrong platform - this source code file is exclusively for Win32 platform
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// processor instructions extension detection routines
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Flag variable indicating whick ISA extensions are disabled (for debugging)
|
||||
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
|
||||
|
||||
|
||||
// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint dwDisableMask)
|
||||
{
|
||||
_dwDisabledISA = dwDisableMask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
uint detectCPUextensions(void)
|
||||
{
|
||||
uint res = 0;
|
||||
|
||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||
|
||||
_asm
|
||||
{
|
||||
; check if 'cpuid' instructions is available by toggling eflags bit 21
|
||||
;
|
||||
xor esi, esi ; clear esi = result register
|
||||
|
||||
pushfd ; save eflags to stack
|
||||
pop eax ; load eax from stack (with eflags)
|
||||
mov ecx, eax ; save the original eflags values to ecx
|
||||
xor eax, 0x00200000 ; toggle bit 21
|
||||
push eax ; store toggled eflags to stack
|
||||
popfd ; load eflags from stack
|
||||
pushfd ; save updated eflags to stack
|
||||
pop eax ; load from stack
|
||||
xor edx, edx ; clear edx for defaulting no mmx
|
||||
cmp eax, ecx ; compare to original eflags values
|
||||
jz end ; jumps to 'end' if cpuid not present
|
||||
|
||||
; cpuid instruction available, test for presence of mmx instructions
|
||||
mov eax, 1
|
||||
cpuid
|
||||
test edx, 0x00800000
|
||||
jz end ; branch if MMX not available
|
||||
|
||||
or esi, SUPPORT_MMX ; otherwise add MMX support bit
|
||||
|
||||
test edx, 0x02000000
|
||||
jz test3DNow ; branch if SSE not available
|
||||
|
||||
or esi, SUPPORT_SSE ; otherwise add SSE support bit
|
||||
|
||||
test3DNow:
|
||||
; test for precense of AMD extensions
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000000
|
||||
jbe end ; branch if no AMD extensions detected
|
||||
|
||||
; test for precense of 3DNow! extension
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
test edx, 0x80000000
|
||||
jz end ; branch if 3DNow! not detected
|
||||
|
||||
or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit
|
||||
|
||||
end:
|
||||
|
||||
mov res, esi
|
||||
}
|
||||
|
||||
return res & ~_dwDisabledISA;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// Win32 version of the x86 CPU detect routine.
|
||||
///
|
||||
/// This file is to be compiled in Windows platform with Microsoft Visual C++
|
||||
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
|
||||
/// for all GNU platforms.
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.10 $
|
||||
//
|
||||
// $Id: cpu_detect_x86_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#error wrong platform - this source code file is exclusively for Win32 platform
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// processor instructions extension detection routines
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Flag variable indicating whick ISA extensions are disabled (for debugging)
|
||||
static uint _dwDisabledISA = 0x00; // 0xffffffff; //<- use this to disable all extensions
|
||||
|
||||
|
||||
// Disables given set of instruction extensions. See SUPPORT_... defines.
|
||||
void disableExtensions(uint dwDisableMask)
|
||||
{
|
||||
_dwDisabledISA = dwDisableMask;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Checks which instruction set extensions are supported by the CPU.
|
||||
uint detectCPUextensions(void)
|
||||
{
|
||||
uint res = 0;
|
||||
|
||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||
|
||||
_asm
|
||||
{
|
||||
; check if 'cpuid' instructions is available by toggling eflags bit 21
|
||||
;
|
||||
xor esi, esi ; clear esi = result register
|
||||
|
||||
pushfd ; save eflags to stack
|
||||
pop eax ; load eax from stack (with eflags)
|
||||
mov ecx, eax ; save the original eflags values to ecx
|
||||
xor eax, 0x00200000 ; toggle bit 21
|
||||
push eax ; store toggled eflags to stack
|
||||
popfd ; load eflags from stack
|
||||
pushfd ; save updated eflags to stack
|
||||
pop eax ; load from stack
|
||||
xor edx, edx ; clear edx for defaulting no mmx
|
||||
cmp eax, ecx ; compare to original eflags values
|
||||
jz end ; jumps to 'end' if cpuid not present
|
||||
|
||||
; cpuid instruction available, test for presence of mmx instructions
|
||||
mov eax, 1
|
||||
cpuid
|
||||
test edx, 0x00800000
|
||||
jz end ; branch if MMX not available
|
||||
|
||||
or esi, SUPPORT_MMX ; otherwise add MMX support bit
|
||||
|
||||
test edx, 0x02000000
|
||||
jz test3DNow ; branch if SSE not available
|
||||
|
||||
or esi, SUPPORT_SSE ; otherwise add SSE support bit
|
||||
|
||||
test3DNow:
|
||||
; test for precense of AMD extensions
|
||||
mov eax, 0x80000000
|
||||
cpuid
|
||||
cmp eax, 0x80000000
|
||||
jbe end ; branch if no AMD extensions detected
|
||||
|
||||
; test for precense of 3DNow! extension
|
||||
mov eax, 0x80000001
|
||||
cpuid
|
||||
test edx, 0x80000000
|
||||
jz end ; branch if 3DNow! not detected
|
||||
|
||||
or esi, SUPPORT_3DNOW ; otherwise add 3DNow support bit
|
||||
|
||||
end:
|
||||
|
||||
mov res, esi
|
||||
}
|
||||
|
||||
return res & ~_dwDisabledISA;
|
||||
}
|
||||
|
|
|
@ -1,305 +1,305 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// MMX optimized routines. All MMX optimized functions have been gathered into
|
||||
/// this single source code file, regardless to their class or original source
|
||||
/// code file, in order to ease porting the library to other compiler and
|
||||
/// processor platforms.
|
||||
///
|
||||
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
|
||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||
/// should compile with both toolsets.
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
|
||||
/// is available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/06 18:52:43 $
|
||||
// File revision : $Revision: 1.1 $
|
||||
//
|
||||
// $Id: mmx_optimized.cpp,v 1.1 2006/02/06 18:52:43 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
// MMX routines available only with integer sample type
|
||||
|
||||
#if !(_WIN32 || __i386__ || __x86_64__)
|
||||
#error "wrong platform - this source code file is exclusively for x86 platforms"
|
||||
#endif
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of MMX optimized functions of class 'TDStretchMMX'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <mmintrin.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const
|
||||
{
|
||||
const __m64 *pVec1, *pVec2;
|
||||
__m64 shifter;
|
||||
__m64 accu;
|
||||
long corr;
|
||||
uint i;
|
||||
|
||||
pVec1 = (__m64*)pV1;
|
||||
pVec2 = (__m64*)pV2;
|
||||
|
||||
shifter = _m_from_int(overlapDividerBits);
|
||||
accu = _mm_setzero_si64();
|
||||
|
||||
// Process 4 parallel sets of 2 * stereo samples each during each
|
||||
// round to improve CPU-level parallellization.
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
__m64 temp;
|
||||
|
||||
// dictionary of instructions:
|
||||
// _m_pmaddwd : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
|
||||
// _mm_add_pi32 : 2*32bit add
|
||||
// _m_psrad : 32bit right-shift
|
||||
|
||||
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]),
|
||||
_mm_madd_pi16(pVec1[1], pVec2[1]));
|
||||
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
|
||||
|
||||
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]),
|
||||
_mm_madd_pi16(pVec1[3], pVec2[3]));
|
||||
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
|
||||
|
||||
pVec1 += 4;
|
||||
pVec2 += 4;
|
||||
}
|
||||
|
||||
// copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
|
||||
// and finally store the result into the variable "corr"
|
||||
|
||||
accu = _mm_add_pi32(accu, _mm_srli_si64(accu, 32));
|
||||
corr = _m_to_int(accu);
|
||||
|
||||
// Clear MMS state
|
||||
_m_empty();
|
||||
|
||||
return corr;
|
||||
// Note: Warning about the missing EMMS instruction is harmless
|
||||
// as it'll be called elsewhere.
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TDStretchMMX::clearCrossCorrState()
|
||||
{
|
||||
// Clear MMS state
|
||||
_m_empty();
|
||||
//_asm EMMS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MMX-optimized version of the function overlapStereo
|
||||
void TDStretchMMX::overlapStereo(short *output, const short *input) const
|
||||
{
|
||||
const __m64 *pVinput, *pVMidBuf;
|
||||
__m64 *pVdest;
|
||||
__m64 mix1, mix2, adder, shifter;
|
||||
uint i;
|
||||
|
||||
pVinput = (const __m64*)input;
|
||||
pVMidBuf = (const __m64*)pMidBuffer;
|
||||
pVdest = (__m64*)output;
|
||||
|
||||
// mix1 = mixer values for 1st stereo sample
|
||||
// mix1 = mixer values for 2nd stereo sample
|
||||
// adder = adder for updating mixer values after each round
|
||||
|
||||
mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
|
||||
adder = _mm_set_pi16(1, -1, 1, -1);
|
||||
mix2 = _mm_add_pi16(mix1, adder);
|
||||
adder = _mm_add_pi16(adder, adder);
|
||||
|
||||
shifter = _m_from_int(overlapDividerBits);
|
||||
|
||||
for (i = 0; i < overlapLength / 4; i ++)
|
||||
{
|
||||
__m64 temp1, temp2;
|
||||
|
||||
// load & shuffle data so that input & mixbuffer data samples are paired
|
||||
temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
|
||||
temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
|
||||
|
||||
// temp = (temp .* mix) >> shifter
|
||||
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
|
||||
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
|
||||
pVdest[0] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
|
||||
|
||||
// update mix += adder
|
||||
mix1 = _mm_add_pi16(mix1, adder);
|
||||
mix2 = _mm_add_pi16(mix2, adder);
|
||||
|
||||
// --- second round begins here ---
|
||||
|
||||
// load & shuffle data so that input & mixbuffer data samples are paired
|
||||
temp1 = _mm_unpacklo_pi16(pVMidBuf[1], pVinput[1]); // = i2l m2l i2r m2r
|
||||
temp2 = _mm_unpackhi_pi16(pVMidBuf[1], pVinput[1]); // = i3l m3l i3r m3r
|
||||
|
||||
// temp = (temp .* mix) >> shifter
|
||||
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
|
||||
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
|
||||
pVdest[1] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
|
||||
|
||||
// update mix += adder
|
||||
mix1 = _mm_add_pi16(mix1, adder);
|
||||
mix2 = _mm_add_pi16(mix2, adder);
|
||||
|
||||
pVinput += 2;
|
||||
pVMidBuf += 2;
|
||||
pVdest += 2;
|
||||
}
|
||||
|
||||
_m_empty(); // clear MMS state
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of MMX optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
|
||||
FIRFilterMMX::FIRFilterMMX() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilterMMX::~FIRFilterMMX()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for MMX routine
|
||||
void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new short[2 * newLength + 8];
|
||||
filterCoeffsAlign = (short *)(((ulongptr)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0;i < length; i += 4)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
|
||||
filterCoeffsAlign[2 * i + 2] = coeffs[i + 0];
|
||||
filterCoeffsAlign[2 * i + 3] = coeffs[i + 2];
|
||||
|
||||
filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];
|
||||
filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];
|
||||
filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];
|
||||
filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// mmx-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, const uint numSamples) const
|
||||
{
|
||||
// Create stack copies of the needed member variables for asm routines :
|
||||
uint i, j;
|
||||
__m64 *pVdest = (__m64*)dest;
|
||||
|
||||
if (length < 2) return 0;
|
||||
|
||||
for (i = 0; i < numSamples / 2; i ++)
|
||||
{
|
||||
__m64 accu1;
|
||||
__m64 accu2;
|
||||
const __m64 *pVsrc = (const __m64*)src;
|
||||
const __m64 *pVfilter = (const __m64*)filterCoeffsAlign;
|
||||
|
||||
accu1 = accu2 = _mm_setzero_si64();
|
||||
for (j = 0; j < lengthDiv8 * 2; j ++)
|
||||
{
|
||||
__m64 temp1, temp2;
|
||||
|
||||
temp1 = _mm_unpacklo_pi16(pVsrc[0], pVsrc[1]); // = l2 l0 r2 r0
|
||||
temp2 = _mm_unpackhi_pi16(pVsrc[0], pVsrc[1]); // = l3 l1 r3 r1
|
||||
|
||||
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp1, pVfilter[0])); // += l2*f2+l0*f0 r2*f2+r0*f0
|
||||
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp2, pVfilter[1])); // += l3*f3+l1*f1 r3*f3+r1*f1
|
||||
|
||||
temp1 = _mm_unpacklo_pi16(pVsrc[1], pVsrc[2]); // = l4 l2 r4 r2
|
||||
|
||||
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp2, pVfilter[0])); // += l3*f2+l1*f0 r3*f2+r1*f0
|
||||
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp1, pVfilter[1])); // += l4*f3+l2*f1 r4*f3+r2*f1
|
||||
|
||||
// accu1 += l2*f2+l0*f0 r2*f2+r0*f0
|
||||
// += l3*f3+l1*f1 r3*f3+r1*f1
|
||||
|
||||
// accu2 += l3*f2+l1*f0 r3*f2+r1*f0
|
||||
// l4*f3+l2*f1 r4*f3+r2*f1
|
||||
|
||||
pVfilter += 2;
|
||||
pVsrc += 2;
|
||||
}
|
||||
// accu >>= resultDivFactor
|
||||
accu1 = _mm_srai_pi32(accu1, resultDivFactor);
|
||||
accu2 = _mm_srai_pi32(accu2, resultDivFactor);
|
||||
|
||||
// pack 2*2*32bits => 4*16 bits
|
||||
pVdest[0] = _mm_packs_pi32(accu1, accu2);
|
||||
src += 4;
|
||||
pVdest ++;
|
||||
}
|
||||
|
||||
_m_empty(); // clear emms state
|
||||
|
||||
return (numSamples & 0xfffffffe) - length;
|
||||
}
|
||||
|
||||
#endif // ALLOW_MMX
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// MMX optimized routines. All MMX optimized functions have been gathered into
|
||||
/// this single source code file, regardless to their class or original source
|
||||
/// code file, in order to ease porting the library to other compiler and
|
||||
/// processor platforms.
|
||||
///
|
||||
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
|
||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||
/// should compile with both toolsets.
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
|
||||
/// is available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/06 18:52:43 $
|
||||
// File revision : $Revision: 1.1 $
|
||||
//
|
||||
// $Id: mmx_optimized.cpp,v 1.1 2006/02/06 18:52:43 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "STTypes.h"
|
||||
|
||||
#ifdef ALLOW_MMX
|
||||
// MMX routines available only with integer sample type
|
||||
|
||||
#if !(_WIN32 || __i386__ || __x86_64__)
|
||||
#error "wrong platform - this source code file is exclusively for x86 platforms"
|
||||
#endif
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of MMX optimized functions of class 'TDStretchMMX'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <mmintrin.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const
|
||||
{
|
||||
const __m64 *pVec1, *pVec2;
|
||||
__m64 shifter;
|
||||
__m64 accu;
|
||||
long corr;
|
||||
uint i;
|
||||
|
||||
pVec1 = (__m64*)pV1;
|
||||
pVec2 = (__m64*)pV2;
|
||||
|
||||
shifter = _m_from_int(overlapDividerBits);
|
||||
accu = _mm_setzero_si64();
|
||||
|
||||
// Process 4 parallel sets of 2 * stereo samples each during each
|
||||
// round to improve CPU-level parallellization.
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
__m64 temp;
|
||||
|
||||
// dictionary of instructions:
|
||||
// _m_pmaddwd : 4*16bit multiply-add, resulting two 32bits = [a0*b0+a1*b1 ; a2*b2+a3*b3]
|
||||
// _mm_add_pi32 : 2*32bit add
|
||||
// _m_psrad : 32bit right-shift
|
||||
|
||||
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[0], pVec2[0]),
|
||||
_mm_madd_pi16(pVec1[1], pVec2[1]));
|
||||
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
|
||||
|
||||
temp = _mm_add_pi32(_mm_madd_pi16(pVec1[2], pVec2[2]),
|
||||
_mm_madd_pi16(pVec1[3], pVec2[3]));
|
||||
accu = _mm_add_pi32(accu, _mm_sra_pi32(temp, shifter));
|
||||
|
||||
pVec1 += 4;
|
||||
pVec2 += 4;
|
||||
}
|
||||
|
||||
// copy hi-dword of mm0 to lo-dword of mm1, then sum mmo+mm1
|
||||
// and finally store the result into the variable "corr"
|
||||
|
||||
accu = _mm_add_pi32(accu, _mm_srli_si64(accu, 32));
|
||||
corr = _m_to_int(accu);
|
||||
|
||||
// Clear MMS state
|
||||
_m_empty();
|
||||
|
||||
return corr;
|
||||
// Note: Warning about the missing EMMS instruction is harmless
|
||||
// as it'll be called elsewhere.
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TDStretchMMX::clearCrossCorrState()
|
||||
{
|
||||
// Clear MMS state
|
||||
_m_empty();
|
||||
//_asm EMMS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MMX-optimized version of the function overlapStereo
|
||||
void TDStretchMMX::overlapStereo(short *output, const short *input) const
|
||||
{
|
||||
const __m64 *pVinput, *pVMidBuf;
|
||||
__m64 *pVdest;
|
||||
__m64 mix1, mix2, adder, shifter;
|
||||
uint i;
|
||||
|
||||
pVinput = (const __m64*)input;
|
||||
pVMidBuf = (const __m64*)pMidBuffer;
|
||||
pVdest = (__m64*)output;
|
||||
|
||||
// mix1 = mixer values for 1st stereo sample
|
||||
// mix1 = mixer values for 2nd stereo sample
|
||||
// adder = adder for updating mixer values after each round
|
||||
|
||||
mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
|
||||
adder = _mm_set_pi16(1, -1, 1, -1);
|
||||
mix2 = _mm_add_pi16(mix1, adder);
|
||||
adder = _mm_add_pi16(adder, adder);
|
||||
|
||||
shifter = _m_from_int(overlapDividerBits);
|
||||
|
||||
for (i = 0; i < overlapLength / 4; i ++)
|
||||
{
|
||||
__m64 temp1, temp2;
|
||||
|
||||
// load & shuffle data so that input & mixbuffer data samples are paired
|
||||
temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
|
||||
temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
|
||||
|
||||
// temp = (temp .* mix) >> shifter
|
||||
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
|
||||
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
|
||||
pVdest[0] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
|
||||
|
||||
// update mix += adder
|
||||
mix1 = _mm_add_pi16(mix1, adder);
|
||||
mix2 = _mm_add_pi16(mix2, adder);
|
||||
|
||||
// --- second round begins here ---
|
||||
|
||||
// load & shuffle data so that input & mixbuffer data samples are paired
|
||||
temp1 = _mm_unpacklo_pi16(pVMidBuf[1], pVinput[1]); // = i2l m2l i2r m2r
|
||||
temp2 = _mm_unpackhi_pi16(pVMidBuf[1], pVinput[1]); // = i3l m3l i3r m3r
|
||||
|
||||
// temp = (temp .* mix) >> shifter
|
||||
temp1 = _mm_sra_pi32(_mm_madd_pi16(temp1, mix1), shifter);
|
||||
temp2 = _mm_sra_pi32(_mm_madd_pi16(temp2, mix2), shifter);
|
||||
pVdest[1] = _mm_packs_pi32(temp1, temp2); // pack 2*2*32bit => 4*16bit
|
||||
|
||||
// update mix += adder
|
||||
mix1 = _mm_add_pi16(mix1, adder);
|
||||
mix2 = _mm_add_pi16(mix2, adder);
|
||||
|
||||
pVinput += 2;
|
||||
pVMidBuf += 2;
|
||||
pVdest += 2;
|
||||
}
|
||||
|
||||
_m_empty(); // clear MMS state
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of MMX optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
|
||||
FIRFilterMMX::FIRFilterMMX() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilterMMX::~FIRFilterMMX()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for MMX routine
|
||||
void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new short[2 * newLength + 8];
|
||||
filterCoeffsAlign = (short *)(((ulongptr)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0;i < length; i += 4)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
|
||||
filterCoeffsAlign[2 * i + 2] = coeffs[i + 0];
|
||||
filterCoeffsAlign[2 * i + 3] = coeffs[i + 2];
|
||||
|
||||
filterCoeffsAlign[2 * i + 4] = coeffs[i + 1];
|
||||
filterCoeffsAlign[2 * i + 5] = coeffs[i + 3];
|
||||
filterCoeffsAlign[2 * i + 6] = coeffs[i + 1];
|
||||
filterCoeffsAlign[2 * i + 7] = coeffs[i + 3];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// mmx-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, const uint numSamples) const
|
||||
{
|
||||
// Create stack copies of the needed member variables for asm routines :
|
||||
uint i, j;
|
||||
__m64 *pVdest = (__m64*)dest;
|
||||
|
||||
if (length < 2) return 0;
|
||||
|
||||
for (i = 0; i < numSamples / 2; i ++)
|
||||
{
|
||||
__m64 accu1;
|
||||
__m64 accu2;
|
||||
const __m64 *pVsrc = (const __m64*)src;
|
||||
const __m64 *pVfilter = (const __m64*)filterCoeffsAlign;
|
||||
|
||||
accu1 = accu2 = _mm_setzero_si64();
|
||||
for (j = 0; j < lengthDiv8 * 2; j ++)
|
||||
{
|
||||
__m64 temp1, temp2;
|
||||
|
||||
temp1 = _mm_unpacklo_pi16(pVsrc[0], pVsrc[1]); // = l2 l0 r2 r0
|
||||
temp2 = _mm_unpackhi_pi16(pVsrc[0], pVsrc[1]); // = l3 l1 r3 r1
|
||||
|
||||
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp1, pVfilter[0])); // += l2*f2+l0*f0 r2*f2+r0*f0
|
||||
accu1 = _mm_add_pi32(accu1, _mm_madd_pi16(temp2, pVfilter[1])); // += l3*f3+l1*f1 r3*f3+r1*f1
|
||||
|
||||
temp1 = _mm_unpacklo_pi16(pVsrc[1], pVsrc[2]); // = l4 l2 r4 r2
|
||||
|
||||
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp2, pVfilter[0])); // += l3*f2+l1*f0 r3*f2+r1*f0
|
||||
accu2 = _mm_add_pi32(accu2, _mm_madd_pi16(temp1, pVfilter[1])); // += l4*f3+l2*f1 r4*f3+r2*f1
|
||||
|
||||
// accu1 += l2*f2+l0*f0 r2*f2+r0*f0
|
||||
// += l3*f3+l1*f1 r3*f3+r1*f1
|
||||
|
||||
// accu2 += l3*f2+l1*f0 r3*f2+r1*f0
|
||||
// l4*f3+l2*f1 r4*f3+r2*f1
|
||||
|
||||
pVfilter += 2;
|
||||
pVsrc += 2;
|
||||
}
|
||||
// accu >>= resultDivFactor
|
||||
accu1 = _mm_srai_pi32(accu1, resultDivFactor);
|
||||
accu2 = _mm_srai_pi32(accu2, resultDivFactor);
|
||||
|
||||
// pack 2*2*32bits => 4*16 bits
|
||||
pVdest[0] = _mm_packs_pi32(accu1, accu2);
|
||||
src += 4;
|
||||
pVdest ++;
|
||||
}
|
||||
|
||||
_m_empty(); // clear emms state
|
||||
|
||||
return (numSamples & 0xfffffffe) - length;
|
||||
}
|
||||
|
||||
#endif // ALLOW_MMX
|
||||
|
|
|
@ -1,484 +1,484 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE
|
||||
/// optimized functions have been gathered into this single source
|
||||
/// code file, regardless to their class or original source code file, in order
|
||||
/// to ease porting the library to other compiler and processor platforms.
|
||||
///
|
||||
/// The SSE-optimizations are programmed using SSE compiler intrinsics that
|
||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||
/// should compile with both toolsets.
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support SSE instruction set. The update is
|
||||
/// available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
||||
/// perform a search with keywords "processor pack".
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.2 $
|
||||
//
|
||||
// $Id: sse_optimized.cpp,v 1.2 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
|
||||
// SSE routines available only with float sample type
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of SSE optimized functions of class 'TDStretchSSE'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const
|
||||
{
|
||||
uint i;
|
||||
__m128 vSum, *pVec2;
|
||||
|
||||
// Note. It means a major slow-down if the routine needs to tolerate
|
||||
// unaligned __m128 memory accesses. It's way faster if we can skip
|
||||
// unaligned slots and use _mm_load_ps instruction instead of _mm_loadu_ps.
|
||||
// This can mean up to ~ 10-fold difference (incl. part of which is
|
||||
// due to skipping every second round for stereo sound though).
|
||||
//
|
||||
// Compile-time define ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
|
||||
// for choosing if this little cheating is allowed.
|
||||
|
||||
#ifdef ALLOW_NONEXACT_SIMD_OPTIMIZATION
|
||||
// Little cheating allowed, return valid correlation only for
|
||||
// aligned locations, meaning every second round for stereo sound.
|
||||
|
||||
#define _MM_LOAD _mm_load_ps
|
||||
|
||||
if (((ulong)pV1) & 15) return -1e50; // skip unaligned locations
|
||||
|
||||
#else
|
||||
// No cheating allowed, use unaligned load & take the resulting
|
||||
// performance hit.
|
||||
#define _MM_LOAD _mm_loadu_ps
|
||||
#endif
|
||||
|
||||
// ensure overlapLength is divisible by 8
|
||||
assert((overlapLength % 8) == 0);
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
// Note: pV2 _must_ be aligned to 16-bit boundary, pV1 need not.
|
||||
pVec2 = (__m128*)pV2;
|
||||
vSum = _mm_setzero_ps();
|
||||
|
||||
// Unroll the loop by factor of 4 * 4 operations
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
// vSum += pV1[0..3] * pV2[0..3]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1),pVec2[0]));
|
||||
|
||||
// vSum += pV1[4..7] * pV2[4..7]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 4), pVec2[1]));
|
||||
|
||||
// vSum += pV1[8..11] * pV2[8..11]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 8), pVec2[2]));
|
||||
|
||||
// vSum += pV1[12..15] * pV2[12..15]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 12), pVec2[3]));
|
||||
|
||||
pV1 += 16;
|
||||
pVec2 += 4;
|
||||
}
|
||||
|
||||
// return value = vSum[0] + vSum[1] + vSum[2] + vSum[3]
|
||||
float *pvSum = (float*)&vSum;
|
||||
return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]);
|
||||
|
||||
/* This is approximately corresponding routine in C-language:
|
||||
double corr;
|
||||
uint i;
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
corr = 0.0;
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
corr += pV1[0] * pV2[0] +
|
||||
pV1[1] * pV2[1] +
|
||||
pV1[2] * pV2[2] +
|
||||
pV1[3] * pV2[3] +
|
||||
pV1[4] * pV2[4] +
|
||||
pV1[5] * pV2[5] +
|
||||
pV1[6] * pV2[6] +
|
||||
pV1[7] * pV2[7] +
|
||||
pV1[8] * pV2[8] +
|
||||
pV1[9] * pV2[9] +
|
||||
pV1[10] * pV2[10] +
|
||||
pV1[11] * pV2[11] +
|
||||
pV1[12] * pV2[12] +
|
||||
pV1[13] * pV2[13] +
|
||||
pV1[14] * pV2[14] +
|
||||
pV1[15] * pV2[15];
|
||||
|
||||
pV1 += 16;
|
||||
pV2 += 16;
|
||||
}
|
||||
*/
|
||||
|
||||
/* This is corresponding routine in assembler. This may be teeny-weeny bit faster
|
||||
than intrinsic version, but more difficult to maintain & get compiled on multiple
|
||||
platforms.
|
||||
|
||||
uint overlapLengthLocal = overlapLength;
|
||||
float corr;
|
||||
|
||||
_asm
|
||||
{
|
||||
// Very important note: data in 'pV2' _must_ be aligned to
|
||||
// 16-byte boundary!
|
||||
|
||||
// give prefetch hints to CPU of what data are to be needed soonish
|
||||
// give more aggressive hints on pV1 as that changes while pV2 stays
|
||||
// same between runs
|
||||
prefetcht0 [pV1]
|
||||
prefetcht0 [pV2]
|
||||
prefetcht0 [pV1 + 32]
|
||||
|
||||
mov eax, dword ptr pV1
|
||||
mov ebx, dword ptr pV2
|
||||
|
||||
xorps xmm0, xmm0
|
||||
|
||||
mov ecx, overlapLengthLocal
|
||||
shr ecx, 3 // div by eight
|
||||
|
||||
loop1:
|
||||
prefetcht0 [eax + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [ebx + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
movups xmm1, [eax]
|
||||
mulps xmm1, [ebx]
|
||||
addps xmm0, xmm1
|
||||
|
||||
movups xmm2, [eax + 16]
|
||||
mulps xmm2, [ebx + 16]
|
||||
addps xmm0, xmm2
|
||||
|
||||
prefetcht0 [eax + 96] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm3, [eax + 32]
|
||||
mulps xmm3, [ebx + 32]
|
||||
addps xmm0, xmm3
|
||||
|
||||
movups xmm4, [eax + 48]
|
||||
mulps xmm4, [ebx + 48]
|
||||
addps xmm0, xmm4
|
||||
|
||||
add eax, 64
|
||||
add ebx, 64
|
||||
|
||||
dec ecx
|
||||
jnz loop1
|
||||
|
||||
// add the four floats of xmm0 together and return the result.
|
||||
|
||||
movhlps xmm1, xmm0 // move 3 & 4 of xmm0 to 1 & 2 of xmm1
|
||||
addps xmm1, xmm0
|
||||
movaps xmm2, xmm1
|
||||
shufps xmm2, xmm2, 0x01 // move 2 of xmm2 as 1 of xmm2
|
||||
addss xmm2, xmm1
|
||||
movss corr, xmm2
|
||||
}
|
||||
|
||||
return (double)corr;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of SSE optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
FIRFilterSSE::FIRFilterSSE() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilterSSE::~FIRFilterSSE()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for SSE routine
|
||||
void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
float fDivider;
|
||||
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||
// also rearrange coefficients suitably for 3DNow!
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||
filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
fDivider = (float)resultDivider;
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0; i < newLength; i ++)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] =
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SSE-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint numSamples) const
|
||||
{
|
||||
int count = (numSamples - length) & -2;
|
||||
int j;
|
||||
|
||||
assert(count % 2 == 0);
|
||||
|
||||
if (count < 2) return 0;
|
||||
|
||||
assert((length % 8) == 0);
|
||||
assert(((unsigned long)filterCoeffsAlign) % 16 == 0);
|
||||
|
||||
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *pSrc;
|
||||
const __m128 *pFil;
|
||||
__m128 sum1, sum2;
|
||||
uint i;
|
||||
|
||||
pSrc = source; // source audio data
|
||||
pFil = (__m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
||||
// are aligned to 16-byte boundary
|
||||
sum1 = sum2 = _mm_setzero_ps();
|
||||
|
||||
for (i = 0; i < length / 8; i ++)
|
||||
{
|
||||
// Unroll loop for efficiency & calculate filter for 2*2 stereo samples
|
||||
// at each pass
|
||||
|
||||
// sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset
|
||||
// sum2 is accu for 2*2 filtered stereo sound data for the next sound sample offset.
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc) , pFil[0]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 2), pFil[0]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 4), pFil[1]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 6), pFil[1]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 8) , pFil[2]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 10), pFil[2]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 12), pFil[3]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 14), pFil[3]));
|
||||
|
||||
pSrc += 16;
|
||||
pFil += 4;
|
||||
}
|
||||
|
||||
// Now sum1 and sum2 both have a filtered 2-channel sample each, but we still need
|
||||
// to sum the two hi- and lo-floats of these registers together.
|
||||
|
||||
// post-shuffle & add the filtered values and store to dest.
|
||||
_mm_storeu_ps(dest, _mm_add_ps(
|
||||
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1,0,3,2)), // s2_1 s2_0 s1_3 s1_2
|
||||
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3,2,1,0)) // s2_3 s2_2 s1_1 s1_0
|
||||
));
|
||||
source += 4;
|
||||
dest += 4;
|
||||
}
|
||||
|
||||
// Ideas for further improvement:
|
||||
// 1. If it could be guaranteed that 'source' were always aligned to 16-byte
|
||||
// boundary, a faster aligned '_mm_load_ps' instruction could be used.
|
||||
// 2. If it could be guaranteed that 'dest' were always aligned to 16-byte
|
||||
// boundary, a faster '_mm_store_ps' instruction could be used.
|
||||
|
||||
return (uint)count;
|
||||
|
||||
/* original routine in C-language. please notice the C-version has differently
|
||||
organized coefficients though.
|
||||
double suml1, suml2;
|
||||
double sumr1, sumr2;
|
||||
uint i, j;
|
||||
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *ptr;
|
||||
const float *pFil;
|
||||
|
||||
suml1 = sumr1 = 0.0;
|
||||
suml2 = sumr2 = 0.0;
|
||||
ptr = src;
|
||||
pFil = filterCoeffs;
|
||||
for (i = 0; i < lengthLocal; i ++)
|
||||
{
|
||||
// unroll loop for efficiency.
|
||||
|
||||
suml1 += ptr[0] * pFil[0] +
|
||||
ptr[2] * pFil[2] +
|
||||
ptr[4] * pFil[4] +
|
||||
ptr[6] * pFil[6];
|
||||
|
||||
sumr1 += ptr[1] * pFil[1] +
|
||||
ptr[3] * pFil[3] +
|
||||
ptr[5] * pFil[5] +
|
||||
ptr[7] * pFil[7];
|
||||
|
||||
suml2 += ptr[8] * pFil[0] +
|
||||
ptr[10] * pFil[2] +
|
||||
ptr[12] * pFil[4] +
|
||||
ptr[14] * pFil[6];
|
||||
|
||||
sumr2 += ptr[9] * pFil[1] +
|
||||
ptr[11] * pFil[3] +
|
||||
ptr[13] * pFil[5] +
|
||||
ptr[15] * pFil[7];
|
||||
|
||||
ptr += 16;
|
||||
pFil += 8;
|
||||
}
|
||||
dest[0] = (float)suml1;
|
||||
dest[1] = (float)sumr1;
|
||||
dest[2] = (float)suml2;
|
||||
dest[3] = (float)sumr2;
|
||||
|
||||
src += 4;
|
||||
dest += 4;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* Similar routine in assembly, again obsoleted due to maintainability
|
||||
_asm
|
||||
{
|
||||
// Very important note: data in 'src' _must_ be aligned to
|
||||
// 16-byte boundary!
|
||||
mov edx, count
|
||||
mov ebx, dword ptr src
|
||||
mov eax, dword ptr dest
|
||||
shr edx, 1
|
||||
|
||||
loop1:
|
||||
// "outer loop" : during each round 2*2 output samples are calculated
|
||||
|
||||
// give prefetch hints to CPU of what data are to be needed soonish
|
||||
prefetcht0 [ebx]
|
||||
prefetcht0 [filterCoeffsLocal]
|
||||
|
||||
mov esi, ebx
|
||||
mov edi, filterCoeffsLocal
|
||||
xorps xmm0, xmm0
|
||||
xorps xmm1, xmm1
|
||||
mov ecx, lengthLocal
|
||||
|
||||
loop2:
|
||||
// "inner loop" : during each round eight FIR filter taps are evaluated for 2*2 samples
|
||||
prefetcht0 [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm2, [esi] // possibly unaligned load
|
||||
movups xmm3, [esi + 8] // possibly unaligned load
|
||||
mulps xmm2, [edi]
|
||||
mulps xmm3, [edi]
|
||||
addps xmm0, xmm2
|
||||
addps xmm1, xmm3
|
||||
|
||||
movups xmm4, [esi + 16] // possibly unaligned load
|
||||
movups xmm5, [esi + 24] // possibly unaligned load
|
||||
mulps xmm4, [edi + 16]
|
||||
mulps xmm5, [edi + 16]
|
||||
addps xmm0, xmm4
|
||||
addps xmm1, xmm5
|
||||
|
||||
prefetcht0 [esi + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [edi + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm6, [esi + 32] // possibly unaligned load
|
||||
movups xmm7, [esi + 40] // possibly unaligned load
|
||||
mulps xmm6, [edi + 32]
|
||||
mulps xmm7, [edi + 32]
|
||||
addps xmm0, xmm6
|
||||
addps xmm1, xmm7
|
||||
|
||||
movups xmm4, [esi + 48] // possibly unaligned load
|
||||
movups xmm5, [esi + 56] // possibly unaligned load
|
||||
mulps xmm4, [edi + 48]
|
||||
mulps xmm5, [edi + 48]
|
||||
addps xmm0, xmm4
|
||||
addps xmm1, xmm5
|
||||
|
||||
add esi, 64
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loop2
|
||||
|
||||
// Now xmm0 and xmm1 both have a filtered 2-channel sample each, but we still need
|
||||
// to sum the two hi- and lo-floats of these registers together.
|
||||
|
||||
movhlps xmm2, xmm0 // xmm2 = xmm2_3 xmm2_2 xmm0_3 xmm0_2
|
||||
movlhps xmm2, xmm1 // xmm2 = xmm1_1 xmm1_0 xmm0_3 xmm0_2
|
||||
shufps xmm0, xmm1, 0xe4 // xmm0 = xmm1_3 xmm1_2 xmm0_1 xmm0_0
|
||||
addps xmm0, xmm2
|
||||
|
||||
movaps [eax], xmm0
|
||||
add ebx, 16
|
||||
add eax, 16
|
||||
|
||||
dec edx
|
||||
jnz loop1
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endif // ALLOW_SSE
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
///
|
||||
/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE
|
||||
/// optimized functions have been gathered into this single source
|
||||
/// code file, regardless to their class or original source code file, in order
|
||||
/// to ease porting the library to other compiler and processor platforms.
|
||||
///
|
||||
/// The SSE-optimizations are programmed using SSE compiler intrinsics that
|
||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||
/// should compile with both toolsets.
|
||||
///
|
||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
||||
/// 6.0 processor pack" update to support SSE instruction set. The update is
|
||||
/// available for download at Microsoft Developers Network, see here:
|
||||
/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx
|
||||
///
|
||||
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
||||
/// perform a search with keywords "processor pack".
|
||||
///
|
||||
/// Author : Copyright (c) Olli Parviainen
|
||||
/// Author e-mail : oparviai 'at' iki.fi
|
||||
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||
///
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Last changed : $Date: 2006/02/05 16:44:06 $
|
||||
// File revision : $Revision: 1.2 $
|
||||
//
|
||||
// $Id: sse_optimized.cpp,v 1.2 2006/02/05 16:44:06 Olli Exp $
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// License :
|
||||
//
|
||||
// SoundTouch audio processing library
|
||||
// Copyright (c) Olli Parviainen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "cpu_detect.h"
|
||||
#include "STTypes.h"
|
||||
|
||||
using namespace soundtouch;
|
||||
|
||||
#ifdef ALLOW_SSE
|
||||
|
||||
// SSE routines available only with float sample type
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of SSE optimized functions of class 'TDStretchSSE'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "TDStretch.h"
|
||||
#include <xmmintrin.h>
|
||||
|
||||
// Calculates cross correlation of two buffers
|
||||
double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const
|
||||
{
|
||||
uint i;
|
||||
__m128 vSum, *pVec2;
|
||||
|
||||
// Note. It means a major slow-down if the routine needs to tolerate
|
||||
// unaligned __m128 memory accesses. It's way faster if we can skip
|
||||
// unaligned slots and use _mm_load_ps instruction instead of _mm_loadu_ps.
|
||||
// This can mean up to ~ 10-fold difference (incl. part of which is
|
||||
// due to skipping every second round for stereo sound though).
|
||||
//
|
||||
// Compile-time define ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
|
||||
// for choosing if this little cheating is allowed.
|
||||
|
||||
#ifdef ALLOW_NONEXACT_SIMD_OPTIMIZATION
|
||||
// Little cheating allowed, return valid correlation only for
|
||||
// aligned locations, meaning every second round for stereo sound.
|
||||
|
||||
#define _MM_LOAD _mm_load_ps
|
||||
|
||||
if (((ulong)pV1) & 15) return -1e50; // skip unaligned locations
|
||||
|
||||
#else
|
||||
// No cheating allowed, use unaligned load & take the resulting
|
||||
// performance hit.
|
||||
#define _MM_LOAD _mm_loadu_ps
|
||||
#endif
|
||||
|
||||
// ensure overlapLength is divisible by 8
|
||||
assert((overlapLength % 8) == 0);
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
// Note: pV2 _must_ be aligned to 16-bit boundary, pV1 need not.
|
||||
pVec2 = (__m128*)pV2;
|
||||
vSum = _mm_setzero_ps();
|
||||
|
||||
// Unroll the loop by factor of 4 * 4 operations
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
// vSum += pV1[0..3] * pV2[0..3]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1),pVec2[0]));
|
||||
|
||||
// vSum += pV1[4..7] * pV2[4..7]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 4), pVec2[1]));
|
||||
|
||||
// vSum += pV1[8..11] * pV2[8..11]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 8), pVec2[2]));
|
||||
|
||||
// vSum += pV1[12..15] * pV2[12..15]
|
||||
vSum = _mm_add_ps(vSum, _mm_mul_ps(_MM_LOAD(pV1 + 12), pVec2[3]));
|
||||
|
||||
pV1 += 16;
|
||||
pVec2 += 4;
|
||||
}
|
||||
|
||||
// return value = vSum[0] + vSum[1] + vSum[2] + vSum[3]
|
||||
float *pvSum = (float*)&vSum;
|
||||
return (double)(pvSum[0] + pvSum[1] + pvSum[2] + pvSum[3]);
|
||||
|
||||
/* This is approximately corresponding routine in C-language:
|
||||
double corr;
|
||||
uint i;
|
||||
|
||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||
corr = 0.0;
|
||||
for (i = 0; i < overlapLength / 8; i ++)
|
||||
{
|
||||
corr += pV1[0] * pV2[0] +
|
||||
pV1[1] * pV2[1] +
|
||||
pV1[2] * pV2[2] +
|
||||
pV1[3] * pV2[3] +
|
||||
pV1[4] * pV2[4] +
|
||||
pV1[5] * pV2[5] +
|
||||
pV1[6] * pV2[6] +
|
||||
pV1[7] * pV2[7] +
|
||||
pV1[8] * pV2[8] +
|
||||
pV1[9] * pV2[9] +
|
||||
pV1[10] * pV2[10] +
|
||||
pV1[11] * pV2[11] +
|
||||
pV1[12] * pV2[12] +
|
||||
pV1[13] * pV2[13] +
|
||||
pV1[14] * pV2[14] +
|
||||
pV1[15] * pV2[15];
|
||||
|
||||
pV1 += 16;
|
||||
pV2 += 16;
|
||||
}
|
||||
*/
|
||||
|
||||
/* This is corresponding routine in assembler. This may be teeny-weeny bit faster
|
||||
than intrinsic version, but more difficult to maintain & get compiled on multiple
|
||||
platforms.
|
||||
|
||||
uint overlapLengthLocal = overlapLength;
|
||||
float corr;
|
||||
|
||||
_asm
|
||||
{
|
||||
// Very important note: data in 'pV2' _must_ be aligned to
|
||||
// 16-byte boundary!
|
||||
|
||||
// give prefetch hints to CPU of what data are to be needed soonish
|
||||
// give more aggressive hints on pV1 as that changes while pV2 stays
|
||||
// same between runs
|
||||
prefetcht0 [pV1]
|
||||
prefetcht0 [pV2]
|
||||
prefetcht0 [pV1 + 32]
|
||||
|
||||
mov eax, dword ptr pV1
|
||||
mov ebx, dword ptr pV2
|
||||
|
||||
xorps xmm0, xmm0
|
||||
|
||||
mov ecx, overlapLengthLocal
|
||||
shr ecx, 3 // div by eight
|
||||
|
||||
loop1:
|
||||
prefetcht0 [eax + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [ebx + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
movups xmm1, [eax]
|
||||
mulps xmm1, [ebx]
|
||||
addps xmm0, xmm1
|
||||
|
||||
movups xmm2, [eax + 16]
|
||||
mulps xmm2, [ebx + 16]
|
||||
addps xmm0, xmm2
|
||||
|
||||
prefetcht0 [eax + 96] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm3, [eax + 32]
|
||||
mulps xmm3, [ebx + 32]
|
||||
addps xmm0, xmm3
|
||||
|
||||
movups xmm4, [eax + 48]
|
||||
mulps xmm4, [ebx + 48]
|
||||
addps xmm0, xmm4
|
||||
|
||||
add eax, 64
|
||||
add ebx, 64
|
||||
|
||||
dec ecx
|
||||
jnz loop1
|
||||
|
||||
// add the four floats of xmm0 together and return the result.
|
||||
|
||||
movhlps xmm1, xmm0 // move 3 & 4 of xmm0 to 1 & 2 of xmm1
|
||||
addps xmm1, xmm0
|
||||
movaps xmm2, xmm1
|
||||
shufps xmm2, xmm2, 0x01 // move 2 of xmm2 as 1 of xmm2
|
||||
addss xmm2, xmm1
|
||||
movss corr, xmm2
|
||||
}
|
||||
|
||||
return (double)corr;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation of SSE optimized functions of class 'FIRFilter'
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "FIRFilter.h"
|
||||
|
||||
FIRFilterSSE::FIRFilterSSE() : FIRFilter()
|
||||
{
|
||||
filterCoeffsUnalign = NULL;
|
||||
}
|
||||
|
||||
|
||||
FIRFilterSSE::~FIRFilterSSE()
|
||||
{
|
||||
delete[] filterCoeffsUnalign;
|
||||
}
|
||||
|
||||
|
||||
// (overloaded) Calculates filter coefficients for SSE routine
|
||||
void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor)
|
||||
{
|
||||
uint i;
|
||||
float fDivider;
|
||||
|
||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||
|
||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||
// also rearrange coefficients suitably for 3DNow!
|
||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||
delete[] filterCoeffsUnalign;
|
||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||
filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & -16);
|
||||
|
||||
fDivider = (float)resultDivider;
|
||||
|
||||
// rearrange the filter coefficients for mmx routines
|
||||
for (i = 0; i < newLength; i ++)
|
||||
{
|
||||
filterCoeffsAlign[2 * i + 0] =
|
||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SSE-optimized version of the filter routine for stereo sound
|
||||
uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint numSamples) const
|
||||
{
|
||||
int count = (numSamples - length) & -2;
|
||||
int j;
|
||||
|
||||
assert(count % 2 == 0);
|
||||
|
||||
if (count < 2) return 0;
|
||||
|
||||
assert((length % 8) == 0);
|
||||
assert(((unsigned long)filterCoeffsAlign) % 16 == 0);
|
||||
|
||||
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *pSrc;
|
||||
const __m128 *pFil;
|
||||
__m128 sum1, sum2;
|
||||
uint i;
|
||||
|
||||
pSrc = source; // source audio data
|
||||
pFil = (__m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
||||
// are aligned to 16-byte boundary
|
||||
sum1 = sum2 = _mm_setzero_ps();
|
||||
|
||||
for (i = 0; i < length / 8; i ++)
|
||||
{
|
||||
// Unroll loop for efficiency & calculate filter for 2*2 stereo samples
|
||||
// at each pass
|
||||
|
||||
// sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset
|
||||
// sum2 is accu for 2*2 filtered stereo sound data for the next sound sample offset.
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc) , pFil[0]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 2), pFil[0]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 4), pFil[1]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 6), pFil[1]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 8) , pFil[2]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 10), pFil[2]));
|
||||
|
||||
sum1 = _mm_add_ps(sum1, _mm_mul_ps(_mm_loadu_ps(pSrc + 12), pFil[3]));
|
||||
sum2 = _mm_add_ps(sum2, _mm_mul_ps(_mm_loadu_ps(pSrc + 14), pFil[3]));
|
||||
|
||||
pSrc += 16;
|
||||
pFil += 4;
|
||||
}
|
||||
|
||||
// Now sum1 and sum2 both have a filtered 2-channel sample each, but we still need
|
||||
// to sum the two hi- and lo-floats of these registers together.
|
||||
|
||||
// post-shuffle & add the filtered values and store to dest.
|
||||
_mm_storeu_ps(dest, _mm_add_ps(
|
||||
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(1,0,3,2)), // s2_1 s2_0 s1_3 s1_2
|
||||
_mm_shuffle_ps(sum1, sum2, _MM_SHUFFLE(3,2,1,0)) // s2_3 s2_2 s1_1 s1_0
|
||||
));
|
||||
source += 4;
|
||||
dest += 4;
|
||||
}
|
||||
|
||||
// Ideas for further improvement:
|
||||
// 1. If it could be guaranteed that 'source' were always aligned to 16-byte
|
||||
// boundary, a faster aligned '_mm_load_ps' instruction could be used.
|
||||
// 2. If it could be guaranteed that 'dest' were always aligned to 16-byte
|
||||
// boundary, a faster '_mm_store_ps' instruction could be used.
|
||||
|
||||
return (uint)count;
|
||||
|
||||
/* original routine in C-language. please notice the C-version has differently
|
||||
organized coefficients though.
|
||||
double suml1, suml2;
|
||||
double sumr1, sumr2;
|
||||
uint i, j;
|
||||
|
||||
for (j = 0; j < count; j += 2)
|
||||
{
|
||||
const float *ptr;
|
||||
const float *pFil;
|
||||
|
||||
suml1 = sumr1 = 0.0;
|
||||
suml2 = sumr2 = 0.0;
|
||||
ptr = src;
|
||||
pFil = filterCoeffs;
|
||||
for (i = 0; i < lengthLocal; i ++)
|
||||
{
|
||||
// unroll loop for efficiency.
|
||||
|
||||
suml1 += ptr[0] * pFil[0] +
|
||||
ptr[2] * pFil[2] +
|
||||
ptr[4] * pFil[4] +
|
||||
ptr[6] * pFil[6];
|
||||
|
||||
sumr1 += ptr[1] * pFil[1] +
|
||||
ptr[3] * pFil[3] +
|
||||
ptr[5] * pFil[5] +
|
||||
ptr[7] * pFil[7];
|
||||
|
||||
suml2 += ptr[8] * pFil[0] +
|
||||
ptr[10] * pFil[2] +
|
||||
ptr[12] * pFil[4] +
|
||||
ptr[14] * pFil[6];
|
||||
|
||||
sumr2 += ptr[9] * pFil[1] +
|
||||
ptr[11] * pFil[3] +
|
||||
ptr[13] * pFil[5] +
|
||||
ptr[15] * pFil[7];
|
||||
|
||||
ptr += 16;
|
||||
pFil += 8;
|
||||
}
|
||||
dest[0] = (float)suml1;
|
||||
dest[1] = (float)sumr1;
|
||||
dest[2] = (float)suml2;
|
||||
dest[3] = (float)sumr2;
|
||||
|
||||
src += 4;
|
||||
dest += 4;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* Similar routine in assembly, again obsoleted due to maintainability
|
||||
_asm
|
||||
{
|
||||
// Very important note: data in 'src' _must_ be aligned to
|
||||
// 16-byte boundary!
|
||||
mov edx, count
|
||||
mov ebx, dword ptr src
|
||||
mov eax, dword ptr dest
|
||||
shr edx, 1
|
||||
|
||||
loop1:
|
||||
// "outer loop" : during each round 2*2 output samples are calculated
|
||||
|
||||
// give prefetch hints to CPU of what data are to be needed soonish
|
||||
prefetcht0 [ebx]
|
||||
prefetcht0 [filterCoeffsLocal]
|
||||
|
||||
mov esi, ebx
|
||||
mov edi, filterCoeffsLocal
|
||||
xorps xmm0, xmm0
|
||||
xorps xmm1, xmm1
|
||||
mov ecx, lengthLocal
|
||||
|
||||
loop2:
|
||||
// "inner loop" : during each round eight FIR filter taps are evaluated for 2*2 samples
|
||||
prefetcht0 [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm2, [esi] // possibly unaligned load
|
||||
movups xmm3, [esi + 8] // possibly unaligned load
|
||||
mulps xmm2, [edi]
|
||||
mulps xmm3, [edi]
|
||||
addps xmm0, xmm2
|
||||
addps xmm1, xmm3
|
||||
|
||||
movups xmm4, [esi + 16] // possibly unaligned load
|
||||
movups xmm5, [esi + 24] // possibly unaligned load
|
||||
mulps xmm4, [edi + 16]
|
||||
mulps xmm5, [edi + 16]
|
||||
addps xmm0, xmm4
|
||||
addps xmm1, xmm5
|
||||
|
||||
prefetcht0 [esi + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
prefetcht0 [edi + 64] // give a prefetch hint to CPU what data are to be needed soonish
|
||||
|
||||
movups xmm6, [esi + 32] // possibly unaligned load
|
||||
movups xmm7, [esi + 40] // possibly unaligned load
|
||||
mulps xmm6, [edi + 32]
|
||||
mulps xmm7, [edi + 32]
|
||||
addps xmm0, xmm6
|
||||
addps xmm1, xmm7
|
||||
|
||||
movups xmm4, [esi + 48] // possibly unaligned load
|
||||
movups xmm5, [esi + 56] // possibly unaligned load
|
||||
mulps xmm4, [edi + 48]
|
||||
mulps xmm5, [edi + 48]
|
||||
addps xmm0, xmm4
|
||||
addps xmm1, xmm5
|
||||
|
||||
add esi, 64
|
||||
add edi, 64
|
||||
dec ecx
|
||||
jnz loop2
|
||||
|
||||
// Now xmm0 and xmm1 both have a filtered 2-channel sample each, but we still need
|
||||
// to sum the two hi- and lo-floats of these registers together.
|
||||
|
||||
movhlps xmm2, xmm0 // xmm2 = xmm2_3 xmm2_2 xmm0_3 xmm0_2
|
||||
movlhps xmm2, xmm1 // xmm2 = xmm1_1 xmm1_0 xmm0_3 xmm0_2
|
||||
shufps xmm0, xmm1, 0xe4 // xmm0 = xmm1_3 xmm1_2 xmm0_1 xmm0_0
|
||||
addps xmm0, xmm2
|
||||
|
||||
movaps [eax], xmm0
|
||||
add ebx, 16
|
||||
add eax, 16
|
||||
|
||||
dec edx
|
||||
jnz loop1
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
#endif // ALLOW_SSE
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,282 +1,282 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Public header file for the library. ---*/
|
||||
/*--- bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_H
|
||||
#define _BZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *(*bzalloc)(void *,int,int);
|
||||
void (*bzfree)(void *,void *);
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*-- High(er) level library functions --*/
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#define BZ_MAX_UNUSED 5000
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
int small,
|
||||
void* unused,
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int small,
|
||||
int verbosity
|
||||
);
|
||||
|
||||
|
||||
/*--
|
||||
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
|
||||
to support better zlib compatibility.
|
||||
This code is not _officially_ part of libbzip2 (yet);
|
||||
I haven't tested it, documented it, or considered the
|
||||
threading-safeness of it.
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Public header file for the library. ---*/
|
||||
/*--- bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_H
|
||||
#define _BZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *(*bzalloc)(void *,int,int);
|
||||
void (*bzfree)(void *,void *);
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*-- High(er) level library functions --*/
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#define BZ_MAX_UNUSED 5000
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
int small,
|
||||
void* unused,
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int small,
|
||||
int verbosity
|
||||
);
|
||||
|
||||
|
||||
/*--
|
||||
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
|
||||
to support better zlib compatibility.
|
||||
This code is not _officially_ part of libbzip2 (yet);
|
||||
I haven't tested it, documented it, or considered the
|
||||
threading-safeness of it.
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,104 +1,104 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for doing CRCs ---*/
|
||||
/*--- crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*--
|
||||
I think this is an implementation of the AUTODIN-II,
|
||||
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
|
||||
from code by Rob Warnock, in Section 51 of the
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for doing CRCs ---*/
|
||||
/*--- crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*--
|
||||
I think this is an implementation of the AUTODIN-II,
|
||||
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
|
||||
from code by Rob Warnock, in Section 51 of the
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,205 +1,205 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Huffman coding low-level stuff ---*/
|
||||
/*--- huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (weight[tmp] < weight[heap[zz >> 1]]) { \
|
||||
heap[zz] = heap[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#define DOWNHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, yy, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (True) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) break; \
|
||||
if (yy < nHeap && \
|
||||
weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
for both the heap and nodes is a sentinel.
|
||||
--*/
|
||||
Int32 nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
|
||||
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (True) {
|
||||
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
heap[0] = 0;
|
||||
weight[0] = 0;
|
||||
parent[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
parent[i] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
nNodes++;
|
||||
parent[n1] = parent[n2] = nNodes;
|
||||
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
|
||||
parent[nNodes] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
|
||||
|
||||
tooLong = False;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
if (! tooLong) break;
|
||||
|
||||
/* 17 Oct 04: keep-going condition for the following loop used
|
||||
to be 'i < alphaSize', which missed the last element,
|
||||
theoretically leading to the possibility of the compressor
|
||||
looping. However, this count-scaling step is only needed if
|
||||
one of the generated Huffman code words is longer than
|
||||
maxLen, which up to and including version 1.0.2 was 20 bits,
|
||||
which is extremely unlikely. In version 1.0.3 maxLen was
|
||||
changed to 17 bits, which has minimal effect on compression
|
||||
ratio, but does mean this scaling step is used from time to
|
||||
time, enough to verify that it works.
|
||||
|
||||
This means that bzip2-1.0.3 and later will only produce
|
||||
Huffman codes with a maximum length of 17 bits. However, in
|
||||
order to preserve backwards compatibility with bitstreams
|
||||
produced by versions pre-1.0.3, the decompressor must still
|
||||
handle lengths of up to 20. */
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = weight[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
weight[i] = j << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
if (length[i] == n) { code[i] = vec; vec++; };
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
pp = 0;
|
||||
for (i = minLen; i <= maxLen; i++)
|
||||
for (j = 0; j < alphaSize; j++)
|
||||
if (length[j] == i) { perm[pp] = j; pp++; };
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
|
||||
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
|
||||
|
||||
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
|
||||
vec = 0;
|
||||
|
||||
for (i = minLen; i <= maxLen; i++) {
|
||||
vec += (base[i+1] - base[i]);
|
||||
limit[i] = vec-1;
|
||||
vec <<= 1;
|
||||
}
|
||||
for (i = minLen + 1; i <= maxLen; i++)
|
||||
base[i] = ((limit[i-1] + 1) << 1) - base[i];
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Huffman coding low-level stuff ---*/
|
||||
/*--- huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (weight[tmp] < weight[heap[zz >> 1]]) { \
|
||||
heap[zz] = heap[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#define DOWNHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, yy, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (True) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) break; \
|
||||
if (yy < nHeap && \
|
||||
weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
for both the heap and nodes is a sentinel.
|
||||
--*/
|
||||
Int32 nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
|
||||
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (True) {
|
||||
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
heap[0] = 0;
|
||||
weight[0] = 0;
|
||||
parent[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
parent[i] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
nNodes++;
|
||||
parent[n1] = parent[n2] = nNodes;
|
||||
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
|
||||
parent[nNodes] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
|
||||
|
||||
tooLong = False;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
if (! tooLong) break;
|
||||
|
||||
/* 17 Oct 04: keep-going condition for the following loop used
|
||||
to be 'i < alphaSize', which missed the last element,
|
||||
theoretically leading to the possibility of the compressor
|
||||
looping. However, this count-scaling step is only needed if
|
||||
one of the generated Huffman code words is longer than
|
||||
maxLen, which up to and including version 1.0.2 was 20 bits,
|
||||
which is extremely unlikely. In version 1.0.3 maxLen was
|
||||
changed to 17 bits, which has minimal effect on compression
|
||||
ratio, but does mean this scaling step is used from time to
|
||||
time, enough to verify that it works.
|
||||
|
||||
This means that bzip2-1.0.3 and later will only produce
|
||||
Huffman codes with a maximum length of 17 bits. However, in
|
||||
order to preserve backwards compatibility with bitstreams
|
||||
produced by versions pre-1.0.3, the decompressor must still
|
||||
handle lengths of up to 20. */
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = weight[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
weight[i] = j << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
if (length[i] == n) { code[i] = vec; vec++; };
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
pp = 0;
|
||||
for (i = minLen; i <= maxLen; i++)
|
||||
for (j = 0; j < alphaSize; j++)
|
||||
if (length[j] == i) { perm[pp] = j; pp++; };
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
|
||||
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
|
||||
|
||||
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
|
||||
vec = 0;
|
||||
|
||||
for (i = minLen; i <= maxLen; i++) {
|
||||
vec += (base[i+1] - base[i]);
|
||||
limit[i] = vec-1;
|
||||
vec <<= 1;
|
||||
}
|
||||
for (i = minLen + 1; i <= maxLen; i++)
|
||||
base[i] = ((limit[i-1] + 1) << 1) - base[i];
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.4 of 20 December 2006
|
||||
Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
|
|
@ -1,149 +1,149 @@
|
|||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
|
||||
if (sum2 > BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
||||
#define NMAX 5552
|
||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||
|
||||
#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
|
||||
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
|
||||
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
|
||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||
|
||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
||||
#ifdef NO_DIVIDE
|
||||
# define MOD(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
||||
if (a >= (BASE << 9)) a -= (BASE << 9); \
|
||||
if (a >= (BASE << 8)) a -= (BASE << 8); \
|
||||
if (a >= (BASE << 7)) a -= (BASE << 7); \
|
||||
if (a >= (BASE << 6)) a -= (BASE << 6); \
|
||||
if (a >= (BASE << 5)) a -= (BASE << 5); \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
# define MOD4(a) \
|
||||
do { \
|
||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
||||
if (a >= BASE) a -= BASE; \
|
||||
} while (0)
|
||||
#else
|
||||
# define MOD(a) a %= BASE
|
||||
# define MOD4(a) a %= BASE
|
||||
#endif
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32(adler, buf, len)
|
||||
uLong adler;
|
||||
const Bytef *buf;
|
||||
uInt len;
|
||||
{
|
||||
unsigned long sum2;
|
||||
unsigned n;
|
||||
|
||||
/* split Adler-32 into component sums */
|
||||
sum2 = (adler >> 16) & 0xffff;
|
||||
adler &= 0xffff;
|
||||
|
||||
/* in case user likes doing a byte at a time, keep it fast */
|
||||
if (len == 1) {
|
||||
adler += buf[0];
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
sum2 += adler;
|
||||
if (sum2 >= BASE)
|
||||
sum2 -= BASE;
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* initial Adler-32 value (deferred check for len == 1 speed) */
|
||||
if (buf == Z_NULL)
|
||||
return 1L;
|
||||
|
||||
/* in case short lengths are provided, keep it somewhat fast */
|
||||
if (len < 16) {
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
if (adler >= BASE)
|
||||
adler -= BASE;
|
||||
MOD4(sum2); /* only added so many BASE's */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* do length NMAX blocks -- requires just one modulo operation */
|
||||
while (len >= NMAX) {
|
||||
len -= NMAX;
|
||||
n = NMAX / 16; /* NMAX is divisible by 16 */
|
||||
do {
|
||||
DO16(buf); /* 16 sums unrolled */
|
||||
buf += 16;
|
||||
} while (--n);
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||
if (len) { /* avoid modulos if none remaining */
|
||||
while (len >= 16) {
|
||||
len -= 16;
|
||||
DO16(buf);
|
||||
buf += 16;
|
||||
}
|
||||
while (len--) {
|
||||
adler += *buf++;
|
||||
sum2 += adler;
|
||||
}
|
||||
MOD(adler);
|
||||
MOD(sum2);
|
||||
}
|
||||
|
||||
/* return recombined sums */
|
||||
return adler | (sum2 << 16);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT adler32_combine(adler1, adler2, len2)
|
||||
uLong adler1;
|
||||
uLong adler2;
|
||||
z_off_t len2;
|
||||
{
|
||||
unsigned long sum1;
|
||||
unsigned long sum2;
|
||||
unsigned rem;
|
||||
|
||||
/* the derivation of this formula is left as an exercise for the reader */
|
||||
rem = (unsigned)(len2 % BASE);
|
||||
sum1 = adler1 & 0xffff;
|
||||
sum2 = rem * sum1;
|
||||
MOD(sum2);
|
||||
sum1 += (adler2 & 0xffff) + BASE - 1;
|
||||
sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum1 > BASE) sum1 -= BASE;
|
||||
if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
|
||||
if (sum2 > BASE) sum2 -= BASE;
|
||||
return sum1 | (sum2 << 16);
|
||||
}
|
||||
|
|
|
@ -1,79 +1,79 @@
|
|||
/* compress.c -- compress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Compresses the source buffer into the destination buffer. The level
|
||||
parameter has the same meaning as in deflateInit. sourceLen is the byte
|
||||
length of the source buffer. Upon entry, destLen is the total size of the
|
||||
destination buffer, which must be at least 0.1% larger than sourceLen plus
|
||||
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
|
||||
|
||||
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
int level;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
#ifdef MAXSEG_64K
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
#endif
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&stream, level);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = deflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
deflateEnd(&stream);
|
||||
return err == Z_OK ? Z_BUF_ERROR : err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = deflateEnd(&stream);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
*/
|
||||
int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
If the default memLevel or windowBits for deflateInit() is changed, then
|
||||
this function needs to be updated.
|
||||
*/
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
|
||||
}
|
||||
/* compress.c -- compress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Compresses the source buffer into the destination buffer. The level
|
||||
parameter has the same meaning as in deflateInit. sourceLen is the byte
|
||||
length of the source buffer. Upon entry, destLen is the total size of the
|
||||
destination buffer, which must be at least 0.1% larger than sourceLen plus
|
||||
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
|
||||
|
||||
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
|
||||
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
|
||||
Z_STREAM_ERROR if the level parameter is invalid.
|
||||
*/
|
||||
int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
int level;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
#ifdef MAXSEG_64K
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
#endif
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
stream.opaque = (voidpf)0;
|
||||
|
||||
err = deflateInit(&stream, level);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = deflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
deflateEnd(&stream);
|
||||
return err == Z_OK ? Z_BUF_ERROR : err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = deflateEnd(&stream);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
*/
|
||||
int ZEXPORT compress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
If the default memLevel or windowBits for deflateInit() is changed, then
|
||||
this function needs to be updated.
|
||||
*/
|
||||
uLong ZEXPORT compressBound (sourceLen)
|
||||
uLong sourceLen;
|
||||
{
|
||||
return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
|
||||
}
|
||||
|
|
|
@ -1,423 +1,423 @@
|
|||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*
|
||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
|
||||
* tables for updating the shift register in one step with three exclusive-ors
|
||||
* instead of four steps with four exclusive-ors. This results in about a
|
||||
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
/*
|
||||
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
|
||||
protection on the static variables used to control the first-use generation
|
||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||
first call get_crc_table() to initialize the tables before allowing more than
|
||||
one thread to use crc32().
|
||||
*/
|
||||
|
||||
#ifdef MAKECRCH
|
||||
# include <stdio.h>
|
||||
# ifndef DYNAMIC_CRC_TABLE
|
||||
# define DYNAMIC_CRC_TABLE
|
||||
# endif /* !DYNAMIC_CRC_TABLE */
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#include "zutil.h" /* for STDC and FAR definitions */
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
# define TBLS 8
|
||||
#else
|
||||
# define TBLS 1
|
||||
#endif /* BYFOUR */
|
||||
|
||||
/* Local functions for crc concatenation */
|
||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||
unsigned long vec));
|
||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local volatile int crc_table_empty = 1;
|
||||
local unsigned long FAR crc_table[TBLS][256];
|
||||
local void make_crc_table OF((void));
|
||||
#ifdef MAKECRCH
|
||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
||||
#endif /* MAKECRCH */
|
||||
/*
|
||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
|
||||
|
||||
Polynomials over GF(2) are represented in binary, one bit per coefficient,
|
||||
with the lowest powers in the most significant bit. Then adding polynomials
|
||||
is just exclusive-or, and multiplying a polynomial by x is a right shift by
|
||||
one. If we call the above polynomial p, and represent a byte as the
|
||||
polynomial q, also with the lowest power in the most significant bit (so the
|
||||
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
|
||||
where a mod b means the remainder after dividing a by b.
|
||||
|
||||
This calculation is done using the shift-register method of multiplying and
|
||||
taking the remainder. The register is initialized to zero, and for each
|
||||
incoming bit, x^32 is added mod p to the register if the bit is a one (where
|
||||
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
|
||||
x (which is shifting right by one and adding x^32 mod p if the bit shifted
|
||||
out is a one). We start with the highest power (least significant bit) of
|
||||
q and repeat for all eight bits of q.
|
||||
|
||||
The first table is simply the CRC of all possible eight bit values. This is
|
||||
all the information needed to generate CRCs on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes. The remaining tables
|
||||
allow for word-at-a-time CRC calculation for both big-endian and little-
|
||||
endian machines, where a word is four bytes.
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static volatile int first = 1; /* flag to limit concurrent making */
|
||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* See if another task is already doing this (not thread-safe, but better
|
||||
than nothing -- significantly reduces duration of vulnerability in
|
||||
case the advice about DYNAMIC_CRC_TABLE is ignored) */
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
|
||||
/* generate a crc for every 8-bit value */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[0][n] = c;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
/* generate crc for each value followed by one, two, and three zeros,
|
||||
and then the byte reversal of those as well as the first table */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = crc_table[0][n];
|
||||
crc_table[4][n] = REV(c);
|
||||
for (k = 1; k < 4; k++) {
|
||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||
crc_table[k][n] = c;
|
||||
crc_table[k + 4][n] = REV(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
|
||||
crc_table_empty = 0;
|
||||
}
|
||||
else { /* not first */
|
||||
/* wait for the other guy to finish (not efficient, but rare) */
|
||||
while (crc_table_empty)
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef MAKECRCH
|
||||
/* write out CRC tables to crc32.h */
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
out = fopen("crc32.h", "w");
|
||||
if (out == NULL) return;
|
||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||
fprintf(out, "local const unsigned long FAR ");
|
||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||
write_table(out, crc_table[0]);
|
||||
# ifdef BYFOUR
|
||||
fprintf(out, "#ifdef BYFOUR\n");
|
||||
for (k = 1; k < 8; k++) {
|
||||
fprintf(out, " },\n {\n");
|
||||
write_table(out, crc_table[k]);
|
||||
}
|
||||
fprintf(out, "#endif\n");
|
||||
# endif /* BYFOUR */
|
||||
fprintf(out, " }\n};\n");
|
||||
fclose(out);
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
}
|
||||
|
||||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#else /* !DYNAMIC_CRC_TABLE */
|
||||
/* ========================================================================
|
||||
* Tables of CRC-32s of all single-byte values, made by make_crc_table().
|
||||
*/
|
||||
#include "crc32.h"
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return (const unsigned long FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
|
||||
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0UL;
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
return crc32_little(crc, buf, len);
|
||||
else
|
||||
return crc32_big(crc, buf, len);
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
crc = crc ^ 0xffffffffUL;
|
||||
while (len >= 8) {
|
||||
DO8;
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1;
|
||||
} while (--len);
|
||||
return crc ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOLIT4 c ^= *buf4++; \
|
||||
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
|
||||
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
|
||||
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_little(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOLIT4;
|
||||
len -= 4;
|
||||
}
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)c;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOBIG4 c ^= *++buf4; \
|
||||
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
|
||||
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
|
||||
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_big(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOBIG4;
|
||||
len -= 4;
|
||||
}
|
||||
buf4++;
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
|
||||
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long gf2_matrix_times(mat, vec)
|
||||
unsigned long *mat;
|
||||
unsigned long vec;
|
||||
{
|
||||
unsigned long sum;
|
||||
|
||||
sum = 0;
|
||||
while (vec) {
|
||||
if (vec & 1)
|
||||
sum ^= *mat;
|
||||
vec >>= 1;
|
||||
mat++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
local void gf2_matrix_square(square, mat)
|
||||
unsigned long *square;
|
||||
unsigned long *mat;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < GF2_DIM; n++)
|
||||
square[n] = gf2_matrix_times(mat, mat[n]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
{
|
||||
int n;
|
||||
unsigned long row;
|
||||
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case */
|
||||
if (len2 == 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
row <<= 1;
|
||||
}
|
||||
|
||||
/* put operator for two zero bits in even */
|
||||
gf2_matrix_square(even, odd);
|
||||
|
||||
/* put operator for four zero bits in odd */
|
||||
gf2_matrix_square(odd, even);
|
||||
|
||||
/* apply len2 zeros to crc1 (first square will put the operator for one
|
||||
zero byte, eight zero bits, in even) */
|
||||
do {
|
||||
/* apply zeros operator for this bit of len2 */
|
||||
gf2_matrix_square(even, odd);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(even, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
if (len2 == 0)
|
||||
break;
|
||||
|
||||
/* another iteration of the loop with odd and even swapped */
|
||||
gf2_matrix_square(odd, even);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(odd, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
} while (len2 != 0);
|
||||
|
||||
/* return combined crc */
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
||||
/* crc32.c -- compute the CRC-32 of a data stream
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*
|
||||
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||
* CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
|
||||
* tables for updating the shift register in one step with three exclusive-ors
|
||||
* instead of four steps with four exclusive-ors. This results in about a
|
||||
* factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
/*
|
||||
Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
|
||||
protection on the static variables used to control the first-use generation
|
||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
||||
first call get_crc_table() to initialize the tables before allowing more than
|
||||
one thread to use crc32().
|
||||
*/
|
||||
|
||||
#ifdef MAKECRCH
|
||||
# include <stdio.h>
|
||||
# ifndef DYNAMIC_CRC_TABLE
|
||||
# define DYNAMIC_CRC_TABLE
|
||||
# endif /* !DYNAMIC_CRC_TABLE */
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#include "zutil.h" /* for STDC and FAR definitions */
|
||||
|
||||
#define local static
|
||||
|
||||
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
|
||||
#ifndef NOBYFOUR
|
||||
# ifdef STDC /* need ANSI C limits.h to determine sizes */
|
||||
# include <limits.h>
|
||||
# define BYFOUR
|
||||
# if (UINT_MAX == 0xffffffffUL)
|
||||
typedef unsigned int u4;
|
||||
# else
|
||||
# if (ULONG_MAX == 0xffffffffUL)
|
||||
typedef unsigned long u4;
|
||||
# else
|
||||
# if (USHRT_MAX == 0xffffffffUL)
|
||||
typedef unsigned short u4;
|
||||
# else
|
||||
# undef BYFOUR /* can't find a four-byte integer type! */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# endif /* STDC */
|
||||
#endif /* !NOBYFOUR */
|
||||
|
||||
/* Definitions for doing the crc four data bytes at a time. */
|
||||
#ifdef BYFOUR
|
||||
# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
|
||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
||||
local unsigned long crc32_little OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
local unsigned long crc32_big OF((unsigned long,
|
||||
const unsigned char FAR *, unsigned));
|
||||
# define TBLS 8
|
||||
#else
|
||||
# define TBLS 1
|
||||
#endif /* BYFOUR */
|
||||
|
||||
/* Local functions for crc concatenation */
|
||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||
unsigned long vec));
|
||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
|
||||
local volatile int crc_table_empty = 1;
|
||||
local unsigned long FAR crc_table[TBLS][256];
|
||||
local void make_crc_table OF((void));
|
||||
#ifdef MAKECRCH
|
||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
||||
#endif /* MAKECRCH */
|
||||
/*
|
||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
|
||||
|
||||
Polynomials over GF(2) are represented in binary, one bit per coefficient,
|
||||
with the lowest powers in the most significant bit. Then adding polynomials
|
||||
is just exclusive-or, and multiplying a polynomial by x is a right shift by
|
||||
one. If we call the above polynomial p, and represent a byte as the
|
||||
polynomial q, also with the lowest power in the most significant bit (so the
|
||||
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
|
||||
where a mod b means the remainder after dividing a by b.
|
||||
|
||||
This calculation is done using the shift-register method of multiplying and
|
||||
taking the remainder. The register is initialized to zero, and for each
|
||||
incoming bit, x^32 is added mod p to the register if the bit is a one (where
|
||||
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
|
||||
x (which is shifting right by one and adding x^32 mod p if the bit shifted
|
||||
out is a one). We start with the highest power (least significant bit) of
|
||||
q and repeat for all eight bits of q.
|
||||
|
||||
The first table is simply the CRC of all possible eight bit values. This is
|
||||
all the information needed to generate CRCs on data a byte at a time for all
|
||||
combinations of CRC register values and incoming bytes. The remaining tables
|
||||
allow for word-at-a-time CRC calculation for both big-endian and little-
|
||||
endian machines, where a word is four bytes.
|
||||
*/
|
||||
local void make_crc_table()
|
||||
{
|
||||
unsigned long c;
|
||||
int n, k;
|
||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
||||
/* terms of polynomial defining this crc (except x^32): */
|
||||
static volatile int first = 1; /* flag to limit concurrent making */
|
||||
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||
|
||||
/* See if another task is already doing this (not thread-safe, but better
|
||||
than nothing -- significantly reduces duration of vulnerability in
|
||||
case the advice about DYNAMIC_CRC_TABLE is ignored) */
|
||||
if (first) {
|
||||
first = 0;
|
||||
|
||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||
poly = 0UL;
|
||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
||||
poly |= 1UL << (31 - p[n]);
|
||||
|
||||
/* generate a crc for every 8-bit value */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long)n;
|
||||
for (k = 0; k < 8; k++)
|
||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||
crc_table[0][n] = c;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
/* generate crc for each value followed by one, two, and three zeros,
|
||||
and then the byte reversal of those as well as the first table */
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = crc_table[0][n];
|
||||
crc_table[4][n] = REV(c);
|
||||
for (k = 1; k < 4; k++) {
|
||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||
crc_table[k][n] = c;
|
||||
crc_table[k + 4][n] = REV(c);
|
||||
}
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
|
||||
crc_table_empty = 0;
|
||||
}
|
||||
else { /* not first */
|
||||
/* wait for the other guy to finish (not efficient, but rare) */
|
||||
while (crc_table_empty)
|
||||
;
|
||||
}
|
||||
|
||||
#ifdef MAKECRCH
|
||||
/* write out CRC tables to crc32.h */
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
out = fopen("crc32.h", "w");
|
||||
if (out == NULL) return;
|
||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||
fprintf(out, "local const unsigned long FAR ");
|
||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||
write_table(out, crc_table[0]);
|
||||
# ifdef BYFOUR
|
||||
fprintf(out, "#ifdef BYFOUR\n");
|
||||
for (k = 1; k < 8; k++) {
|
||||
fprintf(out, " },\n {\n");
|
||||
write_table(out, crc_table[k]);
|
||||
}
|
||||
fprintf(out, "#endif\n");
|
||||
# endif /* BYFOUR */
|
||||
fprintf(out, " }\n};\n");
|
||||
fclose(out);
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
}
|
||||
|
||||
#ifdef MAKECRCH
|
||||
local void write_table(out, table)
|
||||
FILE *out;
|
||||
const unsigned long FAR *table;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < 256; n++)
|
||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||
}
|
||||
#endif /* MAKECRCH */
|
||||
|
||||
#else /* !DYNAMIC_CRC_TABLE */
|
||||
/* ========================================================================
|
||||
* Tables of CRC-32s of all single-byte values, made by make_crc_table().
|
||||
*/
|
||||
#include "crc32.h"
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
/* =========================================================================
|
||||
* This function can be used by asm versions of crc32()
|
||||
*/
|
||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
||||
{
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
return (const unsigned long FAR *)crc_table;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
|
||||
#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
|
||||
|
||||
/* ========================================================================= */
|
||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
if (buf == Z_NULL) return 0UL;
|
||||
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
if (crc_table_empty)
|
||||
make_crc_table();
|
||||
#endif /* DYNAMIC_CRC_TABLE */
|
||||
|
||||
#ifdef BYFOUR
|
||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||
u4 endian;
|
||||
|
||||
endian = 1;
|
||||
if (*((unsigned char *)(&endian)))
|
||||
return crc32_little(crc, buf, len);
|
||||
else
|
||||
return crc32_big(crc, buf, len);
|
||||
}
|
||||
#endif /* BYFOUR */
|
||||
crc = crc ^ 0xffffffffUL;
|
||||
while (len >= 8) {
|
||||
DO8;
|
||||
len -= 8;
|
||||
}
|
||||
if (len) do {
|
||||
DO1;
|
||||
} while (--len);
|
||||
return crc ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
#ifdef BYFOUR
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOLIT4 c ^= *buf4++; \
|
||||
c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
|
||||
crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
|
||||
#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_little(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = (u4)crc;
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
while (len >= 32) {
|
||||
DOLIT32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOLIT4;
|
||||
len -= 4;
|
||||
}
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)c;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
#define DOBIG4 c ^= *++buf4; \
|
||||
c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
|
||||
crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
|
||||
#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long crc32_big(crc, buf, len)
|
||||
unsigned long crc;
|
||||
const unsigned char FAR *buf;
|
||||
unsigned len;
|
||||
{
|
||||
register u4 c;
|
||||
register const u4 FAR *buf4;
|
||||
|
||||
c = REV((u4)crc);
|
||||
c = ~c;
|
||||
while (len && ((ptrdiff_t)buf & 3)) {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
len--;
|
||||
}
|
||||
|
||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
||||
buf4--;
|
||||
while (len >= 32) {
|
||||
DOBIG32;
|
||||
len -= 32;
|
||||
}
|
||||
while (len >= 4) {
|
||||
DOBIG4;
|
||||
len -= 4;
|
||||
}
|
||||
buf4++;
|
||||
buf = (const unsigned char FAR *)buf4;
|
||||
|
||||
if (len) do {
|
||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||
} while (--len);
|
||||
c = ~c;
|
||||
return (unsigned long)(REV(c));
|
||||
}
|
||||
|
||||
#endif /* BYFOUR */
|
||||
|
||||
#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
|
||||
|
||||
/* ========================================================================= */
|
||||
local unsigned long gf2_matrix_times(mat, vec)
|
||||
unsigned long *mat;
|
||||
unsigned long vec;
|
||||
{
|
||||
unsigned long sum;
|
||||
|
||||
sum = 0;
|
||||
while (vec) {
|
||||
if (vec & 1)
|
||||
sum ^= *mat;
|
||||
vec >>= 1;
|
||||
mat++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
local void gf2_matrix_square(square, mat)
|
||||
unsigned long *square;
|
||||
unsigned long *mat;
|
||||
{
|
||||
int n;
|
||||
|
||||
for (n = 0; n < GF2_DIM; n++)
|
||||
square[n] = gf2_matrix_times(mat, mat[n]);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
uLong ZEXPORT crc32_combine(crc1, crc2, len2)
|
||||
uLong crc1;
|
||||
uLong crc2;
|
||||
z_off_t len2;
|
||||
{
|
||||
int n;
|
||||
unsigned long row;
|
||||
unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case */
|
||||
if (len2 == 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = 0xedb88320L; /* CRC-32 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
row <<= 1;
|
||||
}
|
||||
|
||||
/* put operator for two zero bits in even */
|
||||
gf2_matrix_square(even, odd);
|
||||
|
||||
/* put operator for four zero bits in odd */
|
||||
gf2_matrix_square(odd, even);
|
||||
|
||||
/* apply len2 zeros to crc1 (first square will put the operator for one
|
||||
zero byte, eight zero bits, in even) */
|
||||
do {
|
||||
/* apply zeros operator for this bit of len2 */
|
||||
gf2_matrix_square(even, odd);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(even, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
if (len2 == 0)
|
||||
break;
|
||||
|
||||
/* another iteration of the loop with odd and even swapped */
|
||||
gf2_matrix_square(odd, even);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(odd, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
} while (len2 != 0);
|
||||
|
||||
/* return combined crc */
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
||||
|
|
|
@ -1,441 +1,441 @@
|
|||
/* crc32.h -- tables for rapid CRC calculation
|
||||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
#ifdef BYFOUR
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
|
||||
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
|
||||
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
|
||||
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
|
||||
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
|
||||
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
|
||||
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
|
||||
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
|
||||
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
|
||||
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
|
||||
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
|
||||
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
|
||||
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
|
||||
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
|
||||
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
|
||||
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
|
||||
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
|
||||
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
|
||||
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
|
||||
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
|
||||
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
|
||||
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
|
||||
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
|
||||
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
|
||||
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
|
||||
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
|
||||
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
|
||||
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
|
||||
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
|
||||
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
|
||||
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
|
||||
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
|
||||
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
|
||||
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
|
||||
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
|
||||
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
|
||||
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
|
||||
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
|
||||
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
|
||||
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
|
||||
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
|
||||
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
|
||||
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
|
||||
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
|
||||
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
|
||||
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
|
||||
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
|
||||
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
|
||||
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
|
||||
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
|
||||
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
|
||||
0x9324fd72UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
|
||||
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
|
||||
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
|
||||
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
|
||||
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
|
||||
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
|
||||
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
|
||||
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
|
||||
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
|
||||
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
|
||||
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
|
||||
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
|
||||
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
|
||||
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
|
||||
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
|
||||
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
|
||||
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
|
||||
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
|
||||
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
|
||||
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
|
||||
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
|
||||
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
|
||||
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
|
||||
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
|
||||
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
|
||||
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
|
||||
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
|
||||
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
|
||||
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
|
||||
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
|
||||
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
|
||||
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
|
||||
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
|
||||
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
|
||||
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
|
||||
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
|
||||
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
|
||||
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
|
||||
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
|
||||
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
|
||||
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
|
||||
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
|
||||
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
|
||||
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
|
||||
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
|
||||
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
|
||||
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
|
||||
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
|
||||
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
|
||||
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
|
||||
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
|
||||
0xbe9834edUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
|
||||
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
|
||||
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
|
||||
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
|
||||
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
|
||||
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
|
||||
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
|
||||
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
|
||||
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
|
||||
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
|
||||
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
|
||||
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
|
||||
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
|
||||
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
|
||||
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
|
||||
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
|
||||
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
|
||||
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
|
||||
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
|
||||
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
|
||||
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
|
||||
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
|
||||
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
|
||||
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
|
||||
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
|
||||
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
|
||||
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
|
||||
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
|
||||
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
|
||||
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
|
||||
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
|
||||
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
|
||||
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
|
||||
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
|
||||
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
|
||||
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
|
||||
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
|
||||
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
|
||||
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
|
||||
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
|
||||
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
|
||||
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
|
||||
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
|
||||
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
|
||||
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
|
||||
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
|
||||
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
|
||||
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
|
||||
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
|
||||
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
|
||||
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
|
||||
0xde0506f1UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
|
||||
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
|
||||
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
|
||||
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
|
||||
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
|
||||
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
|
||||
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
|
||||
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
|
||||
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
|
||||
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
|
||||
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
|
||||
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
|
||||
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
|
||||
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
|
||||
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
|
||||
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
|
||||
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
|
||||
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
|
||||
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
|
||||
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
|
||||
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
|
||||
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
|
||||
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
|
||||
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
|
||||
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
|
||||
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
|
||||
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
|
||||
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
|
||||
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
|
||||
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
|
||||
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
|
||||
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
|
||||
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
|
||||
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
|
||||
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
|
||||
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
|
||||
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
|
||||
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
|
||||
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
|
||||
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
|
||||
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
|
||||
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
|
||||
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
|
||||
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
|
||||
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
|
||||
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
|
||||
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
|
||||
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
|
||||
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
|
||||
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
|
||||
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
|
||||
0x8def022dUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
|
||||
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
|
||||
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
|
||||
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
|
||||
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
|
||||
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
|
||||
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
|
||||
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
|
||||
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
|
||||
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
|
||||
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
|
||||
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
|
||||
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
|
||||
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
|
||||
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
|
||||
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
|
||||
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
|
||||
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
|
||||
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
|
||||
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
|
||||
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
|
||||
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
|
||||
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
|
||||
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
|
||||
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
|
||||
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
|
||||
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
|
||||
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
|
||||
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
|
||||
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
|
||||
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
|
||||
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
|
||||
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
|
||||
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
|
||||
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
|
||||
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
|
||||
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
|
||||
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
|
||||
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
|
||||
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
|
||||
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
|
||||
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
|
||||
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
|
||||
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
|
||||
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
|
||||
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
|
||||
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
|
||||
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
|
||||
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
|
||||
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
|
||||
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
|
||||
0x72fd2493UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
|
||||
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
|
||||
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
|
||||
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
|
||||
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
|
||||
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
|
||||
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
|
||||
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
|
||||
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
|
||||
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
|
||||
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
|
||||
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
|
||||
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
|
||||
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
|
||||
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
|
||||
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
|
||||
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
|
||||
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
|
||||
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
|
||||
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
|
||||
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
|
||||
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
|
||||
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
|
||||
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
|
||||
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
|
||||
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
|
||||
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
|
||||
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
|
||||
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
|
||||
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
|
||||
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
|
||||
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
|
||||
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
|
||||
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
|
||||
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
|
||||
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
|
||||
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
|
||||
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
|
||||
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
|
||||
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
|
||||
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
|
||||
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
|
||||
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
|
||||
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
|
||||
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
|
||||
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
|
||||
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
|
||||
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
|
||||
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
|
||||
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
|
||||
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
|
||||
0xed3498beUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
|
||||
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
|
||||
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
|
||||
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
|
||||
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
|
||||
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
|
||||
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
|
||||
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
|
||||
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
|
||||
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
|
||||
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
|
||||
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
|
||||
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
|
||||
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
|
||||
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
|
||||
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
|
||||
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
|
||||
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
|
||||
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
|
||||
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
|
||||
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
|
||||
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
|
||||
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
|
||||
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
|
||||
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
|
||||
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
|
||||
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
|
||||
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
|
||||
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
|
||||
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
|
||||
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
|
||||
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
|
||||
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
|
||||
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
|
||||
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
|
||||
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
|
||||
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
|
||||
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
|
||||
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
|
||||
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
|
||||
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
|
||||
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
|
||||
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
|
||||
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
|
||||
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
|
||||
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
|
||||
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
|
||||
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
|
||||
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
|
||||
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
|
||||
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
|
||||
0xf10605deUL
|
||||
#endif
|
||||
}
|
||||
};
|
||||
/* crc32.h -- tables for rapid CRC calculation
|
||||
* Generated automatically by crc32.c
|
||||
*/
|
||||
|
||||
local const unsigned long FAR crc_table[TBLS][256] =
|
||||
{
|
||||
{
|
||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
|
||||
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
|
||||
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
|
||||
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
|
||||
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
|
||||
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
|
||||
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
|
||||
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
|
||||
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
|
||||
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
|
||||
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
|
||||
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
|
||||
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
|
||||
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
|
||||
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
|
||||
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
|
||||
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
|
||||
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
|
||||
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
|
||||
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
|
||||
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
|
||||
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
|
||||
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
|
||||
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
|
||||
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
|
||||
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
|
||||
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
|
||||
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
|
||||
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
|
||||
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
|
||||
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
|
||||
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
|
||||
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
|
||||
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
|
||||
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
|
||||
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
|
||||
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
|
||||
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
|
||||
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
|
||||
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
|
||||
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
|
||||
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
|
||||
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
|
||||
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
|
||||
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
|
||||
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
|
||||
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
|
||||
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
|
||||
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
|
||||
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
|
||||
0x2d02ef8dUL
|
||||
#ifdef BYFOUR
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
|
||||
0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
|
||||
0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
|
||||
0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
|
||||
0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
|
||||
0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
|
||||
0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
|
||||
0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
|
||||
0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
|
||||
0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
|
||||
0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
|
||||
0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
|
||||
0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
|
||||
0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
|
||||
0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
|
||||
0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
|
||||
0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
|
||||
0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
|
||||
0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
|
||||
0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
|
||||
0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
|
||||
0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
|
||||
0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
|
||||
0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
|
||||
0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
|
||||
0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
|
||||
0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
|
||||
0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
|
||||
0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
|
||||
0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
|
||||
0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
|
||||
0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
|
||||
0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
|
||||
0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
|
||||
0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
|
||||
0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
|
||||
0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
|
||||
0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
|
||||
0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
|
||||
0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
|
||||
0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
|
||||
0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
|
||||
0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
|
||||
0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
|
||||
0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
|
||||
0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
|
||||
0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
|
||||
0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
|
||||
0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
|
||||
0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
|
||||
0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
|
||||
0x9324fd72UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
|
||||
0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
|
||||
0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
|
||||
0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
|
||||
0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
|
||||
0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
|
||||
0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
|
||||
0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
|
||||
0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
|
||||
0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
|
||||
0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
|
||||
0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
|
||||
0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
|
||||
0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
|
||||
0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
|
||||
0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
|
||||
0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
|
||||
0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
|
||||
0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
|
||||
0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
|
||||
0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
|
||||
0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
|
||||
0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
|
||||
0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
|
||||
0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
|
||||
0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
|
||||
0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
|
||||
0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
|
||||
0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
|
||||
0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
|
||||
0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
|
||||
0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
|
||||
0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
|
||||
0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
|
||||
0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
|
||||
0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
|
||||
0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
|
||||
0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
|
||||
0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
|
||||
0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
|
||||
0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
|
||||
0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
|
||||
0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
|
||||
0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
|
||||
0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
|
||||
0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
|
||||
0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
|
||||
0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
|
||||
0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
|
||||
0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
|
||||
0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
|
||||
0xbe9834edUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
|
||||
0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
|
||||
0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
|
||||
0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
|
||||
0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
|
||||
0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
|
||||
0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
|
||||
0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
|
||||
0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
|
||||
0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
|
||||
0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
|
||||
0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
|
||||
0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
|
||||
0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
|
||||
0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
|
||||
0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
|
||||
0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
|
||||
0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
|
||||
0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
|
||||
0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
|
||||
0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
|
||||
0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
|
||||
0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
|
||||
0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
|
||||
0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
|
||||
0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
|
||||
0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
|
||||
0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
|
||||
0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
|
||||
0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
|
||||
0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
|
||||
0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
|
||||
0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
|
||||
0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
|
||||
0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
|
||||
0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
|
||||
0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
|
||||
0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
|
||||
0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
|
||||
0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
|
||||
0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
|
||||
0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
|
||||
0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
|
||||
0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
|
||||
0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
|
||||
0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
|
||||
0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
|
||||
0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
|
||||
0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
|
||||
0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
|
||||
0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
|
||||
0xde0506f1UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
|
||||
0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
|
||||
0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
|
||||
0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
|
||||
0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
|
||||
0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
|
||||
0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
|
||||
0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
|
||||
0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
|
||||
0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
|
||||
0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
|
||||
0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
|
||||
0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
|
||||
0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
|
||||
0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
|
||||
0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
|
||||
0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
|
||||
0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
|
||||
0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
|
||||
0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
|
||||
0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
|
||||
0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
|
||||
0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
|
||||
0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
|
||||
0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
|
||||
0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
|
||||
0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
|
||||
0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
|
||||
0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
|
||||
0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
|
||||
0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
|
||||
0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
|
||||
0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
|
||||
0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
|
||||
0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
|
||||
0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
|
||||
0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
|
||||
0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
|
||||
0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
|
||||
0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
|
||||
0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
|
||||
0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
|
||||
0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
|
||||
0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
|
||||
0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
|
||||
0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
|
||||
0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
|
||||
0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
|
||||
0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
|
||||
0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
|
||||
0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
|
||||
0x8def022dUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
|
||||
0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
|
||||
0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
|
||||
0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
|
||||
0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
|
||||
0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
|
||||
0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
|
||||
0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
|
||||
0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
|
||||
0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
|
||||
0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
|
||||
0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
|
||||
0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
|
||||
0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
|
||||
0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
|
||||
0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
|
||||
0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
|
||||
0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
|
||||
0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
|
||||
0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
|
||||
0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
|
||||
0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
|
||||
0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
|
||||
0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
|
||||
0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
|
||||
0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
|
||||
0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
|
||||
0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
|
||||
0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
|
||||
0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
|
||||
0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
|
||||
0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
|
||||
0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
|
||||
0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
|
||||
0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
|
||||
0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
|
||||
0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
|
||||
0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
|
||||
0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
|
||||
0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
|
||||
0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
|
||||
0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
|
||||
0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
|
||||
0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
|
||||
0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
|
||||
0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
|
||||
0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
|
||||
0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
|
||||
0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
|
||||
0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
|
||||
0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
|
||||
0x72fd2493UL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
|
||||
0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
|
||||
0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
|
||||
0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
|
||||
0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
|
||||
0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
|
||||
0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
|
||||
0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
|
||||
0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
|
||||
0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
|
||||
0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
|
||||
0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
|
||||
0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
|
||||
0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
|
||||
0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
|
||||
0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
|
||||
0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
|
||||
0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
|
||||
0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
|
||||
0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
|
||||
0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
|
||||
0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
|
||||
0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
|
||||
0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
|
||||
0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
|
||||
0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
|
||||
0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
|
||||
0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
|
||||
0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
|
||||
0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
|
||||
0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
|
||||
0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
|
||||
0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
|
||||
0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
|
||||
0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
|
||||
0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
|
||||
0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
|
||||
0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
|
||||
0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
|
||||
0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
|
||||
0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
|
||||
0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
|
||||
0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
|
||||
0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
|
||||
0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
|
||||
0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
|
||||
0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
|
||||
0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
|
||||
0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
|
||||
0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
|
||||
0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
|
||||
0xed3498beUL
|
||||
},
|
||||
{
|
||||
0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
|
||||
0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
|
||||
0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
|
||||
0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
|
||||
0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
|
||||
0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
|
||||
0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
|
||||
0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
|
||||
0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
|
||||
0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
|
||||
0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
|
||||
0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
|
||||
0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
|
||||
0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
|
||||
0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
|
||||
0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
|
||||
0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
|
||||
0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
|
||||
0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
|
||||
0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
|
||||
0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
|
||||
0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
|
||||
0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
|
||||
0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
|
||||
0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
|
||||
0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
|
||||
0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
|
||||
0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
|
||||
0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
|
||||
0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
|
||||
0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
|
||||
0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
|
||||
0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
|
||||
0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
|
||||
0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
|
||||
0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
|
||||
0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
|
||||
0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
|
||||
0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
|
||||
0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
|
||||
0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
|
||||
0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
|
||||
0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
|
||||
0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
|
||||
0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
|
||||
0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
|
||||
0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
|
||||
0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
|
||||
0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
|
||||
0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
|
||||
0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
|
||||
0xf10605deUL
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,331 +1,331 @@
|
|||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2004 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef DEFLATE_H
|
||||
#define DEFLATE_H
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip encoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
# define GZIP
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Internal compression state.
|
||||
*/
|
||||
|
||||
#define LENGTH_CODES 29
|
||||
/* number of length codes, not counting the special END_BLOCK code */
|
||||
|
||||
#define LITERALS 256
|
||||
/* number of literal bytes 0..255 */
|
||||
|
||||
#define L_CODES (LITERALS+1+LENGTH_CODES)
|
||||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||||
|
||||
#define D_CODES 30
|
||||
/* number of distance codes */
|
||||
|
||||
#define BL_CODES 19
|
||||
/* number of codes used to transfer the bit lengths */
|
||||
|
||||
#define HEAP_SIZE (2*L_CODES+1)
|
||||
/* maximum heap size */
|
||||
|
||||
#define MAX_BITS 15
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
|
||||
#define INIT_STATE 42
|
||||
#define EXTRA_STATE 69
|
||||
#define NAME_STATE 73
|
||||
#define COMMENT_STATE 91
|
||||
#define HCRC_STATE 103
|
||||
#define BUSY_STATE 113
|
||||
#define FINISH_STATE 666
|
||||
/* Stream status */
|
||||
|
||||
|
||||
/* Data structure describing a single value and its code string. */
|
||||
typedef struct ct_data_s {
|
||||
union {
|
||||
ush freq; /* frequency count */
|
||||
ush code; /* bit string */
|
||||
} fc;
|
||||
union {
|
||||
ush dad; /* father node in Huffman tree */
|
||||
ush len; /* length of bit string */
|
||||
} dl;
|
||||
} FAR ct_data;
|
||||
|
||||
#define Freq fc.freq
|
||||
#define Code fc.code
|
||||
#define Dad dl.dad
|
||||
#define Len dl.len
|
||||
|
||||
typedef struct static_tree_desc_s static_tree_desc;
|
||||
|
||||
typedef struct tree_desc_s {
|
||||
ct_data *dyn_tree; /* the dynamic tree */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
} FAR tree_desc;
|
||||
|
||||
typedef ush Pos;
|
||||
typedef Pos FAR Posf;
|
||||
typedef unsigned IPos;
|
||||
|
||||
/* A Pos is an index in the character window. We use short instead of int to
|
||||
* save space in the various tables. IPos is used only for parameter passing.
|
||||
*/
|
||||
|
||||
typedef struct internal_state {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
int status; /* as the name implies */
|
||||
Bytef *pending_buf; /* output still pending */
|
||||
ulg pending_buf_size; /* size of pending_buf */
|
||||
Bytef *pending_out; /* next pending byte to output to the stream */
|
||||
uInt pending; /* nb of bytes in the pending buffer */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
gz_headerp gzhead; /* gzip header information to write */
|
||||
uInt gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
|
||||
uInt w_size; /* LZ77 window size (32K by default) */
|
||||
uInt w_bits; /* log2(w_size) (8..16) */
|
||||
uInt w_mask; /* w_size - 1 */
|
||||
|
||||
Bytef *window;
|
||||
/* Sliding window. Input bytes are read into the second half of the window,
|
||||
* and move to the first half later to keep a dictionary of at least wSize
|
||||
* bytes. With this organization, matches are limited to a distance of
|
||||
* wSize-MAX_MATCH bytes, but this ensures that IO is always
|
||||
* performed with a length multiple of the block size. Also, it limits
|
||||
* the window size to 64K, which is quite useful on MSDOS.
|
||||
* To do: use the user input buffer as sliding window.
|
||||
*/
|
||||
|
||||
ulg window_size;
|
||||
/* Actual size of window: 2*wSize, except when the user input buffer
|
||||
* is directly used as sliding window.
|
||||
*/
|
||||
|
||||
Posf *prev;
|
||||
/* Link to older string with same hash index. To limit the size of this
|
||||
* array to 64K, this link is maintained only for the last 32K strings.
|
||||
* An index in this array is thus a window index modulo 32K.
|
||||
*/
|
||||
|
||||
Posf *head; /* Heads of the hash chains or NIL. */
|
||||
|
||||
uInt ins_h; /* hash index of string to be inserted */
|
||||
uInt hash_size; /* number of elements in hash table */
|
||||
uInt hash_bits; /* log2(hash_size) */
|
||||
uInt hash_mask; /* hash_size-1 */
|
||||
|
||||
uInt hash_shift;
|
||||
/* Number of bits by which ins_h must be shifted at each input
|
||||
* step. It must be such that after MIN_MATCH steps, the oldest
|
||||
* byte no longer takes part in the hash key, that is:
|
||||
* hash_shift * MIN_MATCH >= hash_bits
|
||||
*/
|
||||
|
||||
long block_start;
|
||||
/* Window position at the beginning of the current output block. Gets
|
||||
* negative when the window is moved backwards.
|
||||
*/
|
||||
|
||||
uInt match_length; /* length of best match */
|
||||
IPos prev_match; /* previous match */
|
||||
int match_available; /* set if previous match exists */
|
||||
uInt strstart; /* start of string to insert */
|
||||
uInt match_start; /* start of matching string */
|
||||
uInt lookahead; /* number of valid bytes ahead in window */
|
||||
|
||||
uInt prev_length;
|
||||
/* Length of the best match at previous step. Matches not greater than this
|
||||
* are discarded. This is used in the lazy match evaluation.
|
||||
*/
|
||||
|
||||
uInt max_chain_length;
|
||||
/* To speed up deflation, hash chains are never searched beyond this
|
||||
* length. A higher limit improves compression ratio but degrades the
|
||||
* speed.
|
||||
*/
|
||||
|
||||
uInt max_lazy_match;
|
||||
/* Attempt to find a better match only when the current match is strictly
|
||||
* smaller than this value. This mechanism is used only for compression
|
||||
* levels >= 4.
|
||||
*/
|
||||
# define max_insert_length max_lazy_match
|
||||
/* Insert new strings in the hash table only if the match length is not
|
||||
* greater than this length. This saves time but degrades compression.
|
||||
* max_insert_length is used only for compression levels <= 3.
|
||||
*/
|
||||
|
||||
int level; /* compression level (1..9) */
|
||||
int strategy; /* favor or force Huffman coding*/
|
||||
|
||||
uInt good_match;
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||
|
||||
struct tree_desc_s l_desc; /* desc. for literal tree */
|
||||
struct tree_desc_s d_desc; /* desc. for distance tree */
|
||||
struct tree_desc_s bl_desc; /* desc. for bit length tree */
|
||||
|
||||
ush bl_count[MAX_BITS+1];
|
||||
/* number of codes at each bit length for an optimal tree */
|
||||
|
||||
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
|
||||
int heap_len; /* number of elements in the heap */
|
||||
int heap_max; /* element of largest frequency */
|
||||
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
|
||||
* The same heap array is used to build all trees.
|
||||
*/
|
||||
|
||||
uch depth[2*L_CODES+1];
|
||||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
uchf *l_buf; /* buffer for literals or lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
* limiting lit_bufsize to 64K:
|
||||
* - frequencies can be kept in 16 bit counters
|
||||
* - if compression is not successful for the first block, all input
|
||||
* data is still in the window so we can still emit a stored block even
|
||||
* when input comes from standard input. (This can also be done for
|
||||
* all blocks if lit_bufsize is not greater than 32K.)
|
||||
* - if compression is not successful for a file smaller than 64K, we can
|
||||
* even emit a stored file instead of a stored block (saving 5 bytes).
|
||||
* This is applicable only for zip (not gzip or zlib).
|
||||
* - creating new Huffman trees less frequently may not provide fast
|
||||
* adaptation to changes in the input data statistics. (Take for
|
||||
* example a binary file with poorly compressible code followed by
|
||||
* a highly compressible string table.) Smaller buffer sizes give
|
||||
* fast adaptation but have of course the overhead of transmitting
|
||||
* trees more frequently.
|
||||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
uInt last_lit; /* running index in l_buf */
|
||||
|
||||
ushf *d_buf;
|
||||
/* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
* the same number of elements. To use different lengths, an extra flag
|
||||
* array would be necessary.
|
||||
*/
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
int last_eob_len; /* bit length of EOB code for last block */
|
||||
|
||||
#ifdef DEBUG
|
||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
|
||||
#endif
|
||||
|
||||
ush bi_buf;
|
||||
/* Output buffer. bits are inserted starting at the bottom (least
|
||||
* significant bits).
|
||||
*/
|
||||
int bi_valid;
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
} FAR deflate_state;
|
||||
|
||||
/* Output a byte on the stream.
|
||||
* IN assertion: there is enough room in pending_buf.
|
||||
*/
|
||||
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
|
||||
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
/* in trees.c */
|
||||
void _tr_init OF((deflate_state *s));
|
||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void _tr_align OF((deflate_state *s));
|
||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
|
||||
#define d_code(dist) \
|
||||
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
||||
/* Mapping from a distance to a distance code. dist is the distance - 1 and
|
||||
* must not have side effects. _dist_code[256] and _dist_code[257] are never
|
||||
* used.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
/* Inline versions of _tr_tally for speed: */
|
||||
|
||||
#if defined(GEN_TREES_H) || !defined(STDC)
|
||||
extern uch _length_code[];
|
||||
extern uch _dist_code[];
|
||||
#else
|
||||
extern const uch _length_code[];
|
||||
extern const uch _dist_code[];
|
||||
#endif
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
{ uch cc = (c); \
|
||||
s->d_buf[s->last_lit] = 0; \
|
||||
s->l_buf[s->last_lit++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (length); \
|
||||
ush dist = (distance); \
|
||||
s->d_buf[s->last_lit] = dist; \
|
||||
s->l_buf[s->last_lit++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
}
|
||||
#else
|
||||
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
flush = _tr_tally(s, distance, length)
|
||||
#endif
|
||||
|
||||
#endif /* DEFLATE_H */
|
||||
/* deflate.h -- internal compression state
|
||||
* Copyright (C) 1995-2004 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef DEFLATE_H
|
||||
#define DEFLATE_H
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer creation by deflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip encoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
# define GZIP
|
||||
#endif
|
||||
|
||||
/* ===========================================================================
|
||||
* Internal compression state.
|
||||
*/
|
||||
|
||||
#define LENGTH_CODES 29
|
||||
/* number of length codes, not counting the special END_BLOCK code */
|
||||
|
||||
#define LITERALS 256
|
||||
/* number of literal bytes 0..255 */
|
||||
|
||||
#define L_CODES (LITERALS+1+LENGTH_CODES)
|
||||
/* number of Literal or Length codes, including the END_BLOCK code */
|
||||
|
||||
#define D_CODES 30
|
||||
/* number of distance codes */
|
||||
|
||||
#define BL_CODES 19
|
||||
/* number of codes used to transfer the bit lengths */
|
||||
|
||||
#define HEAP_SIZE (2*L_CODES+1)
|
||||
/* maximum heap size */
|
||||
|
||||
#define MAX_BITS 15
|
||||
/* All codes must not exceed MAX_BITS bits */
|
||||
|
||||
#define INIT_STATE 42
|
||||
#define EXTRA_STATE 69
|
||||
#define NAME_STATE 73
|
||||
#define COMMENT_STATE 91
|
||||
#define HCRC_STATE 103
|
||||
#define BUSY_STATE 113
|
||||
#define FINISH_STATE 666
|
||||
/* Stream status */
|
||||
|
||||
|
||||
/* Data structure describing a single value and its code string. */
|
||||
typedef struct ct_data_s {
|
||||
union {
|
||||
ush freq; /* frequency count */
|
||||
ush code; /* bit string */
|
||||
} fc;
|
||||
union {
|
||||
ush dad; /* father node in Huffman tree */
|
||||
ush len; /* length of bit string */
|
||||
} dl;
|
||||
} FAR ct_data;
|
||||
|
||||
#define Freq fc.freq
|
||||
#define Code fc.code
|
||||
#define Dad dl.dad
|
||||
#define Len dl.len
|
||||
|
||||
typedef struct static_tree_desc_s static_tree_desc;
|
||||
|
||||
typedef struct tree_desc_s {
|
||||
ct_data *dyn_tree; /* the dynamic tree */
|
||||
int max_code; /* largest code with non zero frequency */
|
||||
static_tree_desc *stat_desc; /* the corresponding static tree */
|
||||
} FAR tree_desc;
|
||||
|
||||
typedef ush Pos;
|
||||
typedef Pos FAR Posf;
|
||||
typedef unsigned IPos;
|
||||
|
||||
/* A Pos is an index in the character window. We use short instead of int to
|
||||
* save space in the various tables. IPos is used only for parameter passing.
|
||||
*/
|
||||
|
||||
typedef struct internal_state {
|
||||
z_streamp strm; /* pointer back to this zlib stream */
|
||||
int status; /* as the name implies */
|
||||
Bytef *pending_buf; /* output still pending */
|
||||
ulg pending_buf_size; /* size of pending_buf */
|
||||
Bytef *pending_out; /* next pending byte to output to the stream */
|
||||
uInt pending; /* nb of bytes in the pending buffer */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
gz_headerp gzhead; /* gzip header information to write */
|
||||
uInt gzindex; /* where in extra, name, or comment */
|
||||
Byte method; /* STORED (for zip only) or DEFLATED */
|
||||
int last_flush; /* value of flush param for previous deflate call */
|
||||
|
||||
/* used by deflate.c: */
|
||||
|
||||
uInt w_size; /* LZ77 window size (32K by default) */
|
||||
uInt w_bits; /* log2(w_size) (8..16) */
|
||||
uInt w_mask; /* w_size - 1 */
|
||||
|
||||
Bytef *window;
|
||||
/* Sliding window. Input bytes are read into the second half of the window,
|
||||
* and move to the first half later to keep a dictionary of at least wSize
|
||||
* bytes. With this organization, matches are limited to a distance of
|
||||
* wSize-MAX_MATCH bytes, but this ensures that IO is always
|
||||
* performed with a length multiple of the block size. Also, it limits
|
||||
* the window size to 64K, which is quite useful on MSDOS.
|
||||
* To do: use the user input buffer as sliding window.
|
||||
*/
|
||||
|
||||
ulg window_size;
|
||||
/* Actual size of window: 2*wSize, except when the user input buffer
|
||||
* is directly used as sliding window.
|
||||
*/
|
||||
|
||||
Posf *prev;
|
||||
/* Link to older string with same hash index. To limit the size of this
|
||||
* array to 64K, this link is maintained only for the last 32K strings.
|
||||
* An index in this array is thus a window index modulo 32K.
|
||||
*/
|
||||
|
||||
Posf *head; /* Heads of the hash chains or NIL. */
|
||||
|
||||
uInt ins_h; /* hash index of string to be inserted */
|
||||
uInt hash_size; /* number of elements in hash table */
|
||||
uInt hash_bits; /* log2(hash_size) */
|
||||
uInt hash_mask; /* hash_size-1 */
|
||||
|
||||
uInt hash_shift;
|
||||
/* Number of bits by which ins_h must be shifted at each input
|
||||
* step. It must be such that after MIN_MATCH steps, the oldest
|
||||
* byte no longer takes part in the hash key, that is:
|
||||
* hash_shift * MIN_MATCH >= hash_bits
|
||||
*/
|
||||
|
||||
long block_start;
|
||||
/* Window position at the beginning of the current output block. Gets
|
||||
* negative when the window is moved backwards.
|
||||
*/
|
||||
|
||||
uInt match_length; /* length of best match */
|
||||
IPos prev_match; /* previous match */
|
||||
int match_available; /* set if previous match exists */
|
||||
uInt strstart; /* start of string to insert */
|
||||
uInt match_start; /* start of matching string */
|
||||
uInt lookahead; /* number of valid bytes ahead in window */
|
||||
|
||||
uInt prev_length;
|
||||
/* Length of the best match at previous step. Matches not greater than this
|
||||
* are discarded. This is used in the lazy match evaluation.
|
||||
*/
|
||||
|
||||
uInt max_chain_length;
|
||||
/* To speed up deflation, hash chains are never searched beyond this
|
||||
* length. A higher limit improves compression ratio but degrades the
|
||||
* speed.
|
||||
*/
|
||||
|
||||
uInt max_lazy_match;
|
||||
/* Attempt to find a better match only when the current match is strictly
|
||||
* smaller than this value. This mechanism is used only for compression
|
||||
* levels >= 4.
|
||||
*/
|
||||
# define max_insert_length max_lazy_match
|
||||
/* Insert new strings in the hash table only if the match length is not
|
||||
* greater than this length. This saves time but degrades compression.
|
||||
* max_insert_length is used only for compression levels <= 3.
|
||||
*/
|
||||
|
||||
int level; /* compression level (1..9) */
|
||||
int strategy; /* favor or force Huffman coding*/
|
||||
|
||||
uInt good_match;
|
||||
/* Use a faster search when the previous match is longer than this */
|
||||
|
||||
int nice_match; /* Stop searching when current match exceeds this */
|
||||
|
||||
/* used by trees.c: */
|
||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
||||
struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||
|
||||
struct tree_desc_s l_desc; /* desc. for literal tree */
|
||||
struct tree_desc_s d_desc; /* desc. for distance tree */
|
||||
struct tree_desc_s bl_desc; /* desc. for bit length tree */
|
||||
|
||||
ush bl_count[MAX_BITS+1];
|
||||
/* number of codes at each bit length for an optimal tree */
|
||||
|
||||
int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
|
||||
int heap_len; /* number of elements in the heap */
|
||||
int heap_max; /* element of largest frequency */
|
||||
/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
|
||||
* The same heap array is used to build all trees.
|
||||
*/
|
||||
|
||||
uch depth[2*L_CODES+1];
|
||||
/* Depth of each subtree used as tie breaker for trees of equal frequency
|
||||
*/
|
||||
|
||||
uchf *l_buf; /* buffer for literals or lengths */
|
||||
|
||||
uInt lit_bufsize;
|
||||
/* Size of match buffer for literals/lengths. There are 4 reasons for
|
||||
* limiting lit_bufsize to 64K:
|
||||
* - frequencies can be kept in 16 bit counters
|
||||
* - if compression is not successful for the first block, all input
|
||||
* data is still in the window so we can still emit a stored block even
|
||||
* when input comes from standard input. (This can also be done for
|
||||
* all blocks if lit_bufsize is not greater than 32K.)
|
||||
* - if compression is not successful for a file smaller than 64K, we can
|
||||
* even emit a stored file instead of a stored block (saving 5 bytes).
|
||||
* This is applicable only for zip (not gzip or zlib).
|
||||
* - creating new Huffman trees less frequently may not provide fast
|
||||
* adaptation to changes in the input data statistics. (Take for
|
||||
* example a binary file with poorly compressible code followed by
|
||||
* a highly compressible string table.) Smaller buffer sizes give
|
||||
* fast adaptation but have of course the overhead of transmitting
|
||||
* trees more frequently.
|
||||
* - I can't count above 4
|
||||
*/
|
||||
|
||||
uInt last_lit; /* running index in l_buf */
|
||||
|
||||
ushf *d_buf;
|
||||
/* Buffer for distances. To simplify the code, d_buf and l_buf have
|
||||
* the same number of elements. To use different lengths, an extra flag
|
||||
* array would be necessary.
|
||||
*/
|
||||
|
||||
ulg opt_len; /* bit length of current block with optimal trees */
|
||||
ulg static_len; /* bit length of current block with static trees */
|
||||
uInt matches; /* number of string matches in current block */
|
||||
int last_eob_len; /* bit length of EOB code for last block */
|
||||
|
||||
#ifdef DEBUG
|
||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||
ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
|
||||
#endif
|
||||
|
||||
ush bi_buf;
|
||||
/* Output buffer. bits are inserted starting at the bottom (least
|
||||
* significant bits).
|
||||
*/
|
||||
int bi_valid;
|
||||
/* Number of valid bits in bi_buf. All bits above the last valid bit
|
||||
* are always zero.
|
||||
*/
|
||||
|
||||
} FAR deflate_state;
|
||||
|
||||
/* Output a byte on the stream.
|
||||
* IN assertion: there is enough room in pending_buf.
|
||||
*/
|
||||
#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
|
||||
|
||||
|
||||
#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
|
||||
/* Minimum amount of lookahead, except at the end of the input file.
|
||||
* See deflate.c for comments about the MIN_MATCH+1.
|
||||
*/
|
||||
|
||||
#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
|
||||
/* In order to simplify the code, particularly on 16 bit machines, match
|
||||
* distances are limited to MAX_DIST instead of WSIZE.
|
||||
*/
|
||||
|
||||
/* in trees.c */
|
||||
void _tr_init OF((deflate_state *s));
|
||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
void _tr_align OF((deflate_state *s));
|
||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||
int eof));
|
||||
|
||||
#define d_code(dist) \
|
||||
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
||||
/* Mapping from a distance to a distance code. dist is the distance - 1 and
|
||||
* must not have side effects. _dist_code[256] and _dist_code[257] are never
|
||||
* used.
|
||||
*/
|
||||
|
||||
#ifndef DEBUG
|
||||
/* Inline versions of _tr_tally for speed: */
|
||||
|
||||
#if defined(GEN_TREES_H) || !defined(STDC)
|
||||
extern uch _length_code[];
|
||||
extern uch _dist_code[];
|
||||
#else
|
||||
extern const uch _length_code[];
|
||||
extern const uch _dist_code[];
|
||||
#endif
|
||||
|
||||
# define _tr_tally_lit(s, c, flush) \
|
||||
{ uch cc = (c); \
|
||||
s->d_buf[s->last_lit] = 0; \
|
||||
s->l_buf[s->last_lit++] = cc; \
|
||||
s->dyn_ltree[cc].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
}
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
{ uch len = (length); \
|
||||
ush dist = (distance); \
|
||||
s->d_buf[s->last_lit] = dist; \
|
||||
s->l_buf[s->last_lit++] = len; \
|
||||
dist--; \
|
||||
s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
|
||||
s->dyn_dtree[d_code(dist)].Freq++; \
|
||||
flush = (s->last_lit == s->lit_bufsize-1); \
|
||||
}
|
||||
#else
|
||||
# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
|
||||
# define _tr_tally_dist(s, distance, length, flush) \
|
||||
flush = _tr_tally(s, distance, length)
|
||||
#endif
|
||||
|
||||
#endif /* DEFLATE_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,318 +1,318 @@
|
|||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
|
||||
#ifndef ASMINF
|
||||
|
||||
/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||
Based on testing to date,
|
||||
Pre-increment preferred for:
|
||||
- PowerPC G3 (Adler)
|
||||
- MIPS R5000 (Randers-Pehrson)
|
||||
Post-increment preferred for:
|
||||
- none
|
||||
No measurable difference:
|
||||
- Pentium III (Anderson)
|
||||
- M68060 (Nikl)
|
||||
*/
|
||||
#ifdef POSTINC
|
||||
# define OFF 0
|
||||
# define PUP(a) *(a)++
|
||||
#else
|
||||
# define OFF 1
|
||||
# define PUP(a) *++(a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
literal and match bytes until either not enough input or output is
|
||||
available, an end-of-block is encountered, or a data error is encountered.
|
||||
When large enough input and output buffers are supplied to inflate(), for
|
||||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||||
inflate execution time is spent in this routine.
|
||||
|
||||
Entry assumptions:
|
||||
|
||||
state->mode == LEN
|
||||
strm->avail_in >= 6
|
||||
strm->avail_out >= 258
|
||||
start >= strm->avail_out
|
||||
state->bits < 8
|
||||
|
||||
On return, state->mode is one of:
|
||||
|
||||
LEN -- ran out of enough output space or enough available input
|
||||
TYPE -- reached end of block code, inflate() to interpret next block
|
||||
BAD -- error in block data
|
||||
|
||||
Notes:
|
||||
|
||||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||||
Therefore if strm->avail_in >= 6, then there is enough input to avoid
|
||||
checking for available input while decoding.
|
||||
|
||||
- The maximum bytes that a single length/distance pair can output is 258
|
||||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void inflate_fast(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
code const FAR *lcode; /* local strm->lencode */
|
||||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code this; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char FAR *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
in = strm->next_in - OFF;
|
||||
last = in + (strm->avail_in - 5);
|
||||
out = strm->next_out - OFF;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - 257);
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
write = state->write;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
PUP(out) = (unsigned char)(this.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
from = window - OFF;
|
||||
if (write == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (write < op) { /* wrap around window */
|
||||
from += wsize + write - op;
|
||||
op -= write;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = window - OFF;
|
||||
if (write < len) { /* some from start of window */
|
||||
op = write;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += write - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
else {
|
||||
from = out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
this = dcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
this = lcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in + OFF;
|
||||
strm->next_out = out + OFF;
|
||||
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||
strm->avail_out = (unsigned)(out < end ?
|
||||
257 + (end - out) : 257 - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
|
||||
- Using bit fields for code structure
|
||||
- Different op definition to avoid & for extra bits (do & for table bits)
|
||||
- Three separate decoding do-loops for direct, window, and write == 0
|
||||
- Special case for distance > 1 copies to do overlapped load and store copy
|
||||
- Explicit branch predictions (based on measured branch probabilities)
|
||||
- Deferring match copy and interspersed it with decoding subsequent codes
|
||||
- Swapping literal/length else
|
||||
- Swapping window/direct else
|
||||
- Larger unrolled copy loops (three is about right)
|
||||
- Moving len -= 3 statement into middle of loop
|
||||
*/
|
||||
|
||||
#endif /* !ASMINF */
|
||||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
#include "inflate.h"
|
||||
#include "inffast.h"
|
||||
|
||||
#ifndef ASMINF
|
||||
|
||||
/* Allow machine dependent optimization for post-increment or pre-increment.
|
||||
Based on testing to date,
|
||||
Pre-increment preferred for:
|
||||
- PowerPC G3 (Adler)
|
||||
- MIPS R5000 (Randers-Pehrson)
|
||||
Post-increment preferred for:
|
||||
- none
|
||||
No measurable difference:
|
||||
- Pentium III (Anderson)
|
||||
- M68060 (Nikl)
|
||||
*/
|
||||
#ifdef POSTINC
|
||||
# define OFF 0
|
||||
# define PUP(a) *(a)++
|
||||
#else
|
||||
# define OFF 1
|
||||
# define PUP(a) *++(a)
|
||||
#endif
|
||||
|
||||
/*
|
||||
Decode literal, length, and distance codes and write out the resulting
|
||||
literal and match bytes until either not enough input or output is
|
||||
available, an end-of-block is encountered, or a data error is encountered.
|
||||
When large enough input and output buffers are supplied to inflate(), for
|
||||
example, a 16K input buffer and a 64K output buffer, more than 95% of the
|
||||
inflate execution time is spent in this routine.
|
||||
|
||||
Entry assumptions:
|
||||
|
||||
state->mode == LEN
|
||||
strm->avail_in >= 6
|
||||
strm->avail_out >= 258
|
||||
start >= strm->avail_out
|
||||
state->bits < 8
|
||||
|
||||
On return, state->mode is one of:
|
||||
|
||||
LEN -- ran out of enough output space or enough available input
|
||||
TYPE -- reached end of block code, inflate() to interpret next block
|
||||
BAD -- error in block data
|
||||
|
||||
Notes:
|
||||
|
||||
- The maximum input bits used by a length/distance pair is 15 bits for the
|
||||
length code, 5 bits for the length extra, 15 bits for the distance code,
|
||||
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
|
||||
Therefore if strm->avail_in >= 6, then there is enough input to avoid
|
||||
checking for available input while decoding.
|
||||
|
||||
- The maximum bytes that a single length/distance pair can output is 258
|
||||
bytes, which is the maximum length that can be coded. inflate_fast()
|
||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||
output space.
|
||||
*/
|
||||
void inflate_fast(strm, start)
|
||||
z_streamp strm;
|
||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||
{
|
||||
struct inflate_state FAR *state;
|
||||
unsigned char FAR *in; /* local strm->next_in */
|
||||
unsigned char FAR *last; /* while in < last, enough input available */
|
||||
unsigned char FAR *out; /* local strm->next_out */
|
||||
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
|
||||
unsigned char FAR *end; /* while out < end, enough space available */
|
||||
#ifdef INFLATE_STRICT
|
||||
unsigned dmax; /* maximum distance from zlib header */
|
||||
#endif
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
|
||||
unsigned long hold; /* local strm->hold */
|
||||
unsigned bits; /* local strm->bits */
|
||||
code const FAR *lcode; /* local strm->lencode */
|
||||
code const FAR *dcode; /* local strm->distcode */
|
||||
unsigned lmask; /* mask for first level of length codes */
|
||||
unsigned dmask; /* mask for first level of distance codes */
|
||||
code this; /* retrieved table entry */
|
||||
unsigned op; /* code bits, operation, extra bits, or */
|
||||
/* window position, window bytes to copy */
|
||||
unsigned len; /* match length, unused bytes */
|
||||
unsigned dist; /* match distance */
|
||||
unsigned char FAR *from; /* where to copy match from */
|
||||
|
||||
/* copy state to local variables */
|
||||
state = (struct inflate_state FAR *)strm->state;
|
||||
in = strm->next_in - OFF;
|
||||
last = in + (strm->avail_in - 5);
|
||||
out = strm->next_out - OFF;
|
||||
beg = out - (start - strm->avail_out);
|
||||
end = out + (strm->avail_out - 257);
|
||||
#ifdef INFLATE_STRICT
|
||||
dmax = state->dmax;
|
||||
#endif
|
||||
wsize = state->wsize;
|
||||
whave = state->whave;
|
||||
write = state->write;
|
||||
window = state->window;
|
||||
hold = state->hold;
|
||||
bits = state->bits;
|
||||
lcode = state->lencode;
|
||||
dcode = state->distcode;
|
||||
lmask = (1U << state->lenbits) - 1;
|
||||
dmask = (1U << state->distbits) - 1;
|
||||
|
||||
/* decode literals and length/distances until end-of-block or not enough
|
||||
input data or output space */
|
||||
do {
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = lcode[hold & lmask];
|
||||
dolen:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op == 0) { /* literal */
|
||||
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
|
||||
"inflate: literal '%c'\n" :
|
||||
"inflate: literal 0x%02x\n", this.val));
|
||||
PUP(out) = (unsigned char)(this.val);
|
||||
}
|
||||
else if (op & 16) { /* length base */
|
||||
len = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (op) {
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
len += (unsigned)hold & ((1U << op) - 1);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
}
|
||||
Tracevv((stderr, "inflate: length %u\n", len));
|
||||
if (bits < 15) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
this = dcode[hold & dmask];
|
||||
dodist:
|
||||
op = (unsigned)(this.bits);
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
op = (unsigned)(this.op);
|
||||
if (op & 16) { /* distance base */
|
||||
dist = (unsigned)(this.val);
|
||||
op &= 15; /* number of extra bits */
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
if (bits < op) {
|
||||
hold += (unsigned long)(PUP(in)) << bits;
|
||||
bits += 8;
|
||||
}
|
||||
}
|
||||
dist += (unsigned)hold & ((1U << op) - 1);
|
||||
#ifdef INFLATE_STRICT
|
||||
if (dist > dmax) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
hold >>= op;
|
||||
bits -= op;
|
||||
Tracevv((stderr, "inflate: distance %u\n", dist));
|
||||
op = (unsigned)(out - beg); /* max distance in output */
|
||||
if (dist > op) { /* see if copy from window */
|
||||
op = dist - op; /* distance back in window */
|
||||
if (op > whave) {
|
||||
strm->msg = (char *)"invalid distance too far back";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
from = window - OFF;
|
||||
if (write == 0) { /* very common case */
|
||||
from += wsize - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
else if (write < op) { /* wrap around window */
|
||||
from += wsize + write - op;
|
||||
op -= write;
|
||||
if (op < len) { /* some from end of window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = window - OFF;
|
||||
if (write < len) { /* some from start of window */
|
||||
op = write;
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* contiguous in window */
|
||||
from += write - op;
|
||||
if (op < len) { /* some from window */
|
||||
len -= op;
|
||||
do {
|
||||
PUP(out) = PUP(from);
|
||||
} while (--op);
|
||||
from = out - dist; /* rest from output */
|
||||
}
|
||||
}
|
||||
while (len > 2) {
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
}
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
else {
|
||||
from = out - dist; /* copy direct from output */
|
||||
do { /* minimum length is three */
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
PUP(out) = PUP(from);
|
||||
len -= 3;
|
||||
} while (len > 2);
|
||||
if (len) {
|
||||
PUP(out) = PUP(from);
|
||||
if (len > 1)
|
||||
PUP(out) = PUP(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level distance code */
|
||||
this = dcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dodist;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid distance code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((op & 64) == 0) { /* 2nd level length code */
|
||||
this = lcode[this.val + (hold & ((1U << op) - 1))];
|
||||
goto dolen;
|
||||
}
|
||||
else if (op & 32) { /* end-of-block */
|
||||
Tracevv((stderr, "inflate: end of block\n"));
|
||||
state->mode = TYPE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
strm->msg = (char *)"invalid literal/length code";
|
||||
state->mode = BAD;
|
||||
break;
|
||||
}
|
||||
} while (in < last && out < end);
|
||||
|
||||
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
|
||||
len = bits >> 3;
|
||||
in -= len;
|
||||
bits -= len << 3;
|
||||
hold &= (1U << bits) - 1;
|
||||
|
||||
/* update state and return */
|
||||
strm->next_in = in + OFF;
|
||||
strm->next_out = out + OFF;
|
||||
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
|
||||
strm->avail_out = (unsigned)(out < end ?
|
||||
257 + (end - out) : 257 - (out - end));
|
||||
state->hold = hold;
|
||||
state->bits = bits;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
|
||||
- Using bit fields for code structure
|
||||
- Different op definition to avoid & for extra bits (do & for table bits)
|
||||
- Three separate decoding do-loops for direct, window, and write == 0
|
||||
- Special case for distance > 1 copies to do overlapped load and store copy
|
||||
- Explicit branch predictions (based on measured branch probabilities)
|
||||
- Deferring match copy and interspersed it with decoding subsequent codes
|
||||
- Swapping literal/length else
|
||||
- Swapping window/direct else
|
||||
- Larger unrolled copy loops (three is about right)
|
||||
- Moving len -= 3 statement into middle of loop
|
||||
*/
|
||||
|
||||
#endif /* !ASMINF */
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
||||
/* inffast.h -- header to use inffast.c
|
||||
* Copyright (C) 1995-2003 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
||||
|
|
|
@ -1,94 +1,94 @@
|
|||
/* inffixed.h -- table for decoding fixed codes
|
||||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It
|
||||
is part of the implementation of the compression library and
|
||||
is subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
static const code lenfix[512] = {
|
||||
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
|
||||
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
|
||||
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
|
||||
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
|
||||
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
|
||||
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
|
||||
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
|
||||
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
|
||||
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
|
||||
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
|
||||
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
|
||||
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
|
||||
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
|
||||
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
|
||||
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
|
||||
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
|
||||
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
|
||||
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
|
||||
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
|
||||
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
|
||||
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
|
||||
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
|
||||
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
|
||||
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
|
||||
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
|
||||
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
|
||||
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
|
||||
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
|
||||
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
|
||||
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
|
||||
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
|
||||
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
|
||||
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
|
||||
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
|
||||
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
|
||||
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
|
||||
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
|
||||
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
|
||||
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
|
||||
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
|
||||
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
|
||||
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
|
||||
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
|
||||
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
|
||||
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
|
||||
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
|
||||
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
|
||||
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
|
||||
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
|
||||
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
|
||||
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
|
||||
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
|
||||
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
|
||||
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
|
||||
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
|
||||
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
|
||||
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
|
||||
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
|
||||
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
|
||||
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
|
||||
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
|
||||
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
|
||||
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
|
||||
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
|
||||
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
|
||||
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
|
||||
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
|
||||
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
|
||||
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
|
||||
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
|
||||
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
|
||||
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
|
||||
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
|
||||
{0,9,255}
|
||||
};
|
||||
|
||||
static const code distfix[32] = {
|
||||
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
|
||||
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
|
||||
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
|
||||
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
|
||||
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
|
||||
{22,5,193},{64,5,0}
|
||||
};
|
||||
/* inffixed.h -- table for decoding fixed codes
|
||||
* Generated automatically by makefixed().
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It
|
||||
is part of the implementation of the compression library and
|
||||
is subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
static const code lenfix[512] = {
|
||||
{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
|
||||
{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
|
||||
{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
|
||||
{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
|
||||
{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
|
||||
{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
|
||||
{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
|
||||
{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
|
||||
{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
|
||||
{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
|
||||
{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
|
||||
{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
|
||||
{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
|
||||
{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
|
||||
{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
|
||||
{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
|
||||
{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
|
||||
{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
|
||||
{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
|
||||
{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
|
||||
{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
|
||||
{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
|
||||
{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
|
||||
{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
|
||||
{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
|
||||
{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
|
||||
{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
|
||||
{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
|
||||
{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
|
||||
{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
|
||||
{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
|
||||
{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
|
||||
{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
|
||||
{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
|
||||
{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
|
||||
{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
|
||||
{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
|
||||
{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
|
||||
{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
|
||||
{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
|
||||
{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
|
||||
{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
|
||||
{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
|
||||
{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
|
||||
{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
|
||||
{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
|
||||
{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
|
||||
{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
|
||||
{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
|
||||
{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
|
||||
{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
|
||||
{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
|
||||
{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
|
||||
{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
|
||||
{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
|
||||
{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
|
||||
{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
|
||||
{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
|
||||
{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
|
||||
{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
|
||||
{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
|
||||
{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
|
||||
{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
|
||||
{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
|
||||
{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
|
||||
{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
|
||||
{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
|
||||
{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
|
||||
{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
|
||||
{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
|
||||
{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
|
||||
{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
|
||||
{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
|
||||
{0,9,255}
|
||||
};
|
||||
|
||||
static const code distfix[32] = {
|
||||
{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
|
||||
{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
|
||||
{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
|
||||
{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
|
||||
{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
|
||||
{22,5,193},{64,5,0}
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,115 +1,115 @@
|
|||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip decoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
# define GUNZIP
|
||||
#endif
|
||||
|
||||
/* Possible inflate modes between inflate() calls */
|
||||
typedef enum {
|
||||
HEAD, /* i: waiting for magic header */
|
||||
FLAGS, /* i: waiting for method and flags (gzip) */
|
||||
TIME, /* i: waiting for modification time (gzip) */
|
||||
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||||
EXLEN, /* i: waiting for extra length (gzip) */
|
||||
EXTRA, /* i: waiting for extra bytes (gzip) */
|
||||
NAME, /* i: waiting for end of file name (gzip) */
|
||||
COMMENT, /* i: waiting for end of comment (gzip) */
|
||||
HCRC, /* i: waiting for header crc (gzip) */
|
||||
DICTID, /* i: waiting for dictionary check value */
|
||||
DICT, /* waiting for inflateSetDictionary() call */
|
||||
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||||
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||||
STORED, /* i: waiting for stored size (length and complement) */
|
||||
COPY, /* i/o: waiting for input or output to copy stored block */
|
||||
TABLE, /* i: waiting for dynamic block table lengths */
|
||||
LENLENS, /* i: waiting for code length code lengths */
|
||||
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||||
LEN, /* i: waiting for length/lit code */
|
||||
LENEXT, /* i: waiting for length extra bits */
|
||||
DIST, /* i: waiting for distance code */
|
||||
DISTEXT, /* i: waiting for distance extra bits */
|
||||
MATCH, /* o: waiting for output space to copy string */
|
||||
LIT, /* o: waiting for output space to write literal */
|
||||
CHECK, /* i: waiting for 32-bit check value */
|
||||
LENGTH, /* i: waiting for 32-bit length (gzip) */
|
||||
DONE, /* finished check, done -- remain here until reset */
|
||||
BAD, /* got a data error -- remain here until reset */
|
||||
MEM, /* got an inflate() memory error -- remain here until reset */
|
||||
SYNC /* looking for synchronization bytes to restart inflate() */
|
||||
} inflate_mode;
|
||||
|
||||
/*
|
||||
State transitions between above modes -
|
||||
|
||||
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||||
NAME -> COMMENT -> HCRC -> TYPE
|
||||
(zlib) -> DICTID or TYPE
|
||||
DICTID -> DICT -> TYPE
|
||||
Read deflate blocks:
|
||||
TYPE -> STORED or TABLE or LEN or CHECK
|
||||
STORED -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN
|
||||
Read deflate codes:
|
||||
LEN -> LENEXT or LIT or TYPE
|
||||
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||||
LIT -> LEN
|
||||
Process trailer:
|
||||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||||
struct inflate_state {
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
unsigned long check; /* protected copy of check value */
|
||||
unsigned long total; /* protected copy of output count */
|
||||
gz_headerp head; /* where to save gzip header information */
|
||||
/* sliding window */
|
||||
unsigned wbits; /* log base 2 of requested window size */
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
unsigned bits; /* number of bits in "in" */
|
||||
/* for string and stored block copying */
|
||||
unsigned length; /* literal or length of data to copy */
|
||||
unsigned offset; /* distance back to copy string from */
|
||||
/* for table and code decoding */
|
||||
unsigned extra; /* extra bits needed */
|
||||
/* fixed and dynamic code tables */
|
||||
code const FAR *lencode; /* starting table for length/literal codes */
|
||||
code const FAR *distcode; /* starting table for distance codes */
|
||||
unsigned lenbits; /* index bits for lencode */
|
||||
unsigned distbits; /* index bits for distcode */
|
||||
/* dynamic table building */
|
||||
unsigned ncode; /* number of code length code lengths */
|
||||
unsigned nlen; /* number of length code lengths */
|
||||
unsigned ndist; /* number of distance code lengths */
|
||||
unsigned have; /* number of code lengths in lens[] */
|
||||
code FAR *next; /* next available space in codes[] */
|
||||
unsigned short lens[320]; /* temporary storage for code lengths */
|
||||
unsigned short work[288]; /* work area for code table building */
|
||||
code codes[ENOUGH]; /* space for code tables */
|
||||
};
|
||||
/* inflate.h -- internal inflate state definition
|
||||
* Copyright (C) 1995-2004 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* define NO_GZIP when compiling if you want to disable gzip header and
|
||||
trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
|
||||
the crc code when it is not needed. For shared libraries, gzip decoding
|
||||
should be left enabled. */
|
||||
#ifndef NO_GZIP
|
||||
# define GUNZIP
|
||||
#endif
|
||||
|
||||
/* Possible inflate modes between inflate() calls */
|
||||
typedef enum {
|
||||
HEAD, /* i: waiting for magic header */
|
||||
FLAGS, /* i: waiting for method and flags (gzip) */
|
||||
TIME, /* i: waiting for modification time (gzip) */
|
||||
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||||
EXLEN, /* i: waiting for extra length (gzip) */
|
||||
EXTRA, /* i: waiting for extra bytes (gzip) */
|
||||
NAME, /* i: waiting for end of file name (gzip) */
|
||||
COMMENT, /* i: waiting for end of comment (gzip) */
|
||||
HCRC, /* i: waiting for header crc (gzip) */
|
||||
DICTID, /* i: waiting for dictionary check value */
|
||||
DICT, /* waiting for inflateSetDictionary() call */
|
||||
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||||
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||||
STORED, /* i: waiting for stored size (length and complement) */
|
||||
COPY, /* i/o: waiting for input or output to copy stored block */
|
||||
TABLE, /* i: waiting for dynamic block table lengths */
|
||||
LENLENS, /* i: waiting for code length code lengths */
|
||||
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||||
LEN, /* i: waiting for length/lit code */
|
||||
LENEXT, /* i: waiting for length extra bits */
|
||||
DIST, /* i: waiting for distance code */
|
||||
DISTEXT, /* i: waiting for distance extra bits */
|
||||
MATCH, /* o: waiting for output space to copy string */
|
||||
LIT, /* o: waiting for output space to write literal */
|
||||
CHECK, /* i: waiting for 32-bit check value */
|
||||
LENGTH, /* i: waiting for 32-bit length (gzip) */
|
||||
DONE, /* finished check, done -- remain here until reset */
|
||||
BAD, /* got a data error -- remain here until reset */
|
||||
MEM, /* got an inflate() memory error -- remain here until reset */
|
||||
SYNC /* looking for synchronization bytes to restart inflate() */
|
||||
} inflate_mode;
|
||||
|
||||
/*
|
||||
State transitions between above modes -
|
||||
|
||||
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||||
|
||||
Process header:
|
||||
HEAD -> (gzip) or (zlib)
|
||||
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||||
NAME -> COMMENT -> HCRC -> TYPE
|
||||
(zlib) -> DICTID or TYPE
|
||||
DICTID -> DICT -> TYPE
|
||||
Read deflate blocks:
|
||||
TYPE -> STORED or TABLE or LEN or CHECK
|
||||
STORED -> COPY -> TYPE
|
||||
TABLE -> LENLENS -> CODELENS -> LEN
|
||||
Read deflate codes:
|
||||
LEN -> LENEXT or LIT or TYPE
|
||||
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||||
LIT -> LEN
|
||||
Process trailer:
|
||||
CHECK -> LENGTH -> DONE
|
||||
*/
|
||||
|
||||
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||||
struct inflate_state {
|
||||
inflate_mode mode; /* current inflate mode */
|
||||
int last; /* true if processing last block */
|
||||
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||||
int havedict; /* true if dictionary provided */
|
||||
int flags; /* gzip header method and flags (0 if zlib) */
|
||||
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||||
unsigned long check; /* protected copy of check value */
|
||||
unsigned long total; /* protected copy of output count */
|
||||
gz_headerp head; /* where to save gzip header information */
|
||||
/* sliding window */
|
||||
unsigned wbits; /* log base 2 of requested window size */
|
||||
unsigned wsize; /* window size or zero if not using window */
|
||||
unsigned whave; /* valid bytes in the window */
|
||||
unsigned write; /* window write index */
|
||||
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||||
/* bit accumulator */
|
||||
unsigned long hold; /* input bit accumulator */
|
||||
unsigned bits; /* number of bits in "in" */
|
||||
/* for string and stored block copying */
|
||||
unsigned length; /* literal or length of data to copy */
|
||||
unsigned offset; /* distance back to copy string from */
|
||||
/* for table and code decoding */
|
||||
unsigned extra; /* extra bits needed */
|
||||
/* fixed and dynamic code tables */
|
||||
code const FAR *lencode; /* starting table for length/literal codes */
|
||||
code const FAR *distcode; /* starting table for distance codes */
|
||||
unsigned lenbits; /* index bits for lencode */
|
||||
unsigned distbits; /* index bits for distcode */
|
||||
/* dynamic table building */
|
||||
unsigned ncode; /* number of code length code lengths */
|
||||
unsigned nlen; /* number of length code lengths */
|
||||
unsigned ndist; /* number of distance code lengths */
|
||||
unsigned have; /* number of code lengths in lens[] */
|
||||
code FAR *next; /* next available space in codes[] */
|
||||
unsigned short lens[320]; /* temporary storage for code lengths */
|
||||
unsigned short work[288]; /* work area for code table building */
|
||||
code codes[ENOUGH]; /* space for code tables */
|
||||
};
|
||||
|
|
|
@ -1,329 +1,329 @@
|
|||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
include such an acknowledgment, I would appreciate that you keep this
|
||||
copyright string in the executable of your product.
|
||||
*/
|
||||
|
||||
/*
|
||||
Build a set of tables to decode the provided canonical Huffman code.
|
||||
The code lengths are lens[0..codes-1]. The result starts at *table,
|
||||
whose indices are 0..2^bits-1. work is a writable array of at least
|
||||
lens shorts, which is used as a work area. type is the type of code
|
||||
to be generated, CODES, LENS, or DISTS. On return, zero is success,
|
||||
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
|
||||
on return points to the next available entry's address. bits is the
|
||||
requested root table index bits, and on return it is the actual root
|
||||
table index bits. It will differ if the request is greater than the
|
||||
longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int inflate_table(type, lens, codes, table, bits, work)
|
||||
codetype type;
|
||||
unsigned short FAR *lens;
|
||||
unsigned codes;
|
||||
code FAR * FAR *table;
|
||||
unsigned FAR *bits;
|
||||
unsigned short FAR *work;
|
||||
{
|
||||
unsigned len; /* a code's length in bits */
|
||||
unsigned sym; /* index of code symbols */
|
||||
unsigned min, max; /* minimum and maximum code lengths */
|
||||
unsigned root; /* number of index bits for root table */
|
||||
unsigned curr; /* number of index bits for current table */
|
||||
unsigned drop; /* code bits to drop for sub-table */
|
||||
int left; /* number of prefix codes available */
|
||||
unsigned used; /* code entries in table used */
|
||||
unsigned huff; /* Huffman code */
|
||||
unsigned incr; /* for incrementing code, index */
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code this; /* table entry for duplication */
|
||||
code FAR *next; /* next available space in table */
|
||||
const unsigned short FAR *base; /* base value table to use */
|
||||
const unsigned short FAR *extra; /* extra bits table to use */
|
||||
int end; /* use base and extra for symbol > end */
|
||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577, 0, 0};
|
||||
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64};
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++)
|
||||
count[len] = 0;
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
count[lens[sym]]++;
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = *bits;
|
||||
for (max = MAXBITS; max >= 1; max--)
|
||||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)1;
|
||||
this.val = (unsigned short)0;
|
||||
*(*table)++ = this; /* make a table to force an error */
|
||||
*(*table)++ = this;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min <= MAXBITS; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) return -1; /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type == CODES || max != 1))
|
||||
return -1; /* incomplete set */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++)
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked when a LENS table is being made
|
||||
against the space in *table, ENOUGH, minus the maximum space needed by
|
||||
the worst case distance code, MAXD. This should never happen, but the
|
||||
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
|
||||
This assumes that when type == LENS, bits == 9.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base -= 257;
|
||||
extra = lext;
|
||||
extra -= 257;
|
||||
end = 256;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = *table; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = (unsigned)(-1); /* trigger new sub-table when len > root */
|
||||
used = 1U << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
this.op = (unsigned char)0;
|
||||
this.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
this.op = (unsigned char)(extra[work[sym]]);
|
||||
this.val = base[work[sym]];
|
||||
}
|
||||
else {
|
||||
this.op = (unsigned char)(32 + 64); /* end of block */
|
||||
this.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1U << (len - drop);
|
||||
fill = 1U << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = this;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) == 0) {
|
||||
if (len == max) break;
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) != low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop == 0)
|
||||
drop = root;
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = (int)(1 << curr);
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) break;
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
(*table)[low].op = (unsigned char)curr;
|
||||
(*table)[low].bits = (unsigned char)root;
|
||||
(*table)[low].val = (unsigned short)(next - *table);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
this.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
this.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = this;
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
*table += used;
|
||||
*bits = root;
|
||||
return 0;
|
||||
}
|
||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
#include "zutil.h"
|
||||
#include "inftrees.h"
|
||||
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
include such an acknowledgment, I would appreciate that you keep this
|
||||
copyright string in the executable of your product.
|
||||
*/
|
||||
|
||||
/*
|
||||
Build a set of tables to decode the provided canonical Huffman code.
|
||||
The code lengths are lens[0..codes-1]. The result starts at *table,
|
||||
whose indices are 0..2^bits-1. work is a writable array of at least
|
||||
lens shorts, which is used as a work area. type is the type of code
|
||||
to be generated, CODES, LENS, or DISTS. On return, zero is success,
|
||||
-1 is an invalid code, and +1 means that ENOUGH isn't enough. table
|
||||
on return points to the next available entry's address. bits is the
|
||||
requested root table index bits, and on return it is the actual root
|
||||
table index bits. It will differ if the request is greater than the
|
||||
longest code or if it is less than the shortest code.
|
||||
*/
|
||||
int inflate_table(type, lens, codes, table, bits, work)
|
||||
codetype type;
|
||||
unsigned short FAR *lens;
|
||||
unsigned codes;
|
||||
code FAR * FAR *table;
|
||||
unsigned FAR *bits;
|
||||
unsigned short FAR *work;
|
||||
{
|
||||
unsigned len; /* a code's length in bits */
|
||||
unsigned sym; /* index of code symbols */
|
||||
unsigned min, max; /* minimum and maximum code lengths */
|
||||
unsigned root; /* number of index bits for root table */
|
||||
unsigned curr; /* number of index bits for current table */
|
||||
unsigned drop; /* code bits to drop for sub-table */
|
||||
int left; /* number of prefix codes available */
|
||||
unsigned used; /* code entries in table used */
|
||||
unsigned huff; /* Huffman code */
|
||||
unsigned incr; /* for incrementing code, index */
|
||||
unsigned fill; /* index for replicating entries */
|
||||
unsigned low; /* low bits for current root entry */
|
||||
unsigned mask; /* mask for low root bits */
|
||||
code this; /* table entry for duplication */
|
||||
code FAR *next; /* next available space in table */
|
||||
const unsigned short FAR *base; /* base value table to use */
|
||||
const unsigned short FAR *extra; /* extra bits table to use */
|
||||
int end; /* use base and extra for symbol > end */
|
||||
unsigned short count[MAXBITS+1]; /* number of codes of each length */
|
||||
unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
|
||||
static const unsigned short lbase[31] = { /* Length codes 257..285 base */
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
8193, 12289, 16385, 24577, 0, 0};
|
||||
static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
|
||||
16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
|
||||
23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
|
||||
28, 28, 29, 29, 64, 64};
|
||||
|
||||
/*
|
||||
Process a set of code lengths to create a canonical Huffman code. The
|
||||
code lengths are lens[0..codes-1]. Each length corresponds to the
|
||||
symbols 0..codes-1. The Huffman code is generated by first sorting the
|
||||
symbols by length from short to long, and retaining the symbol order
|
||||
for codes with equal lengths. Then the code starts with all zero bits
|
||||
for the first code of the shortest length, and the codes are integer
|
||||
increments for the same length, and zeros are appended as the length
|
||||
increases. For the deflate format, these bits are stored backwards
|
||||
from their more natural integer increment ordering, and so when the
|
||||
decoding tables are built in the large loop below, the integer codes
|
||||
are incremented backwards.
|
||||
|
||||
This routine assumes, but does not check, that all of the entries in
|
||||
lens[] are in the range 0..MAXBITS. The caller must assure this.
|
||||
1..MAXBITS is interpreted as that code length. zero means that that
|
||||
symbol does not occur in this code.
|
||||
|
||||
The codes are sorted by computing a count of codes for each length,
|
||||
creating from that a table of starting indices for each length in the
|
||||
sorted table, and then entering the symbols in order in the sorted
|
||||
table. The sorted table is work[], with that space being provided by
|
||||
the caller.
|
||||
|
||||
The length counts are used for other purposes as well, i.e. finding
|
||||
the minimum and maximum length codes, determining if there are any
|
||||
codes at all, checking for a valid set of lengths, and looking ahead
|
||||
at length counts to determine sub-table sizes when building the
|
||||
decoding tables.
|
||||
*/
|
||||
|
||||
/* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
|
||||
for (len = 0; len <= MAXBITS; len++)
|
||||
count[len] = 0;
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
count[lens[sym]]++;
|
||||
|
||||
/* bound code lengths, force root to be within code lengths */
|
||||
root = *bits;
|
||||
for (max = MAXBITS; max >= 1; max--)
|
||||
if (count[max] != 0) break;
|
||||
if (root > max) root = max;
|
||||
if (max == 0) { /* no symbols to code at all */
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)1;
|
||||
this.val = (unsigned short)0;
|
||||
*(*table)++ = this; /* make a table to force an error */
|
||||
*(*table)++ = this;
|
||||
*bits = 1;
|
||||
return 0; /* no symbols, but wait for decoding to report error */
|
||||
}
|
||||
for (min = 1; min <= MAXBITS; min++)
|
||||
if (count[min] != 0) break;
|
||||
if (root < min) root = min;
|
||||
|
||||
/* check for an over-subscribed or incomplete set of lengths */
|
||||
left = 1;
|
||||
for (len = 1; len <= MAXBITS; len++) {
|
||||
left <<= 1;
|
||||
left -= count[len];
|
||||
if (left < 0) return -1; /* over-subscribed */
|
||||
}
|
||||
if (left > 0 && (type == CODES || max != 1))
|
||||
return -1; /* incomplete set */
|
||||
|
||||
/* generate offsets into symbol table for each length for sorting */
|
||||
offs[1] = 0;
|
||||
for (len = 1; len < MAXBITS; len++)
|
||||
offs[len + 1] = offs[len] + count[len];
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
for (sym = 0; sym < codes; sym++)
|
||||
if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
|
||||
|
||||
/*
|
||||
Create and fill in decoding tables. In this loop, the table being
|
||||
filled is at next and has curr index bits. The code being used is huff
|
||||
with length len. That code is converted to an index by dropping drop
|
||||
bits off of the bottom. For codes where len is less than drop + curr,
|
||||
those top drop + curr - len bits are incremented through all values to
|
||||
fill the table with replicated entries.
|
||||
|
||||
root is the number of index bits for the root table. When len exceeds
|
||||
root, sub-tables are created pointed to by the root entry with an index
|
||||
of the low root bits of huff. This is saved in low to check for when a
|
||||
new sub-table should be started. drop is zero when the root table is
|
||||
being filled, and drop is root when sub-tables are being filled.
|
||||
|
||||
When a new sub-table is needed, it is necessary to look ahead in the
|
||||
code lengths to determine what size sub-table is needed. The length
|
||||
counts are used for this, and so count[] is decremented as codes are
|
||||
entered in the tables.
|
||||
|
||||
used keeps track of how many table entries have been allocated from the
|
||||
provided *table space. It is checked when a LENS table is being made
|
||||
against the space in *table, ENOUGH, minus the maximum space needed by
|
||||
the worst case distance code, MAXD. This should never happen, but the
|
||||
sufficiency of ENOUGH has not been proven exhaustively, hence the check.
|
||||
This assumes that when type == LENS, bits == 9.
|
||||
|
||||
sym increments through all symbols, and the loop terminates when
|
||||
all codes of length max, i.e. all codes, have been processed. This
|
||||
routine permits incomplete codes, so another loop after this one fills
|
||||
in the rest of the decoding tables with invalid code markers.
|
||||
*/
|
||||
|
||||
/* set up for code type */
|
||||
switch (type) {
|
||||
case CODES:
|
||||
base = extra = work; /* dummy value--not used */
|
||||
end = 19;
|
||||
break;
|
||||
case LENS:
|
||||
base = lbase;
|
||||
base -= 257;
|
||||
extra = lext;
|
||||
extra -= 257;
|
||||
end = 256;
|
||||
break;
|
||||
default: /* DISTS */
|
||||
base = dbase;
|
||||
extra = dext;
|
||||
end = -1;
|
||||
}
|
||||
|
||||
/* initialize state for loop */
|
||||
huff = 0; /* starting code */
|
||||
sym = 0; /* starting code symbol */
|
||||
len = min; /* starting code length */
|
||||
next = *table; /* current table to fill in */
|
||||
curr = root; /* current table index bits */
|
||||
drop = 0; /* current bits to drop from code for index */
|
||||
low = (unsigned)(-1); /* trigger new sub-table when len > root */
|
||||
used = 1U << root; /* use root table entries */
|
||||
mask = used - 1; /* mask for comparing low */
|
||||
|
||||
/* check available table space */
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* process all codes and make table entries */
|
||||
for (;;) {
|
||||
/* create table entry */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
if ((int)(work[sym]) < end) {
|
||||
this.op = (unsigned char)0;
|
||||
this.val = work[sym];
|
||||
}
|
||||
else if ((int)(work[sym]) > end) {
|
||||
this.op = (unsigned char)(extra[work[sym]]);
|
||||
this.val = base[work[sym]];
|
||||
}
|
||||
else {
|
||||
this.op = (unsigned char)(32 + 64); /* end of block */
|
||||
this.val = 0;
|
||||
}
|
||||
|
||||
/* replicate for those indices with low len bits equal to huff */
|
||||
incr = 1U << (len - drop);
|
||||
fill = 1U << curr;
|
||||
min = fill; /* save offset to next table */
|
||||
do {
|
||||
fill -= incr;
|
||||
next[(huff >> drop) + fill] = this;
|
||||
} while (fill != 0);
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
|
||||
/* go to next symbol, update count, len */
|
||||
sym++;
|
||||
if (--(count[len]) == 0) {
|
||||
if (len == max) break;
|
||||
len = lens[work[sym]];
|
||||
}
|
||||
|
||||
/* create new sub-table if needed */
|
||||
if (len > root && (huff & mask) != low) {
|
||||
/* if first time, transition to sub-tables */
|
||||
if (drop == 0)
|
||||
drop = root;
|
||||
|
||||
/* increment past last table */
|
||||
next += min; /* here min is 1 << curr */
|
||||
|
||||
/* determine length of next table */
|
||||
curr = len - drop;
|
||||
left = (int)(1 << curr);
|
||||
while (curr + drop < max) {
|
||||
left -= count[curr + drop];
|
||||
if (left <= 0) break;
|
||||
curr++;
|
||||
left <<= 1;
|
||||
}
|
||||
|
||||
/* check for enough space */
|
||||
used += 1U << curr;
|
||||
if (type == LENS && used >= ENOUGH - MAXD)
|
||||
return 1;
|
||||
|
||||
/* point entry in root table to sub-table */
|
||||
low = huff & mask;
|
||||
(*table)[low].op = (unsigned char)curr;
|
||||
(*table)[low].bits = (unsigned char)root;
|
||||
(*table)[low].val = (unsigned short)(next - *table);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
||||
loop above in incrementing huff for table indices. It is assumed that
|
||||
len is equal to curr + drop, so there is no loop needed to increment
|
||||
through high index bits. When the current sub-table is filled, the loop
|
||||
drops back to the root table to fill in any remaining entries there.
|
||||
*/
|
||||
this.op = (unsigned char)64; /* invalid code marker */
|
||||
this.bits = (unsigned char)(len - drop);
|
||||
this.val = (unsigned short)0;
|
||||
while (huff != 0) {
|
||||
/* when done with sub-table, drop back to root table */
|
||||
if (drop != 0 && (huff & mask) != low) {
|
||||
drop = 0;
|
||||
len = root;
|
||||
next = *table;
|
||||
this.bits = (unsigned char)len;
|
||||
}
|
||||
|
||||
/* put invalid code marker in table */
|
||||
next[huff >> drop] = this;
|
||||
|
||||
/* backwards increment the len-bit code huff */
|
||||
incr = 1U << (len - 1);
|
||||
while (huff & incr)
|
||||
incr >>= 1;
|
||||
if (incr != 0) {
|
||||
huff &= incr - 1;
|
||||
huff += incr;
|
||||
}
|
||||
else
|
||||
huff = 0;
|
||||
}
|
||||
|
||||
/* set return parameters */
|
||||
*table += used;
|
||||
*bits = root;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* Structure for decoding tables. Each entry provides either the
|
||||
information needed to do the operation requested by the code that
|
||||
indexed that table entry, or it provides a pointer to another
|
||||
table that indexes more bits of the code. op indicates whether
|
||||
the entry is a pointer to another table, a literal, a length or
|
||||
distance, an end-of-block, or an invalid code. For a table
|
||||
pointer, the low four bits of op is the number of index bits of
|
||||
that table. For a length or distance, the low four bits of op
|
||||
is the number of extra bits to get after the code. bits is
|
||||
the number of bits in this code or part of the code to drop off
|
||||
of the bit buffer. val is the actual byte to output in the case
|
||||
of a literal, the base length or distance, or the offset from
|
||||
the current table to the next table. Each entry is four bytes. */
|
||||
typedef struct {
|
||||
unsigned char op; /* operation, extra bits, table bits */
|
||||
unsigned char bits; /* bits in this part of the code */
|
||||
unsigned short val; /* offset in table or code value */
|
||||
} code;
|
||||
|
||||
/* op values as set by inflate_table():
|
||||
00000000 - literal
|
||||
0000tttt - table link, tttt != 0 is the number of table index bits
|
||||
0001eeee - length or distance, eeee is the number of extra bits
|
||||
01100000 - end of block
|
||||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Maximum size of dynamic tree. The maximum found in a long but non-
|
||||
exhaustive search was 1444 code structures (852 for length/literals
|
||||
and 592 for distances, the latter actually the result of an
|
||||
exhaustive search). The true maximum is not known, but the value
|
||||
below is more than safe. */
|
||||
#define ENOUGH 2048
|
||||
#define MAXD 592
|
||||
|
||||
/* Type of code to build for inftable() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work));
|
||||
/* inftrees.h -- header to use inftrees.c
|
||||
* Copyright (C) 1995-2005 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* Structure for decoding tables. Each entry provides either the
|
||||
information needed to do the operation requested by the code that
|
||||
indexed that table entry, or it provides a pointer to another
|
||||
table that indexes more bits of the code. op indicates whether
|
||||
the entry is a pointer to another table, a literal, a length or
|
||||
distance, an end-of-block, or an invalid code. For a table
|
||||
pointer, the low four bits of op is the number of index bits of
|
||||
that table. For a length or distance, the low four bits of op
|
||||
is the number of extra bits to get after the code. bits is
|
||||
the number of bits in this code or part of the code to drop off
|
||||
of the bit buffer. val is the actual byte to output in the case
|
||||
of a literal, the base length or distance, or the offset from
|
||||
the current table to the next table. Each entry is four bytes. */
|
||||
typedef struct {
|
||||
unsigned char op; /* operation, extra bits, table bits */
|
||||
unsigned char bits; /* bits in this part of the code */
|
||||
unsigned short val; /* offset in table or code value */
|
||||
} code;
|
||||
|
||||
/* op values as set by inflate_table():
|
||||
00000000 - literal
|
||||
0000tttt - table link, tttt != 0 is the number of table index bits
|
||||
0001eeee - length or distance, eeee is the number of extra bits
|
||||
01100000 - end of block
|
||||
01000000 - invalid code
|
||||
*/
|
||||
|
||||
/* Maximum size of dynamic tree. The maximum found in a long but non-
|
||||
exhaustive search was 1444 code structures (852 for length/literals
|
||||
and 592 for distances, the latter actually the result of an
|
||||
exhaustive search). The true maximum is not known, but the value
|
||||
below is more than safe. */
|
||||
#define ENOUGH 2048
|
||||
#define MAXD 592
|
||||
|
||||
/* Type of code to build for inftable() */
|
||||
typedef enum {
|
||||
CODES,
|
||||
LENS,
|
||||
DISTS
|
||||
} codetype;
|
||||
|
||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||
unsigned codes, code FAR * FAR *table,
|
||||
unsigned FAR *bits, unsigned short FAR *work));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,128 +1,128 @@
|
|||
/* header created automatically with -DGEN_TREES_H */
|
||||
|
||||
local const ct_data static_ltree[L_CODES+2] = {
|
||||
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
|
||||
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
|
||||
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
|
||||
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
|
||||
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
|
||||
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
|
||||
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
|
||||
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
|
||||
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
|
||||
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
|
||||
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
|
||||
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
|
||||
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
|
||||
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
|
||||
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
|
||||
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
|
||||
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
|
||||
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
|
||||
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
|
||||
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
|
||||
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
|
||||
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
|
||||
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
|
||||
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
|
||||
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
|
||||
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
|
||||
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
|
||||
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
|
||||
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
|
||||
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
|
||||
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
|
||||
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
|
||||
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
|
||||
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
|
||||
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
|
||||
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
|
||||
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
|
||||
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
|
||||
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
|
||||
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
|
||||
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
|
||||
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
|
||||
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
|
||||
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
|
||||
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
|
||||
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
|
||||
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
|
||||
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
|
||||
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
|
||||
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
|
||||
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
|
||||
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
|
||||
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
|
||||
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
|
||||
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
|
||||
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
|
||||
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
|
||||
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
|
||||
};
|
||||
|
||||
local const ct_data static_dtree[D_CODES] = {
|
||||
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
|
||||
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
|
||||
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
|
||||
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
|
||||
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
|
||||
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
||||
};
|
||||
|
||||
const uch _dist_code[DIST_CODE_LEN] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
|
||||
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
|
||||
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
|
||||
};
|
||||
|
||||
local const int base_length[LENGTH_CODES] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
|
||||
64, 80, 96, 112, 128, 160, 192, 224, 0
|
||||
};
|
||||
|
||||
local const int base_dist[D_CODES] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
|
||||
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
|
||||
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
|
||||
};
|
||||
|
||||
/* header created automatically with -DGEN_TREES_H */
|
||||
|
||||
local const ct_data static_ltree[L_CODES+2] = {
|
||||
{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
|
||||
{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
|
||||
{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
|
||||
{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
|
||||
{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
|
||||
{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
|
||||
{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
|
||||
{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
|
||||
{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
|
||||
{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
|
||||
{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
|
||||
{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
|
||||
{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
|
||||
{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
|
||||
{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
|
||||
{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
|
||||
{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
|
||||
{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
|
||||
{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
|
||||
{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
|
||||
{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
|
||||
{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
|
||||
{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
|
||||
{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
|
||||
{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
|
||||
{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
|
||||
{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
|
||||
{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
|
||||
{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
|
||||
{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
|
||||
{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
|
||||
{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
|
||||
{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
|
||||
{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
|
||||
{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
|
||||
{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
|
||||
{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
|
||||
{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
|
||||
{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
|
||||
{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
|
||||
{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
|
||||
{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
|
||||
{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
|
||||
{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
|
||||
{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
|
||||
{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
|
||||
{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
|
||||
{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
|
||||
{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
|
||||
{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
|
||||
{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
|
||||
{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
|
||||
{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
|
||||
{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
|
||||
{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
|
||||
{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
|
||||
{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
|
||||
{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
|
||||
};
|
||||
|
||||
local const ct_data static_dtree[D_CODES] = {
|
||||
{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
|
||||
{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
|
||||
{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
|
||||
{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
|
||||
{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
|
||||
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
||||
};
|
||||
|
||||
const uch _dist_code[DIST_CODE_LEN] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
|
||||
18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
|
||||
29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
|
||||
13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
|
||||
27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
|
||||
};
|
||||
|
||||
local const int base_length[LENGTH_CODES] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
|
||||
64, 80, 96, 112, 128, 160, 192, 224, 0
|
||||
};
|
||||
|
||||
local const int base_dist[D_CODES] = {
|
||||
0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
|
||||
32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
|
||||
1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
|
||||
};
|
||||
|
||||
|
|
|
@ -1,61 +1,61 @@
|
|||
/* uncompr.c -- decompress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
size of the destination buffer, which must be large enough to hold the
|
||||
entire uncompressed data. (The size of the uncompressed data must have
|
||||
been saved previously by the compressor and transmitted to the decompressor
|
||||
by some mechanism outside the scope of this compression library.)
|
||||
Upon exit, destLen is the actual size of the compressed buffer.
|
||||
This function can be used to decompress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted.
|
||||
*/
|
||||
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
|
||||
err = inflateInit(&stream);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = inflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
inflateEnd(&stream);
|
||||
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
|
||||
return Z_DATA_ERROR;
|
||||
return err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = inflateEnd(&stream);
|
||||
return err;
|
||||
}
|
||||
/* uncompr.c -- decompress a memory buffer
|
||||
* Copyright (C) 1995-2003 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
/* ===========================================================================
|
||||
Decompresses the source buffer into the destination buffer. sourceLen is
|
||||
the byte length of the source buffer. Upon entry, destLen is the total
|
||||
size of the destination buffer, which must be large enough to hold the
|
||||
entire uncompressed data. (The size of the uncompressed data must have
|
||||
been saved previously by the compressor and transmitted to the decompressor
|
||||
by some mechanism outside the scope of this compression library.)
|
||||
Upon exit, destLen is the actual size of the compressed buffer.
|
||||
This function can be used to decompress a whole file at once if the
|
||||
input file is mmap'ed.
|
||||
|
||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
||||
enough memory, Z_BUF_ERROR if there was not enough room in the output
|
||||
buffer, or Z_DATA_ERROR if the input data was corrupted.
|
||||
*/
|
||||
int ZEXPORT uncompress (dest, destLen, source, sourceLen)
|
||||
Bytef *dest;
|
||||
uLongf *destLen;
|
||||
const Bytef *source;
|
||||
uLong sourceLen;
|
||||
{
|
||||
z_stream stream;
|
||||
int err;
|
||||
|
||||
stream.next_in = (Bytef*)source;
|
||||
stream.avail_in = (uInt)sourceLen;
|
||||
/* Check for source > 64K on 16-bit machine: */
|
||||
if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.next_out = dest;
|
||||
stream.avail_out = (uInt)*destLen;
|
||||
if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
|
||||
|
||||
stream.zalloc = (alloc_func)0;
|
||||
stream.zfree = (free_func)0;
|
||||
|
||||
err = inflateInit(&stream);
|
||||
if (err != Z_OK) return err;
|
||||
|
||||
err = inflate(&stream, Z_FINISH);
|
||||
if (err != Z_STREAM_END) {
|
||||
inflateEnd(&stream);
|
||||
if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
|
||||
return Z_DATA_ERROR;
|
||||
return err;
|
||||
}
|
||||
*destLen = stream.total_out;
|
||||
|
||||
err = inflateEnd(&stream);
|
||||
return err;
|
||||
}
|
||||
|
|
|
@ -1,332 +1,332 @@
|
|||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define zError z_zError
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
||||
/* zconf.h -- configuration of the zlib compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZCONF_H
|
||||
#define ZCONF_H
|
||||
|
||||
/*
|
||||
* If you *really* need a unique prefix for all types and library functions,
|
||||
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
|
||||
*/
|
||||
#ifdef Z_PREFIX
|
||||
# define deflateInit_ z_deflateInit_
|
||||
# define deflate z_deflate
|
||||
# define deflateEnd z_deflateEnd
|
||||
# define inflateInit_ z_inflateInit_
|
||||
# define inflate z_inflate
|
||||
# define inflateEnd z_inflateEnd
|
||||
# define deflateInit2_ z_deflateInit2_
|
||||
# define deflateSetDictionary z_deflateSetDictionary
|
||||
# define deflateCopy z_deflateCopy
|
||||
# define deflateReset z_deflateReset
|
||||
# define deflateParams z_deflateParams
|
||||
# define deflateBound z_deflateBound
|
||||
# define deflatePrime z_deflatePrime
|
||||
# define inflateInit2_ z_inflateInit2_
|
||||
# define inflateSetDictionary z_inflateSetDictionary
|
||||
# define inflateSync z_inflateSync
|
||||
# define inflateSyncPoint z_inflateSyncPoint
|
||||
# define inflateCopy z_inflateCopy
|
||||
# define inflateReset z_inflateReset
|
||||
# define inflateBack z_inflateBack
|
||||
# define inflateBackEnd z_inflateBackEnd
|
||||
# define compress z_compress
|
||||
# define compress2 z_compress2
|
||||
# define compressBound z_compressBound
|
||||
# define uncompress z_uncompress
|
||||
# define adler32 z_adler32
|
||||
# define crc32 z_crc32
|
||||
# define get_crc_table z_get_crc_table
|
||||
# define zError z_zError
|
||||
|
||||
# define alloc_func z_alloc_func
|
||||
# define free_func z_free_func
|
||||
# define in_func z_in_func
|
||||
# define out_func z_out_func
|
||||
# define Byte z_Byte
|
||||
# define uInt z_uInt
|
||||
# define uLong z_uLong
|
||||
# define Bytef z_Bytef
|
||||
# define charf z_charf
|
||||
# define intf z_intf
|
||||
# define uIntf z_uIntf
|
||||
# define uLongf z_uLongf
|
||||
# define voidpf z_voidpf
|
||||
# define voidp z_voidp
|
||||
#endif
|
||||
|
||||
#if defined(__MSDOS__) && !defined(MSDOS)
|
||||
# define MSDOS
|
||||
#endif
|
||||
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
|
||||
# define OS2
|
||||
#endif
|
||||
#if defined(_WINDOWS) && !defined(WINDOWS)
|
||||
# define WINDOWS
|
||||
#endif
|
||||
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
|
||||
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
|
||||
# ifndef SYS16BIT
|
||||
# define SYS16BIT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
|
||||
* than 64k bytes at a time (needed on systems with 16-bit int).
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# define MAXSEG_64K
|
||||
#endif
|
||||
#ifdef MSDOS
|
||||
# define UNALIGNED_OK
|
||||
#endif
|
||||
|
||||
#ifdef __STDC_VERSION__
|
||||
# ifndef STDC
|
||||
# define STDC
|
||||
# endif
|
||||
# if __STDC_VERSION__ >= 199901L
|
||||
# ifndef STDC99
|
||||
# define STDC99
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
|
||||
# define STDC
|
||||
#endif
|
||||
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
|
||||
# define STDC
|
||||
#endif
|
||||
|
||||
#ifndef STDC
|
||||
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
|
||||
# define const /* note: need a more gentle solution here */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Some Mac compilers merge all .h files incorrectly: */
|
||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||
# define NO_DUMMY_DECL
|
||||
#endif
|
||||
|
||||
/* Maximum value for memLevel in deflateInit2 */
|
||||
#ifndef MAX_MEM_LEVEL
|
||||
# ifdef MAXSEG_64K
|
||||
# define MAX_MEM_LEVEL 8
|
||||
# else
|
||||
# define MAX_MEM_LEVEL 9
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
|
||||
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
|
||||
* created by gzip. (Files created by minigzip can still be extracted by
|
||||
* gzip.)
|
||||
*/
|
||||
#ifndef MAX_WBITS
|
||||
# define MAX_WBITS 15 /* 32K LZ77 window */
|
||||
#endif
|
||||
|
||||
/* The memory requirements for deflate are (in bytes):
|
||||
(1 << (windowBits+2)) + (1 << (memLevel+9))
|
||||
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
|
||||
plus a few kilobytes for small objects. For example, if you want to reduce
|
||||
the default memory requirements from 256K to 128K, compile with
|
||||
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
|
||||
Of course this will generally degrade compression (there's no free lunch).
|
||||
|
||||
The memory requirements for inflate are (in bytes) 1 << windowBits
|
||||
that is, 32K for windowBits=15 (default value) plus a few kilobytes
|
||||
for small objects.
|
||||
*/
|
||||
|
||||
/* Type declarations */
|
||||
|
||||
#ifndef OF /* function prototypes */
|
||||
# ifdef STDC
|
||||
# define OF(args) args
|
||||
# else
|
||||
# define OF(args) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||
* model programming (small or medium model with some far allocations).
|
||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
|
||||
* just define FAR to be empty.
|
||||
*/
|
||||
#ifdef SYS16BIT
|
||||
# if defined(M_I86SM) || defined(M_I86MM)
|
||||
/* MSC small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef _MSC_VER
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
# if (defined(__SMALL__) || defined(__MEDIUM__))
|
||||
/* Turbo C small or medium model */
|
||||
# define SMALL_MEDIUM
|
||||
# ifdef __BORLANDC__
|
||||
# define FAR _far
|
||||
# else
|
||||
# define FAR far
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS) || defined(WIN32)
|
||||
/* If building or using zlib as a DLL, define ZLIB_DLL.
|
||||
* This is not mandatory, but it offers a little performance increase.
|
||||
*/
|
||||
# ifdef ZLIB_DLL
|
||||
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXTERN extern __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXTERN extern __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# endif /* ZLIB_DLL */
|
||||
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
|
||||
* define ZLIB_WINAPI.
|
||||
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
|
||||
*/
|
||||
# ifdef ZLIB_WINAPI
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
# include <windows.h>
|
||||
/* No need for _export, use ZLIB.DEF instead. */
|
||||
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
|
||||
# define ZEXPORT WINAPI
|
||||
# ifdef WIN32
|
||||
# define ZEXPORTVA WINAPIV
|
||||
# else
|
||||
# define ZEXPORTVA FAR CDECL
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (__BEOS__)
|
||||
# ifdef ZLIB_DLL
|
||||
# ifdef ZLIB_INTERNAL
|
||||
# define ZEXPORT __declspec(dllexport)
|
||||
# define ZEXPORTVA __declspec(dllexport)
|
||||
# else
|
||||
# define ZEXPORT __declspec(dllimport)
|
||||
# define ZEXPORTVA __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef ZEXTERN
|
||||
# define ZEXTERN extern
|
||||
#endif
|
||||
#ifndef ZEXPORT
|
||||
# define ZEXPORT
|
||||
#endif
|
||||
#ifndef ZEXPORTVA
|
||||
# define ZEXPORTVA
|
||||
#endif
|
||||
|
||||
#ifndef FAR
|
||||
# define FAR
|
||||
#endif
|
||||
|
||||
#if !defined(__MACTYPES__)
|
||||
typedef unsigned char Byte; /* 8 bits */
|
||||
#endif
|
||||
typedef unsigned int uInt; /* 16 bits or more */
|
||||
typedef unsigned long uLong; /* 32 bits or more */
|
||||
|
||||
#ifdef SMALL_MEDIUM
|
||||
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
|
||||
# define Bytef Byte FAR
|
||||
#else
|
||||
typedef Byte FAR Bytef;
|
||||
#endif
|
||||
typedef char FAR charf;
|
||||
typedef int FAR intf;
|
||||
typedef uInt FAR uIntf;
|
||||
typedef uLong FAR uLongf;
|
||||
|
||||
#ifdef STDC
|
||||
typedef void const *voidpc;
|
||||
typedef void FAR *voidpf;
|
||||
typedef void *voidp;
|
||||
#else
|
||||
typedef Byte const *voidpc;
|
||||
typedef Byte FAR *voidpf;
|
||||
typedef Byte *voidp;
|
||||
#endif
|
||||
|
||||
#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
|
||||
# include <sys/types.h> /* for off_t */
|
||||
# include <unistd.h> /* for SEEK_* and off_t */
|
||||
# ifdef VMS
|
||||
# include <unixio.h> /* for off_t */
|
||||
# endif
|
||||
# define z_off_t off_t
|
||||
#endif
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
# define SEEK_CUR 1 /* Seek from current position. */
|
||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||
#endif
|
||||
#ifndef z_off_t
|
||||
# define z_off_t long
|
||||
#endif
|
||||
|
||||
#if defined(__OS400__)
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(__MVS__)
|
||||
# define NO_vsnprintf
|
||||
# ifdef FAR
|
||||
# undef FAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* MVS linker does not support external names larger than 8 bytes */
|
||||
#if defined(__MVS__)
|
||||
# pragma map(deflateInit_,"DEIN")
|
||||
# pragma map(deflateInit2_,"DEIN2")
|
||||
# pragma map(deflateEnd,"DEEND")
|
||||
# pragma map(deflateBound,"DEBND")
|
||||
# pragma map(inflateInit_,"ININ")
|
||||
# pragma map(inflateInit2_,"ININ2")
|
||||
# pragma map(inflateEnd,"INEND")
|
||||
# pragma map(inflateSync,"INSY")
|
||||
# pragma map(inflateSetDictionary,"INSEDI")
|
||||
# pragma map(compressBound,"CMBND")
|
||||
# pragma map(inflate_table,"INTABL")
|
||||
# pragma map(inflate_fast,"INFA")
|
||||
# pragma map(inflate_copyright,"INCOPY")
|
||||
#endif
|
||||
|
||||
#endif /* ZCONF_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,318 +1,318 @@
|
|||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
#ifndef NO_DUMMY_DECL
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
"file error", /* Z_ERRNO (-1) */
|
||||
"stream error", /* Z_STREAM_ERROR (-2) */
|
||||
"data error", /* Z_DATA_ERROR (-3) */
|
||||
"insufficient memory", /* Z_MEM_ERROR (-4) */
|
||||
"buffer error", /* Z_BUF_ERROR (-5) */
|
||||
"incompatible version",/* Z_VERSION_ERROR (-6) */
|
||||
""};
|
||||
|
||||
|
||||
const char * ZEXPORT zlibVersion()
|
||||
{
|
||||
return ZLIB_VERSION;
|
||||
}
|
||||
|
||||
uLong ZEXPORT zlibCompileFlags()
|
||||
{
|
||||
uLong flags;
|
||||
|
||||
flags = 0;
|
||||
switch (sizeof(uInt)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1; break;
|
||||
case 8: flags += 2; break;
|
||||
default: flags += 3;
|
||||
}
|
||||
switch (sizeof(uLong)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 2; break;
|
||||
case 8: flags += 2 << 2; break;
|
||||
default: flags += 3 << 2;
|
||||
}
|
||||
switch (sizeof(voidpf)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 4; break;
|
||||
case 8: flags += 2 << 4; break;
|
||||
default: flags += 3 << 4;
|
||||
}
|
||||
switch (sizeof(z_off_t)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 6; break;
|
||||
case 8: flags += 2 << 6; break;
|
||||
default: flags += 3 << 6;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
#ifdef BUILDFIXED
|
||||
flags += 1 << 12;
|
||||
#endif
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
flags += 1 << 13;
|
||||
#endif
|
||||
#ifdef NO_GZCOMPRESS
|
||||
flags += 1L << 16;
|
||||
#endif
|
||||
#ifdef NO_GZIP
|
||||
flags += 1L << 17;
|
||||
#endif
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
flags += 1L << 20;
|
||||
#endif
|
||||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
#ifdef STDC
|
||||
# ifdef NO_vsnprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_vsprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
flags += 1L << 24;
|
||||
# ifdef NO_snprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_sprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_snprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
# ifndef verbose
|
||||
# define verbose 0
|
||||
# endif
|
||||
int z_verbose = verbose;
|
||||
|
||||
void z_error (m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* exported to allow conversion of error code to string for compress() and
|
||||
* uncompress()
|
||||
*/
|
||||
const char * ZEXPORT zError(err)
|
||||
int err;
|
||||
{
|
||||
return ERR_MSG(err);
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used.
|
||||
*/
|
||||
int errno = 0;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MEMCPY
|
||||
|
||||
void zmemcpy(dest, source, len)
|
||||
Bytef* dest;
|
||||
const Bytef* source;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = *source++; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
|
||||
int zmemcmp(s1, s2, len)
|
||||
const Bytef* s1;
|
||||
const Bytef* s2;
|
||||
uInt len;
|
||||
{
|
||||
uInt j;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zmemzero(dest, len)
|
||||
Bytef* dest;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = 0; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SYS16BIT
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* Turbo C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
|
||||
* and farmalloc(64K) returns a pointer with an offset of 8, so we
|
||||
* must fix the pointer. Warning: the pointer must be put back to its
|
||||
* original form in order to free it, use zcfree().
|
||||
*/
|
||||
|
||||
#define MAX_PTR 10
|
||||
/* 10*64K = 640K */
|
||||
|
||||
local int next_ptr = 0;
|
||||
|
||||
typedef struct ptr_table_s {
|
||||
voidpf org_ptr;
|
||||
voidpf new_ptr;
|
||||
} ptr_table;
|
||||
|
||||
local ptr_table table[MAX_PTR];
|
||||
/* This table is used to remember the original form of pointers
|
||||
* to large buffers (64K). Such pointers are normalized with a zero offset.
|
||||
* Since MSDOS is not a preemptive multitasking OS, this table is not
|
||||
* protected from concurrent access. This hack doesn't work anyway on
|
||||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf = opaque; /* just to make some compilers happy */
|
||||
ulg bsize = (ulg)items*size;
|
||||
|
||||
/* If we allocate less than 65520 bytes, we assume that farmalloc
|
||||
* will return a usable pointer which doesn't have to be normalized.
|
||||
*/
|
||||
if (bsize < 65520L) {
|
||||
buf = farmalloc(bsize);
|
||||
if (*(ush*)&buf != 0) return buf;
|
||||
} else {
|
||||
buf = farmalloc(bsize + 16L);
|
||||
}
|
||||
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
|
||||
table[next_ptr].org_ptr = buf;
|
||||
|
||||
/* Normalize the pointer to seg:0 */
|
||||
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
|
||||
*(ush*)&buf = 0;
|
||||
table[next_ptr++].new_ptr = buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
if (*(ush*)&ptr != 0) { /* object < 64K */
|
||||
farfree(ptr);
|
||||
return;
|
||||
}
|
||||
/* Find the original pointer */
|
||||
for (n = 0; n < next_ptr; n++) {
|
||||
if (ptr != table[n].new_ptr) continue;
|
||||
|
||||
farfree(table[n].org_ptr);
|
||||
while (++n < next_ptr) {
|
||||
table[n-1] = table[n];
|
||||
}
|
||||
next_ptr--;
|
||||
return;
|
||||
}
|
||||
ptr = opaque; /* just to make some compilers happy */
|
||||
Assert(0, "zcfree: ptr not found");
|
||||
}
|
||||
|
||||
#endif /* __TURBOC__ */
|
||||
|
||||
|
||||
#ifdef M_I86
|
||||
/* Microsoft C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
|
||||
# define _halloc halloc
|
||||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
_hfree(ptr);
|
||||
}
|
||||
|
||||
#endif /* M_I86 */
|
||||
|
||||
#endif /* SYS16BIT */
|
||||
|
||||
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef STDC
|
||||
extern voidp malloc OF((uInt size));
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
{
|
||||
if (opaque) items += size - size; /* make compiler happy */
|
||||
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
|
||||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void zcfree (opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
free(ptr);
|
||||
if (opaque) return; /* make compiler happy */
|
||||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#include "zutil.h"
|
||||
|
||||
#ifndef NO_DUMMY_DECL
|
||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||
#endif
|
||||
|
||||
const char * const z_errmsg[10] = {
|
||||
"need dictionary", /* Z_NEED_DICT 2 */
|
||||
"stream end", /* Z_STREAM_END 1 */
|
||||
"", /* Z_OK 0 */
|
||||
"file error", /* Z_ERRNO (-1) */
|
||||
"stream error", /* Z_STREAM_ERROR (-2) */
|
||||
"data error", /* Z_DATA_ERROR (-3) */
|
||||
"insufficient memory", /* Z_MEM_ERROR (-4) */
|
||||
"buffer error", /* Z_BUF_ERROR (-5) */
|
||||
"incompatible version",/* Z_VERSION_ERROR (-6) */
|
||||
""};
|
||||
|
||||
|
||||
const char * ZEXPORT zlibVersion()
|
||||
{
|
||||
return ZLIB_VERSION;
|
||||
}
|
||||
|
||||
uLong ZEXPORT zlibCompileFlags()
|
||||
{
|
||||
uLong flags;
|
||||
|
||||
flags = 0;
|
||||
switch (sizeof(uInt)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1; break;
|
||||
case 8: flags += 2; break;
|
||||
default: flags += 3;
|
||||
}
|
||||
switch (sizeof(uLong)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 2; break;
|
||||
case 8: flags += 2 << 2; break;
|
||||
default: flags += 3 << 2;
|
||||
}
|
||||
switch (sizeof(voidpf)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 4; break;
|
||||
case 8: flags += 2 << 4; break;
|
||||
default: flags += 3 << 4;
|
||||
}
|
||||
switch (sizeof(z_off_t)) {
|
||||
case 2: break;
|
||||
case 4: flags += 1 << 6; break;
|
||||
case 8: flags += 2 << 6; break;
|
||||
default: flags += 3 << 6;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
flags += 1 << 8;
|
||||
#endif
|
||||
#if defined(ASMV) || defined(ASMINF)
|
||||
flags += 1 << 9;
|
||||
#endif
|
||||
#ifdef ZLIB_WINAPI
|
||||
flags += 1 << 10;
|
||||
#endif
|
||||
#ifdef BUILDFIXED
|
||||
flags += 1 << 12;
|
||||
#endif
|
||||
#ifdef DYNAMIC_CRC_TABLE
|
||||
flags += 1 << 13;
|
||||
#endif
|
||||
#ifdef NO_GZCOMPRESS
|
||||
flags += 1L << 16;
|
||||
#endif
|
||||
#ifdef NO_GZIP
|
||||
flags += 1L << 17;
|
||||
#endif
|
||||
#ifdef PKZIP_BUG_WORKAROUND
|
||||
flags += 1L << 20;
|
||||
#endif
|
||||
#ifdef FASTEST
|
||||
flags += 1L << 21;
|
||||
#endif
|
||||
#ifdef STDC
|
||||
# ifdef NO_vsnprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_vsprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_vsnprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
flags += 1L << 24;
|
||||
# ifdef NO_snprintf
|
||||
flags += 1L << 25;
|
||||
# ifdef HAS_sprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# else
|
||||
# ifdef HAS_snprintf_void
|
||||
flags += 1L << 26;
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
return flags;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
# ifndef verbose
|
||||
# define verbose 0
|
||||
# endif
|
||||
int z_verbose = verbose;
|
||||
|
||||
void z_error (m)
|
||||
char *m;
|
||||
{
|
||||
fprintf(stderr, "%s\n", m);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* exported to allow conversion of error code to string for compress() and
|
||||
* uncompress()
|
||||
*/
|
||||
const char * ZEXPORT zError(err)
|
||||
int err;
|
||||
{
|
||||
return ERR_MSG(err);
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used.
|
||||
*/
|
||||
int errno = 0;
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MEMCPY
|
||||
|
||||
void zmemcpy(dest, source, len)
|
||||
Bytef* dest;
|
||||
const Bytef* source;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = *source++; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
|
||||
int zmemcmp(s1, s2, len)
|
||||
const Bytef* s1;
|
||||
const Bytef* s2;
|
||||
uInt len;
|
||||
{
|
||||
uInt j;
|
||||
|
||||
for (j = 0; j < len; j++) {
|
||||
if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zmemzero(dest, len)
|
||||
Bytef* dest;
|
||||
uInt len;
|
||||
{
|
||||
if (len == 0) return;
|
||||
do {
|
||||
*dest++ = 0; /* ??? to be unrolled */
|
||||
} while (--len != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SYS16BIT
|
||||
|
||||
#ifdef __TURBOC__
|
||||
/* Turbo C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
|
||||
* and farmalloc(64K) returns a pointer with an offset of 8, so we
|
||||
* must fix the pointer. Warning: the pointer must be put back to its
|
||||
* original form in order to free it, use zcfree().
|
||||
*/
|
||||
|
||||
#define MAX_PTR 10
|
||||
/* 10*64K = 640K */
|
||||
|
||||
local int next_ptr = 0;
|
||||
|
||||
typedef struct ptr_table_s {
|
||||
voidpf org_ptr;
|
||||
voidpf new_ptr;
|
||||
} ptr_table;
|
||||
|
||||
local ptr_table table[MAX_PTR];
|
||||
/* This table is used to remember the original form of pointers
|
||||
* to large buffers (64K). Such pointers are normalized with a zero offset.
|
||||
* Since MSDOS is not a preemptive multitasking OS, this table is not
|
||||
* protected from concurrent access. This hack doesn't work anyway on
|
||||
* a protected system like OS/2. Use Microsoft C instead.
|
||||
*/
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
voidpf buf = opaque; /* just to make some compilers happy */
|
||||
ulg bsize = (ulg)items*size;
|
||||
|
||||
/* If we allocate less than 65520 bytes, we assume that farmalloc
|
||||
* will return a usable pointer which doesn't have to be normalized.
|
||||
*/
|
||||
if (bsize < 65520L) {
|
||||
buf = farmalloc(bsize);
|
||||
if (*(ush*)&buf != 0) return buf;
|
||||
} else {
|
||||
buf = farmalloc(bsize + 16L);
|
||||
}
|
||||
if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
|
||||
table[next_ptr].org_ptr = buf;
|
||||
|
||||
/* Normalize the pointer to seg:0 */
|
||||
*((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
|
||||
*(ush*)&buf = 0;
|
||||
table[next_ptr++].new_ptr = buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
int n;
|
||||
if (*(ush*)&ptr != 0) { /* object < 64K */
|
||||
farfree(ptr);
|
||||
return;
|
||||
}
|
||||
/* Find the original pointer */
|
||||
for (n = 0; n < next_ptr; n++) {
|
||||
if (ptr != table[n].new_ptr) continue;
|
||||
|
||||
farfree(table[n].org_ptr);
|
||||
while (++n < next_ptr) {
|
||||
table[n-1] = table[n];
|
||||
}
|
||||
next_ptr--;
|
||||
return;
|
||||
}
|
||||
ptr = opaque; /* just to make some compilers happy */
|
||||
Assert(0, "zcfree: ptr not found");
|
||||
}
|
||||
|
||||
#endif /* __TURBOC__ */
|
||||
|
||||
|
||||
#ifdef M_I86
|
||||
/* Microsoft C in 16-bit mode */
|
||||
|
||||
# define MY_ZCALLOC
|
||||
|
||||
#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
|
||||
# define _halloc halloc
|
||||
# define _hfree hfree
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
return _halloc((long)items, size);
|
||||
}
|
||||
|
||||
void zcfree (voidpf opaque, voidpf ptr)
|
||||
{
|
||||
if (opaque) opaque = 0; /* to make compiler happy */
|
||||
_hfree(ptr);
|
||||
}
|
||||
|
||||
#endif /* M_I86 */
|
||||
|
||||
#endif /* SYS16BIT */
|
||||
|
||||
|
||||
#ifndef MY_ZCALLOC /* Any system without a special alloc function */
|
||||
|
||||
#ifndef STDC
|
||||
extern voidp malloc OF((uInt size));
|
||||
extern voidp calloc OF((uInt items, uInt size));
|
||||
extern void free OF((voidpf ptr));
|
||||
#endif
|
||||
|
||||
voidpf zcalloc (opaque, items, size)
|
||||
voidpf opaque;
|
||||
unsigned items;
|
||||
unsigned size;
|
||||
{
|
||||
if (opaque) items += size - size; /* make compiler happy */
|
||||
return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
|
||||
(voidpf)calloc(items, size);
|
||||
}
|
||||
|
||||
void zcfree (opaque, ptr)
|
||||
voidpf opaque;
|
||||
voidpf ptr;
|
||||
{
|
||||
free(ptr);
|
||||
if (opaque) return; /* make compiler happy */
|
||||
}
|
||||
|
||||
#endif /* MY_ZCALLOC */
|
||||
|
|
|
@ -1,269 +1,269 @@
|
|||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef _WIN32_WCE
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_ERRNO_H
|
||||
# ifdef _WIN32_WCE
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used. We rename it to
|
||||
* avoid conflict with other libraries that use the same workaround.
|
||||
*/
|
||||
# define errno z_errno
|
||||
# endif
|
||||
extern int errno;
|
||||
#else
|
||||
# ifndef _WIN32_WCE
|
||||
# include <errno.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef uch FAR uchf;
|
||||
typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = (char*)ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 9
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define OS_CODE 0x01
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define OS_CODE 0x02
|
||||
# define F_OPEN(name, mode) \
|
||||
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# define OS_CODE 0x05
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# ifdef M_I86
|
||||
#include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
|
||||
# define OS_CODE 0x0b
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define OS_CODE 0x0f
|
||||
#endif
|
||||
|
||||
#if defined(_BEOS_) || defined(RISCOS)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600))
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef F_OPEN
|
||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
# ifdef MSDOS
|
||||
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||
but for now we just assume it doesn't. */
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __TURBOC__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef WIN32
|
||||
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||||
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __SASC
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
#ifdef VMS
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(pyr)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
/* Use our own functions for small and medium model with MSC <= 5.0.
|
||||
* You may have to use the same strategy for Borland C (untested).
|
||||
* The __SC__ check is for Symantec.
|
||||
*/
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
extern void zmemzero OF((Bytef* dest, uInt len));
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
extern int z_verbose;
|
||||
extern void z_error OF((char *m));
|
||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
|
||||
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
||||
void zcfree OF((voidpf opaque, voidpf ptr));
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
/* zutil.h -- internal interface and configuration of the compression library
|
||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
/* WARNING: this file should *not* be used by applications. It is
|
||||
part of the implementation of the compression library and is
|
||||
subject to change. Applications should only use zlib.h.
|
||||
*/
|
||||
|
||||
/* @(#) $Id$ */
|
||||
|
||||
#ifndef ZUTIL_H
|
||||
#define ZUTIL_H
|
||||
|
||||
#define ZLIB_INTERNAL
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef STDC
|
||||
# ifndef _WIN32_WCE
|
||||
# include <stddef.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef NO_ERRNO_H
|
||||
# ifdef _WIN32_WCE
|
||||
/* The Microsoft C Run-Time Library for Windows CE doesn't have
|
||||
* errno. We define it as a global variable to simplify porting.
|
||||
* Its value is always 0 and should not be used. We rename it to
|
||||
* avoid conflict with other libraries that use the same workaround.
|
||||
*/
|
||||
# define errno z_errno
|
||||
# endif
|
||||
extern int errno;
|
||||
#else
|
||||
# ifndef _WIN32_WCE
|
||||
# include <errno.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef local
|
||||
# define local static
|
||||
#endif
|
||||
/* compile with -Dlocal if your debugger can't find static symbols */
|
||||
|
||||
typedef unsigned char uch;
|
||||
typedef uch FAR uchf;
|
||||
typedef unsigned short ush;
|
||||
typedef ush FAR ushf;
|
||||
typedef unsigned long ulg;
|
||||
|
||||
extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||
/* (size given to avoid silly warnings with Visual C++) */
|
||||
|
||||
#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
|
||||
|
||||
#define ERR_RETURN(strm,err) \
|
||||
return (strm->msg = (char*)ERR_MSG(err), (err))
|
||||
/* To be used only when the state is known to be valid */
|
||||
|
||||
/* common constants */
|
||||
|
||||
#ifndef DEF_WBITS
|
||||
# define DEF_WBITS MAX_WBITS
|
||||
#endif
|
||||
/* default windowBits for decompression. MAX_WBITS is for compression only */
|
||||
|
||||
#if MAX_MEM_LEVEL >= 8
|
||||
# define DEF_MEM_LEVEL 9
|
||||
#else
|
||||
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||
#endif
|
||||
/* default memLevel */
|
||||
|
||||
#define STORED_BLOCK 0
|
||||
#define STATIC_TREES 1
|
||||
#define DYN_TREES 2
|
||||
/* The three kinds of block type */
|
||||
|
||||
#define MIN_MATCH 3
|
||||
#define MAX_MATCH 258
|
||||
/* The minimum and maximum match lengths */
|
||||
|
||||
#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
|
||||
|
||||
/* target dependencies */
|
||||
|
||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||
# define OS_CODE 0x00
|
||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||
# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||
/* Allow compilation with ANSI keywords only enabled */
|
||||
void _Cdecl farfree( void *block );
|
||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||
# else
|
||||
# include <alloc.h>
|
||||
# endif
|
||||
# else /* MSC or DJGPP */
|
||||
# include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef AMIGA
|
||||
# define OS_CODE 0x01
|
||||
#endif
|
||||
|
||||
#if defined(VAXC) || defined(VMS)
|
||||
# define OS_CODE 0x02
|
||||
# define F_OPEN(name, mode) \
|
||||
fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
|
||||
#endif
|
||||
|
||||
#if defined(ATARI) || defined(atarist)
|
||||
# define OS_CODE 0x05
|
||||
#endif
|
||||
|
||||
#ifdef OS2
|
||||
# define OS_CODE 0x06
|
||||
# ifdef M_I86
|
||||
#include <malloc.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||
# define OS_CODE 0x07
|
||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||
# include <unix.h> /* for fdopen */
|
||||
# else
|
||||
# ifndef fdopen
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef TOPS20
|
||||
# define OS_CODE 0x0a
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
|
||||
# define OS_CODE 0x0b
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __50SERIES /* Prime/PRIMOS */
|
||||
# define OS_CODE 0x0f
|
||||
#endif
|
||||
|
||||
#if defined(_BEOS_) || defined(RISCOS)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER > 600))
|
||||
# if defined(_WIN32_WCE)
|
||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||
# ifndef _PTRDIFF_T_DEFINED
|
||||
typedef int ptrdiff_t;
|
||||
# define _PTRDIFF_T_DEFINED
|
||||
# endif
|
||||
# else
|
||||
# define fdopen(fd,type) _fdopen(fd,type)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* common defaults */
|
||||
|
||||
#ifndef OS_CODE
|
||||
# define OS_CODE 0x03 /* assume Unix */
|
||||
#endif
|
||||
|
||||
#ifndef F_OPEN
|
||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
|
||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
# ifndef HAVE_VSNPRINTF
|
||||
# define HAVE_VSNPRINTF
|
||||
# endif
|
||||
#endif
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
# ifdef MSDOS
|
||||
/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
|
||||
but for now we just assume it doesn't. */
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef __TURBOC__
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
# ifdef WIN32
|
||||
/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
|
||||
# if !defined(vsnprintf) && !defined(NO_vsnprintf)
|
||||
# define vsnprintf _vsnprintf
|
||||
# endif
|
||||
# endif
|
||||
# ifdef __SASC
|
||||
# define NO_vsnprintf
|
||||
# endif
|
||||
#endif
|
||||
#ifdef VMS
|
||||
# define NO_vsnprintf
|
||||
#endif
|
||||
|
||||
#if defined(pyr)
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||
/* Use our own functions for small and medium model with MSC <= 5.0.
|
||||
* You may have to use the same strategy for Borland C (untested).
|
||||
* The __SC__ check is for Symantec.
|
||||
*/
|
||||
# define NO_MEMCPY
|
||||
#endif
|
||||
#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
|
||||
# define HAVE_MEMCPY
|
||||
#endif
|
||||
#ifdef HAVE_MEMCPY
|
||||
# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
|
||||
# define zmemcpy _fmemcpy
|
||||
# define zmemcmp _fmemcmp
|
||||
# define zmemzero(dest, len) _fmemset(dest, 0, len)
|
||||
# else
|
||||
# define zmemcpy memcpy
|
||||
# define zmemcmp memcmp
|
||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||
# endif
|
||||
#else
|
||||
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||
extern void zmemzero OF((Bytef* dest, uInt len));
|
||||
#endif
|
||||
|
||||
/* Diagnostic functions */
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
extern int z_verbose;
|
||||
extern void z_error OF((char *m));
|
||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||
# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
|
||||
#else
|
||||
# define Assert(cond,msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
#endif
|
||||
|
||||
|
||||
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
||||
void zcfree OF((voidpf opaque, voidpf ptr));
|
||||
|
||||
#define ZALLOC(strm, items, size) \
|
||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||
|
||||
#endif /* ZUTIL_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,219 +1,219 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#ifndef __PS2ETYPES_H__
|
||||
#define __PS2ETYPES_H__
|
||||
|
||||
#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case
|
||||
#define __LINUX__
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define __LINUX__
|
||||
#endif
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
#define CALLBACK
|
||||
#else
|
||||
#define CALLBACK __stdcall
|
||||
#endif
|
||||
|
||||
|
||||
// jASSUME - give hints to the optimizer
|
||||
// This is primarily useful for the default case switch optimizer, which enables VC to
|
||||
// generate more compact switches.
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define jBREAKPOINT() ((void) 0)
|
||||
# ifdef _MSC_VER
|
||||
# define jASSUME(exp) (__assume(exp))
|
||||
# else
|
||||
# define jASSUME(exp) ((void) sizeof(exp))
|
||||
# endif
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define jBREAKPOINT() do { __asm int 3 } while(0)
|
||||
# else
|
||||
# define jBREAKPOINT() ((void) *(volatile char *) 0)
|
||||
# endif
|
||||
# define jASSUME(exp) if(exp) ; else jBREAKPOINT()
|
||||
#endif
|
||||
|
||||
// disable the default case in a switch
|
||||
#define jNO_DEFAULT \
|
||||
{ \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
jASSUME(0); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
// Basic types
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
typedef __int8 s8;
|
||||
typedef __int16 s16;
|
||||
typedef __int32 s32;
|
||||
typedef __int64 s64;
|
||||
|
||||
typedef unsigned __int8 u8;
|
||||
typedef unsigned __int16 u16;
|
||||
typedef unsigned __int32 u32;
|
||||
typedef unsigned __int64 u64;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
|
||||
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
|
||||
#define PCSX2_ALIGNED16_DECL(x) __declspec(align(16)) x
|
||||
|
||||
#define __naked __declspec(naked)
|
||||
|
||||
#else // _MSC_VER
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include "stdint.h"
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef uintptr_t uptr;
|
||||
typedef intptr_t sptr;
|
||||
|
||||
#else // HAVE_STDINT_H
|
||||
|
||||
typedef char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef long long s64;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#endif // HAVE_STDINT_H
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define LONG long
|
||||
typedef union _LARGE_INTEGER
|
||||
{
|
||||
long long QuadPart;
|
||||
} LARGE_INTEGER;
|
||||
|
||||
#define __fastcall __attribute__((fastcall))
|
||||
#define __unused __attribute__((unused))
|
||||
#define _inline __inline__ __attribute__((unused))
|
||||
#define __forceinline __attribute__((always_inline,unused))
|
||||
#define __naked // GCC lacks the naked specifier
|
||||
|
||||
#endif // __LINUX__
|
||||
|
||||
#define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
|
||||
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
|
||||
|
||||
#define PCSX2_ALIGNED16_DECL(x) x
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if !defined(__LINUX__) || !defined(HAVE_STDINT_H)
|
||||
#if defined(__x86_64__)
|
||||
typedef u64 uptr;
|
||||
typedef s64 sptr;
|
||||
#else
|
||||
typedef u32 uptr;
|
||||
typedef s32 sptr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// A rough-and-ready cross platform 128-bit datatype, Non-SSE style.
|
||||
#ifdef __cplusplus
|
||||
struct u128
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
|
||||
// Implicit conversion from u64
|
||||
u128( u64 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
|
||||
// Implicit conversion from u32
|
||||
u128( u32 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
};
|
||||
|
||||
struct s128
|
||||
{
|
||||
s64 lo;
|
||||
s64 hi;
|
||||
|
||||
// Implicit conversion from u64
|
||||
s128( s64 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
|
||||
// Implicit conversion from u32
|
||||
s128( s32 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef union _u128_t
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
} u128;
|
||||
|
||||
typedef union _s128_t
|
||||
{
|
||||
s64 lo;
|
||||
s64 hi;
|
||||
} s128;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
s8 *data;
|
||||
} freezeData;
|
||||
|
||||
/* common defines */
|
||||
#ifndef C_ASSERT
|
||||
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
||||
#endif
|
||||
|
||||
#endif /* __PS2ETYPES_H__ */
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
#ifndef __PS2ETYPES_H__
|
||||
#define __PS2ETYPES_H__
|
||||
|
||||
#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case
|
||||
#define __LINUX__
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define __LINUX__
|
||||
#endif
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
#define CALLBACK
|
||||
#else
|
||||
#define CALLBACK __stdcall
|
||||
#endif
|
||||
|
||||
|
||||
// jASSUME - give hints to the optimizer
|
||||
// This is primarily useful for the default case switch optimizer, which enables VC to
|
||||
// generate more compact switches.
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define jBREAKPOINT() ((void) 0)
|
||||
# ifdef _MSC_VER
|
||||
# define jASSUME(exp) (__assume(exp))
|
||||
# else
|
||||
# define jASSUME(exp) ((void) sizeof(exp))
|
||||
# endif
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define jBREAKPOINT() do { __asm int 3 } while(0)
|
||||
# else
|
||||
# define jBREAKPOINT() ((void) *(volatile char *) 0)
|
||||
# endif
|
||||
# define jASSUME(exp) if(exp) ; else jBREAKPOINT()
|
||||
#endif
|
||||
|
||||
// disable the default case in a switch
|
||||
#define jNO_DEFAULT \
|
||||
{ \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
jASSUME(0); \
|
||||
break; \
|
||||
}
|
||||
|
||||
|
||||
// Basic types
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
typedef __int8 s8;
|
||||
typedef __int16 s16;
|
||||
typedef __int32 s32;
|
||||
typedef __int64 s64;
|
||||
|
||||
typedef unsigned __int8 u8;
|
||||
typedef unsigned __int16 u16;
|
||||
typedef unsigned __int32 u32;
|
||||
typedef unsigned __int64 u64;
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
|
||||
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
|
||||
#define PCSX2_ALIGNED16_DECL(x) __declspec(align(16)) x
|
||||
|
||||
#define __naked __declspec(naked)
|
||||
|
||||
#else // _MSC_VER
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include "stdint.h"
|
||||
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef uintptr_t uptr;
|
||||
typedef intptr_t sptr;
|
||||
|
||||
#else // HAVE_STDINT_H
|
||||
|
||||
typedef char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef long long s64;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#endif // HAVE_STDINT_H
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define LONG long
|
||||
typedef union _LARGE_INTEGER
|
||||
{
|
||||
long long QuadPart;
|
||||
} LARGE_INTEGER;
|
||||
|
||||
#define __fastcall __attribute__((fastcall))
|
||||
#define __unused __attribute__((unused))
|
||||
#define _inline __inline__ __attribute__((unused))
|
||||
#define __forceinline __attribute__((always_inline,unused))
|
||||
#define __naked // GCC lacks the naked specifier
|
||||
|
||||
#endif // __LINUX__
|
||||
|
||||
#define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
|
||||
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
|
||||
|
||||
#define PCSX2_ALIGNED16_DECL(x) x
|
||||
|
||||
#endif // _MSC_VER
|
||||
|
||||
#if !defined(__LINUX__) || !defined(HAVE_STDINT_H)
|
||||
#if defined(__x86_64__)
|
||||
typedef u64 uptr;
|
||||
typedef s64 sptr;
|
||||
#else
|
||||
typedef u32 uptr;
|
||||
typedef s32 sptr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// A rough-and-ready cross platform 128-bit datatype, Non-SSE style.
|
||||
#ifdef __cplusplus
|
||||
struct u128
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
|
||||
// Implicit conversion from u64
|
||||
u128( u64 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
|
||||
// Implicit conversion from u32
|
||||
u128( u32 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
};
|
||||
|
||||
struct s128
|
||||
{
|
||||
s64 lo;
|
||||
s64 hi;
|
||||
|
||||
// Implicit conversion from u64
|
||||
s128( s64 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
|
||||
// Implicit conversion from u32
|
||||
s128( s32 src ) :
|
||||
lo( src )
|
||||
, hi( 0 ) {}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
typedef union _u128_t
|
||||
{
|
||||
u64 lo;
|
||||
u64 hi;
|
||||
} u128;
|
||||
|
||||
typedef union _s128_t
|
||||
{
|
||||
s64 lo;
|
||||
s64 hi;
|
||||
} s128;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
s8 *data;
|
||||
} freezeData;
|
||||
|
||||
/* common defines */
|
||||
#ifndef C_ASSERT
|
||||
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
||||
#endif
|
||||
|
||||
#endif /* __PS2ETYPES_H__ */
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
// svnrev_template.h --> svnrev.h
|
||||
//
|
||||
// This file acts as a template for the automatic SVN revision/version tag.
|
||||
// It is used by the utility SubWCrev.exe to create an "svnrev.h" file for
|
||||
// whichever project is being compiled (as indicated by command line options
|
||||
// passed to SubWCRev.exe during the project's pre-build step).
|
||||
//
|
||||
// The SubWCRev.exe utility is part of TortoiseSVN and requires several DLLs
|
||||
// installed by TortoiseSVN, so it will only be available if you have TortoiseSVN
|
||||
// installed on your system. If you do not have it installed, a generic template
|
||||
// is used instead (see svnrev_generic.h). Having TortoiseSVN is handy but not
|
||||
// necessary. If you do not have it installed, everything will still compile
|
||||
// fine except without the SVN revision tagged to the application/dll version.
|
||||
//
|
||||
// TortoiseSVN can be downloaded from http://tortoisesvn.tigris.org
|
||||
|
||||
#define SVN_REV $WCREV$
|
||||
// svnrev_template.h --> svnrev.h
|
||||
//
|
||||
// This file acts as a template for the automatic SVN revision/version tag.
|
||||
// It is used by the utility SubWCrev.exe to create an "svnrev.h" file for
|
||||
// whichever project is being compiled (as indicated by command line options
|
||||
// passed to SubWCRev.exe during the project's pre-build step).
|
||||
//
|
||||
// The SubWCRev.exe utility is part of TortoiseSVN and requires several DLLs
|
||||
// installed by TortoiseSVN, so it will only be available if you have TortoiseSVN
|
||||
// installed on your system. If you do not have it installed, a generic template
|
||||
// is used instead (see svnrev_generic.h). Having TortoiseSVN is handy but not
|
||||
// necessary. If you do not have it installed, everything will still compile
|
||||
// fine except without the SVN revision tagged to the application/dll version.
|
||||
//
|
||||
// TortoiseSVN can be downloaded from http://tortoisesvn.tigris.org
|
||||
|
||||
#define SVN_REV $WCREV$
|
||||
#define SVN_MODS $WCMODS?1:0$
|
|
@ -1,23 +1,23 @@
|
|||
// svnrev_genric.h --> svnrev.h
|
||||
//
|
||||
// This file acts as a placebo for people who do not have TortoiseSVN installed.
|
||||
// It provides "empty" revision information to the Pcsx2 Playground projects in
|
||||
// the absence of real revisions derived from the repository being built.
|
||||
//
|
||||
// This file does not affect application/dll builds in any significant manner,
|
||||
// other than the lack of automatic revision tags inserted into the app (which
|
||||
// is very convenient but hardly necessary).
|
||||
//
|
||||
// See svn_template.h for more information on how the process of revision
|
||||
// templating works.
|
||||
//
|
||||
// If you would like to enable automatic revisin tagging, TortoiseSVN can be
|
||||
// downloaded from http://tortoisesvn.tigris.org
|
||||
|
||||
#define SVN_REV_UNKNOWN
|
||||
|
||||
// The following defines are included so that code will still compile even if it
|
||||
// doesn't check for the SVN_REV_UNKNOWN define.
|
||||
|
||||
#define SVN_REV 0
|
||||
// svnrev_genric.h --> svnrev.h
|
||||
//
|
||||
// This file acts as a placebo for people who do not have TortoiseSVN installed.
|
||||
// It provides "empty" revision information to the Pcsx2 Playground projects in
|
||||
// the absence of real revisions derived from the repository being built.
|
||||
//
|
||||
// This file does not affect application/dll builds in any significant manner,
|
||||
// other than the lack of automatic revision tags inserted into the app (which
|
||||
// is very convenient but hardly necessary).
|
||||
//
|
||||
// See svn_template.h for more information on how the process of revision
|
||||
// templating works.
|
||||
//
|
||||
// If you would like to enable automatic revisin tagging, TortoiseSVN can be
|
||||
// downloaded from http://tortoisesvn.tigris.org
|
||||
|
||||
#define SVN_REV_UNKNOWN
|
||||
|
||||
// The following defines are included so that code will still compile even if it
|
||||
// doesn't check for the SVN_REV_UNKNOWN define.
|
||||
|
||||
#define SVN_REV 0
|
||||
#define SVN_MODS ""
|
|
@ -1,57 +1,57 @@
|
|||
#
|
||||
#
|
||||
|
||||
all: ps2romgen_exe romdir_exe romver_exe fps2bios
|
||||
|
||||
VERSION = 0
|
||||
BUILD = 1
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
STRIP = strip
|
||||
|
||||
OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math
|
||||
CFLAGS = -Wall ${OPTIMIZE} -I.
|
||||
DIRS = kernel intro loader
|
||||
FILES = RESET ROMDIR EXTINFO ROMVER IOPBOOT EELOAD \
|
||||
SYSMEM LOADCORE EXCEPMAN INTRMAN SSBUSC DMACMAN \
|
||||
TIMRMAN SYSCLIB HEAPLIB THREADMAN VBLANK STDIO \
|
||||
SIFMAN SIFCMD SIO2MAN LOADER INTRO IOPBTCONF FP2BLOGO \
|
||||
IOMAN MODLOAD ROMDRV IGREETING REBOOT LOADFILE CDVDMAN \
|
||||
CDVDFSV SIFINIT FILEIO SECRMAN EESYNC
|
||||
|
||||
ps2romgen_exe: ps2romgen.o
|
||||
${CC} ${CFLAGS} ps2romgen.o -o build/ps2romgen_exe
|
||||
|
||||
romdir_exe: romdir.o
|
||||
${CC} ${CFLAGS} romdir.o -o build/romdir_exe
|
||||
|
||||
romver_exe: romver.o
|
||||
${CC} ${CFLAGS} romver.o -o build/romver_exe
|
||||
|
||||
fps2bios:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
cp -f used/* build
|
||||
cp -f FP2BLOGO build
|
||||
cp -f IOPBTCONF build/
|
||||
(cd build; \
|
||||
./romver_exe $(VERSION) $(BUILD); \
|
||||
./romdir_exe $(FILES); \
|
||||
./ps2romgen_exe fps2bios; \
|
||||
cd ..)
|
||||
cp build/fps2bios ../bin/bios
|
||||
|
||||
.PHONY: clean ps2romgen_exe romdir_exe fps2bios
|
||||
|
||||
clean:
|
||||
${RM} *.o build/*
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c -o $@ $<
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
all: ps2romgen_exe romdir_exe romver_exe fps2bios
|
||||
|
||||
VERSION = 0
|
||||
BUILD = 1
|
||||
|
||||
CC = gcc
|
||||
RM = rm -f
|
||||
STRIP = strip
|
||||
|
||||
OPTIMIZE = -O2 -fomit-frame-pointer -finline-functions -ffast-math
|
||||
CFLAGS = -Wall ${OPTIMIZE} -I.
|
||||
DIRS = kernel intro loader
|
||||
FILES = RESET ROMDIR EXTINFO ROMVER IOPBOOT EELOAD \
|
||||
SYSMEM LOADCORE EXCEPMAN INTRMAN SSBUSC DMACMAN \
|
||||
TIMRMAN SYSCLIB HEAPLIB THREADMAN VBLANK STDIO \
|
||||
SIFMAN SIFCMD SIO2MAN LOADER INTRO IOPBTCONF FP2BLOGO \
|
||||
IOMAN MODLOAD ROMDRV IGREETING REBOOT LOADFILE CDVDMAN \
|
||||
CDVDFSV SIFINIT FILEIO SECRMAN EESYNC
|
||||
|
||||
ps2romgen_exe: ps2romgen.o
|
||||
${CC} ${CFLAGS} ps2romgen.o -o build/ps2romgen_exe
|
||||
|
||||
romdir_exe: romdir.o
|
||||
${CC} ${CFLAGS} romdir.o -o build/romdir_exe
|
||||
|
||||
romver_exe: romver.o
|
||||
${CC} ${CFLAGS} romver.o -o build/romver_exe
|
||||
|
||||
fps2bios:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
cp -f used/* build
|
||||
cp -f FP2BLOGO build
|
||||
cp -f IOPBTCONF build/
|
||||
(cd build; \
|
||||
./romver_exe $(VERSION) $(BUILD); \
|
||||
./romdir_exe $(FILES); \
|
||||
./ps2romgen_exe fps2bios; \
|
||||
cd ..)
|
||||
cp build/fps2bios ../bin/bios
|
||||
|
||||
.PHONY: clean ps2romgen_exe romdir_exe fps2bios
|
||||
|
||||
clean:
|
||||
${RM} *.o build/*
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
|
||||
%.o: %.c
|
||||
${CC} ${CFLAGS} -c -o $@ $<
|
||||
|
||||
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0 -D_EE
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: intro
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/ee/lib
|
||||
LDADD = -lmc -lpad -lc -lkernel -lm
|
||||
OBJECTS = intro.o eedebug.o crt0.o romdir.o
|
||||
DEST = ../build/INTRO
|
||||
|
||||
intro: $(OBJECTS)
|
||||
$(EELD) -T linkfile $(EECFLAGS) $(OBJECTS) $(LDFLAGS) $(LDADD) -o $(DEST)
|
||||
|
||||
%.o: %.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
%.o: %.s
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(DEST)
|
||||
|
||||
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0 -D_EE
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: intro
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/ee/lib
|
||||
LDADD = -lmc -lpad -lc -lkernel -lm
|
||||
OBJECTS = intro.o eedebug.o crt0.o romdir.o
|
||||
DEST = ../build/INTRO
|
||||
|
||||
intro: $(OBJECTS)
|
||||
$(EELD) -T linkfile $(EECFLAGS) $(OBJECTS) $(LDFLAGS) $(LDADD) -o $(DEST)
|
||||
|
||||
%.o: %.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
%.o: %.s
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(DEST)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c) {
|
||||
while (*((u32*)0x1000f130) & 0x8000) { __asm__ ("nop\nnop\nnop\n"); }
|
||||
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
void __puts(u8 *s) {
|
||||
while (*s != 0) {
|
||||
__putc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
int __printf(const char *format, ...) {
|
||||
char buf[4096];
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf(buf, 4096, format, args);
|
||||
va_end(args);
|
||||
|
||||
__puts((u8*)buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c) {
|
||||
while (*((u32*)0x1000f130) & 0x8000) { __asm__ ("nop\nnop\nnop\n"); }
|
||||
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
void __puts(u8 *s) {
|
||||
while (*s != 0) {
|
||||
__putc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
int __printf(const char *format, ...) {
|
||||
char buf[4096];
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf(buf, 4096, format, args);
|
||||
va_end(args);
|
||||
|
||||
__puts((u8*)buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __EEDEBUG_H__
|
||||
#define __EEDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
int __printf(const char *format, ...);
|
||||
|
||||
#endif /* __EEDEBUG_H__ */
|
||||
#ifndef __EEDEBUG_H__
|
||||
#define __EEDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
int __printf(const char *format, ...);
|
||||
|
||||
#endif /* __EEDEBUG_H__ */
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#ifndef __ROMDIR_H__
|
||||
#define __ROMDIR_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
struct romdir {
|
||||
/*following variable must place in designed order*/
|
||||
u8 fileName[10];
|
||||
u16 extInfoSize;
|
||||
u32 fileSize;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rominfo {
|
||||
u32 fileOffset;
|
||||
u32 fileSize;
|
||||
};
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri);
|
||||
|
||||
#endif /* __ROMDIR_H__ */
|
||||
#ifndef __ROMDIR_H__
|
||||
#define __ROMDIR_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
struct romdir {
|
||||
/*following variable must place in designed order*/
|
||||
u8 fileName[10];
|
||||
u16 extInfoSize;
|
||||
u32 fileSize;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rominfo {
|
||||
u32 fileOffset;
|
||||
u32 fileSize;
|
||||
};
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri);
|
||||
|
||||
#endif /* __ROMDIR_H__ */
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "eedebug.h"
|
||||
#include "romdir.h"
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
__printf("INTRO start\n");
|
||||
|
||||
__printf("INTRO end\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "eedebug.h"
|
||||
#include "romdir.h"
|
||||
|
||||
|
||||
int main() {
|
||||
|
||||
__printf("INTRO start\n");
|
||||
|
||||
__printf("INTRO end\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
/***************************************************************
|
||||
* romdir.c, based over Alex Lau (http://alexlau.8k.com) RomDir *
|
||||
****************************************************************/
|
||||
#include "romdir.h"
|
||||
|
||||
struct romdir *romdirInit() {
|
||||
u8 *mem;
|
||||
|
||||
for (mem=(u8*)0xbfc00000; (u32)mem<0xbfc01000; mem++) {
|
||||
if (mem[0] == 'R' && mem[1] == 'E' &&
|
||||
mem[2] == 'S' && mem[3] == 'E' &&
|
||||
mem[4] == 'T')
|
||||
break;
|
||||
}
|
||||
if ((u32)mem == 0xbfc01000) return NULL;
|
||||
|
||||
return (struct romdir*)mem;
|
||||
}
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri) {
|
||||
struct romdir *rd;
|
||||
struct romdir *base;
|
||||
int i;
|
||||
|
||||
base = romdirInit();
|
||||
if (base == NULL) return NULL;
|
||||
|
||||
ri->fileOffset = 0;
|
||||
for (rd = base; rd->fileName[0] != 0; rd++) {
|
||||
for (i=0; i<10 && name[i] != 0; i++) {
|
||||
if (rd->fileName[i] != name[i]) break;
|
||||
}
|
||||
if (rd->fileName[i] != name[i]) {
|
||||
ri->fileOffset+= (rd->fileSize + 15) & ~0xF;
|
||||
continue;
|
||||
}
|
||||
|
||||
ri->fileSize = rd->fileSize;
|
||||
return ri;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/***************************************************************
|
||||
* romdir.c, based over Alex Lau (http://alexlau.8k.com) RomDir *
|
||||
****************************************************************/
|
||||
#include "romdir.h"
|
||||
|
||||
struct romdir *romdirInit() {
|
||||
u8 *mem;
|
||||
|
||||
for (mem=(u8*)0xbfc00000; (u32)mem<0xbfc01000; mem++) {
|
||||
if (mem[0] == 'R' && mem[1] == 'E' &&
|
||||
mem[2] == 'S' && mem[3] == 'E' &&
|
||||
mem[4] == 'T')
|
||||
break;
|
||||
}
|
||||
if ((u32)mem == 0xbfc01000) return NULL;
|
||||
|
||||
return (struct romdir*)mem;
|
||||
}
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri) {
|
||||
struct romdir *rd;
|
||||
struct romdir *base;
|
||||
int i;
|
||||
|
||||
base = romdirInit();
|
||||
if (base == NULL) return NULL;
|
||||
|
||||
ri->fileOffset = 0;
|
||||
for (rd = base; rd->fileName[0] != 0; rd++) {
|
||||
for (i=0; i<10 && name[i] != 0; i++) {
|
||||
if (rd->fileName[i] != name[i]) break;
|
||||
}
|
||||
if (rd->fileName[i] != name[i]) {
|
||||
ri->fileOffset+= (rd->fileSize + 15) & ~0xF;
|
||||
continue;
|
||||
}
|
||||
|
||||
ri->fileSize = rd->fileSize;
|
||||
return ri;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,73 +1,73 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0
|
||||
EEINCLUDES = -I. -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: start
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
OBJS = eestart.o iopstart.o start.o romdir.o
|
||||
DIRS = eeload iopload
|
||||
|
||||
start: $(OBJS)
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
$(EELD) -Wl,--oformat,binary -T linkfile $(EECFLAGS) $(OBJS) -o ../build/RESET
|
||||
|
||||
iopstart.o: iopstart.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
eestart.o: eestart.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
romdir.o: romdir.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
start.o: start.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
rm -f $(OBJS) start
|
||||
|
||||
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0
|
||||
EEINCLUDES = -I. -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: start
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
OBJS = eestart.o iopstart.o start.o romdir.o
|
||||
DIRS = eeload iopload
|
||||
|
||||
start: $(OBJS)
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
$(EELD) -Wl,--oformat,binary -T linkfile $(EECFLAGS) $(OBJS) -o ../build/RESET
|
||||
|
||||
iopstart.o: iopstart.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
eestart.o: eestart.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
romdir.o: romdir.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
start.o: start.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
rm -f $(OBJS) start
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,61 +1,61 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0 -D_EE --save-temps
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles
|
||||
IOPINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: eeload
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/ee/lib
|
||||
LDADD = -lmc -lpad -lc -lkernel
|
||||
OBJECTS = eeirq.o eedata.o eekernel.o eeinit.o eeload.o eeelf.o eedebug.o romdir.o
|
||||
|
||||
eeload: $(OBJECTS)
|
||||
$(EELD) -Wl,--oformat,binary,--Map,eeload.map -T linkfile $(EECFLAGS) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../build/EELOAD
|
||||
|
||||
# restrict all but the kernel registers
|
||||
eeirq.o: eeirq.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5 -ffixed-6 -ffixed-7 -ffixed-8 -ffixed-9 -ffixed-10 -ffixed-11 -ffixed-12 -ffixed-13 -ffixed-14 -ffixed-15 -ffixed-16 -ffixed-17 -ffixed-18 -ffixed-19 -ffixed-20 -ffixed-21 -ffixed-22 -ffixed-23 -ffixed-24 -ffixed-25 -fcall-used-26 -fcall-used-27 -ffixed-30 -o $@ -c $<
|
||||
%.o: %.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) eeload
|
||||
|
||||
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles -G0 -D_EE --save-temps
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles
|
||||
IOPINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: eeload
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/ee/lib
|
||||
LDADD = -lmc -lpad -lc -lkernel
|
||||
OBJECTS = eeirq.o eedata.o eekernel.o eeinit.o eeload.o eeelf.o eedebug.o romdir.o
|
||||
|
||||
eeload: $(OBJECTS)
|
||||
$(EELD) -Wl,--oformat,binary,--Map,eeload.map -T linkfile $(EECFLAGS) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../build/EELOAD
|
||||
|
||||
# restrict all but the kernel registers
|
||||
eeirq.o: eeirq.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -ffixed-2 -ffixed-3 -ffixed-4 -ffixed-5 -ffixed-6 -ffixed-7 -ffixed-8 -ffixed-9 -ffixed-10 -ffixed-11 -ffixed-12 -ffixed-13 -ffixed-14 -ffixed-15 -ffixed-16 -ffixed-17 -ffixed-18 -ffixed-19 -ffixed-20 -ffixed-21 -ffixed-22 -ffixed-23 -ffixed-24 -ffixed-25 -fcall-used-26 -fcall-used-27 -ffixed-30 -o $@ -c $<
|
||||
%.o: %.c
|
||||
$(EECC) $(EEINCLUDES) $(EECFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) eeload
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,198 +1,198 @@
|
|||
// eedata.c - needed in order to assure
|
||||
// that some of the kernel variables are as close to 0x80000000 as possible
|
||||
// (ie, look in saveContext2)
|
||||
//[made by] [RO]man, zerofrog
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eekernel.h"
|
||||
#include "eeirq.h"
|
||||
|
||||
eeRegs SavedRegs __attribute((aligned(256)));
|
||||
u128 SavedSP __attribute((aligned(16)));
|
||||
u128 SavedRA __attribute((aligned(16)));
|
||||
u128 SavedAT __attribute((aligned(16)));
|
||||
u64 SavedT9 __attribute((aligned(16)));
|
||||
|
||||
u32 _CpuConfig_0(u32);
|
||||
u32 _CpuConfig_1(u32);
|
||||
u32 _CpuConfig_2(u32);
|
||||
u32 _CpuConfig_3(u32);
|
||||
u32 _CpuConfig_4(u32);
|
||||
u32 _CpuConfig_5(u32);
|
||||
u32 (*table_CpuConfig[6])(u32) = {_CpuConfig_0, _CpuConfig_1, _CpuConfig_2,
|
||||
_CpuConfig_3, _CpuConfig_4, _CpuConfig_5};
|
||||
|
||||
u32 dmac_CHCR[10] = {
|
||||
0xB0008000,
|
||||
0xB0009000,
|
||||
0xB000A000,
|
||||
0xB000B000,
|
||||
0xB000B400,
|
||||
0xB000C000,
|
||||
0xB000C400,
|
||||
0xB000C800,
|
||||
0xB000D000,
|
||||
0xB000D400,
|
||||
};
|
||||
|
||||
void (*VCRTable[14])() = {
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
SyscException, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
void (*VIntTable[8])() = {
|
||||
0, 0, DMACException, INTCException,
|
||||
0, 0, 0, TIMERException,
|
||||
};
|
||||
|
||||
void _DummyINTCHandler(int);
|
||||
void _DummyDMACHandler(int);
|
||||
|
||||
void (*INTCTable[16])(int) = {
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler };
|
||||
|
||||
void (*DMACTable[16])(int) = {
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler };
|
||||
|
||||
|
||||
void (*table_SYSCALL[0x80])() = {
|
||||
(void (*))_RFU___, // 0x00
|
||||
(void (*))_ResetEE,
|
||||
(void (*))_SetGsCrt,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_Exit, // 0x04
|
||||
(void (*))_RFU005,
|
||||
(void (*))_LoadPS2Exe,
|
||||
(void (*))_ExecPS2,
|
||||
(void (*))_RFU___, // 0x08
|
||||
(void (*))_TlbWriteRandom,
|
||||
(void (*))_AddSbusIntcHandler,
|
||||
(void (*))_RemoveSbusIntcHandler,
|
||||
(void (*))_Interrupt2Iop, // 0x0C
|
||||
(void (*))_SetVTLBRefillHandler,
|
||||
(void (*))_SetVCommonHandler,
|
||||
(void (*))_SetVInterruptHandler,
|
||||
(void (*))_AddIntcHandler, // 0x10
|
||||
(void (*))_RemoveIntcHandler,
|
||||
(void (*))_AddDmacHandler,
|
||||
(void (*))_RemoveDmacHandler,
|
||||
(void (*))__EnableIntc, // 0x14
|
||||
(void (*))__DisableIntc,
|
||||
(void (*))__EnableDmac,
|
||||
(void (*))__DisableDmac,
|
||||
(void (*))_SetAlarm, // 0x18
|
||||
(void (*))_ReleaseAlarm,
|
||||
(void (*))__EnableIntc,
|
||||
(void (*))__DisableIntc,
|
||||
(void (*))__EnableDmac, // 0x1C
|
||||
(void (*))__DisableDmac,
|
||||
(void (*))_SetAlarm,
|
||||
(void (*))_ReleaseAlarm,
|
||||
(void (*))_CreateThread, // 0x20
|
||||
(void (*))_DeleteThread,
|
||||
(void (*))_StartThread,
|
||||
(void (*))_ExitThread,
|
||||
(void (*))_ExitDeleteThread, // 0x24
|
||||
(void (*))_TerminateThread,
|
||||
(void (*))_iTerminateThread,
|
||||
(void (*))_DisableDispatchThread,
|
||||
(void (*))_EnableDispatchThread, // 0x28
|
||||
(void (*))_ChangeThreadPriority,
|
||||
(void (*))_iChangeThreadPriority,
|
||||
(void (*))_RotateThreadReadyQueue,
|
||||
(void (*))_iRotateThreadReadyQueue, // 0x2C
|
||||
(void (*))_ReleaseWaitThread,
|
||||
(void (*))_iReleaseWaitThread,
|
||||
(void (*))_GetThreadId,
|
||||
(void (*))_ReferThreadStatus, // 0x30
|
||||
(void (*))_ReferThreadStatus,
|
||||
(void (*))_SleepThread,
|
||||
(void (*))_WakeupThread,
|
||||
(void (*))_iWakeupThread,
|
||||
(void (*))_CancelWakeupThread,
|
||||
(void (*))_CancelWakeupThread,
|
||||
(void (*))_SuspendThread,
|
||||
(void (*))_SuspendThread,
|
||||
(void (*))_ResumeThread,
|
||||
(void (*))_iResumeThread,
|
||||
(void (*))_JoinThread,
|
||||
(void (*))_InitializeMainThread,
|
||||
(void (*))_InitializeHeapArea,
|
||||
(void (*))_EndOfHeap,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_CreateSema, // 0x40
|
||||
(void (*))_DeleteSema,
|
||||
(void (*))_SignalSema,
|
||||
(void (*))_iSignalSema,
|
||||
(void (*))_WaitSema,
|
||||
(void (*))_PollSema,
|
||||
(void (*))_PollSema,
|
||||
(void (*))_ReferSemaStatus,
|
||||
(void (*))_ReferSemaStatus,
|
||||
(void (*))_iDeleteSema,
|
||||
(void (*))_SetOsdConfigParam,
|
||||
(void (*))_GetOsdConfigParam,
|
||||
(void (*))_GetGsHParam,
|
||||
(void (*))_GetGsVParam,
|
||||
(void (*))_SetGsHParam,
|
||||
(void (*))_SetGsVParam,
|
||||
(void (*))_CreateEventFlag, // 0x50
|
||||
(void (*))_DeleteEventFlag,
|
||||
(void (*))_SetEventFlag,
|
||||
(void (*))_iSetEventFlag,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_EnableIntcHandler,
|
||||
(void (*))_DisableIntcHandler,
|
||||
(void (*))_EnableDmacHandler,
|
||||
(void (*))_DisableDmacHandler,
|
||||
(void (*))_KSeg0, // 0x60
|
||||
(void (*))_EnableCache,
|
||||
(void (*))_DisableCache,
|
||||
(void (*))_GetCop0,
|
||||
(void (*))_FlushCache,
|
||||
(void (*))_105,
|
||||
(void (*))_CpuConfig,
|
||||
(void (*))_GetCop0,
|
||||
(void (*))_FlushCache,
|
||||
(void (*))_105,
|
||||
(void (*))_CpuConfig,
|
||||
(void (*))_SifStopDma, //_sceSifStopDma,
|
||||
(void (*))_SetCPUTimerHandler,
|
||||
(void (*))_SetCPUTimer,
|
||||
(void (*))0,//_SetOsdConfigParam2,
|
||||
(void (*))0,//_GetOsdConfigParam2,
|
||||
(void (*))_GsGetIMR, // 0x70
|
||||
(void (*))_GsPutIMR,
|
||||
(void (*))_SetPgifHandler,
|
||||
(void (*))_SetVSyncFlag,
|
||||
(void (*))_SetSYSCALL,
|
||||
(void (*))_print,
|
||||
(void (*))_SifDmaStat,
|
||||
(void (*))_SifSetDma,
|
||||
(void (*))_SifSetDChain,
|
||||
(void (*))_SifSetReg,
|
||||
(void (*))_SifGetReg,
|
||||
(void (*))_ExecOSD,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_PSMode,
|
||||
(void (*))_MachineType,
|
||||
(void (*))_GetMemorySize
|
||||
};
|
||||
// eedata.c - needed in order to assure
|
||||
// that some of the kernel variables are as close to 0x80000000 as possible
|
||||
// (ie, look in saveContext2)
|
||||
//[made by] [RO]man, zerofrog
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eekernel.h"
|
||||
#include "eeirq.h"
|
||||
|
||||
eeRegs SavedRegs __attribute((aligned(256)));
|
||||
u128 SavedSP __attribute((aligned(16)));
|
||||
u128 SavedRA __attribute((aligned(16)));
|
||||
u128 SavedAT __attribute((aligned(16)));
|
||||
u64 SavedT9 __attribute((aligned(16)));
|
||||
|
||||
u32 _CpuConfig_0(u32);
|
||||
u32 _CpuConfig_1(u32);
|
||||
u32 _CpuConfig_2(u32);
|
||||
u32 _CpuConfig_3(u32);
|
||||
u32 _CpuConfig_4(u32);
|
||||
u32 _CpuConfig_5(u32);
|
||||
u32 (*table_CpuConfig[6])(u32) = {_CpuConfig_0, _CpuConfig_1, _CpuConfig_2,
|
||||
_CpuConfig_3, _CpuConfig_4, _CpuConfig_5};
|
||||
|
||||
u32 dmac_CHCR[10] = {
|
||||
0xB0008000,
|
||||
0xB0009000,
|
||||
0xB000A000,
|
||||
0xB000B000,
|
||||
0xB000B400,
|
||||
0xB000C000,
|
||||
0xB000C400,
|
||||
0xB000C800,
|
||||
0xB000D000,
|
||||
0xB000D400,
|
||||
};
|
||||
|
||||
void (*VCRTable[14])() = {
|
||||
0, 0, 0, 0,
|
||||
0, 0, 0, 0,
|
||||
SyscException, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
void (*VIntTable[8])() = {
|
||||
0, 0, DMACException, INTCException,
|
||||
0, 0, 0, TIMERException,
|
||||
};
|
||||
|
||||
void _DummyINTCHandler(int);
|
||||
void _DummyDMACHandler(int);
|
||||
|
||||
void (*INTCTable[16])(int) = {
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler,
|
||||
_DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler, _DummyINTCHandler };
|
||||
|
||||
void (*DMACTable[16])(int) = {
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler,
|
||||
_DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler, _DummyDMACHandler };
|
||||
|
||||
|
||||
void (*table_SYSCALL[0x80])() = {
|
||||
(void (*))_RFU___, // 0x00
|
||||
(void (*))_ResetEE,
|
||||
(void (*))_SetGsCrt,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_Exit, // 0x04
|
||||
(void (*))_RFU005,
|
||||
(void (*))_LoadPS2Exe,
|
||||
(void (*))_ExecPS2,
|
||||
(void (*))_RFU___, // 0x08
|
||||
(void (*))_TlbWriteRandom,
|
||||
(void (*))_AddSbusIntcHandler,
|
||||
(void (*))_RemoveSbusIntcHandler,
|
||||
(void (*))_Interrupt2Iop, // 0x0C
|
||||
(void (*))_SetVTLBRefillHandler,
|
||||
(void (*))_SetVCommonHandler,
|
||||
(void (*))_SetVInterruptHandler,
|
||||
(void (*))_AddIntcHandler, // 0x10
|
||||
(void (*))_RemoveIntcHandler,
|
||||
(void (*))_AddDmacHandler,
|
||||
(void (*))_RemoveDmacHandler,
|
||||
(void (*))__EnableIntc, // 0x14
|
||||
(void (*))__DisableIntc,
|
||||
(void (*))__EnableDmac,
|
||||
(void (*))__DisableDmac,
|
||||
(void (*))_SetAlarm, // 0x18
|
||||
(void (*))_ReleaseAlarm,
|
||||
(void (*))__EnableIntc,
|
||||
(void (*))__DisableIntc,
|
||||
(void (*))__EnableDmac, // 0x1C
|
||||
(void (*))__DisableDmac,
|
||||
(void (*))_SetAlarm,
|
||||
(void (*))_ReleaseAlarm,
|
||||
(void (*))_CreateThread, // 0x20
|
||||
(void (*))_DeleteThread,
|
||||
(void (*))_StartThread,
|
||||
(void (*))_ExitThread,
|
||||
(void (*))_ExitDeleteThread, // 0x24
|
||||
(void (*))_TerminateThread,
|
||||
(void (*))_iTerminateThread,
|
||||
(void (*))_DisableDispatchThread,
|
||||
(void (*))_EnableDispatchThread, // 0x28
|
||||
(void (*))_ChangeThreadPriority,
|
||||
(void (*))_iChangeThreadPriority,
|
||||
(void (*))_RotateThreadReadyQueue,
|
||||
(void (*))_iRotateThreadReadyQueue, // 0x2C
|
||||
(void (*))_ReleaseWaitThread,
|
||||
(void (*))_iReleaseWaitThread,
|
||||
(void (*))_GetThreadId,
|
||||
(void (*))_ReferThreadStatus, // 0x30
|
||||
(void (*))_ReferThreadStatus,
|
||||
(void (*))_SleepThread,
|
||||
(void (*))_WakeupThread,
|
||||
(void (*))_iWakeupThread,
|
||||
(void (*))_CancelWakeupThread,
|
||||
(void (*))_CancelWakeupThread,
|
||||
(void (*))_SuspendThread,
|
||||
(void (*))_SuspendThread,
|
||||
(void (*))_ResumeThread,
|
||||
(void (*))_iResumeThread,
|
||||
(void (*))_JoinThread,
|
||||
(void (*))_InitializeMainThread,
|
||||
(void (*))_InitializeHeapArea,
|
||||
(void (*))_EndOfHeap,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_CreateSema, // 0x40
|
||||
(void (*))_DeleteSema,
|
||||
(void (*))_SignalSema,
|
||||
(void (*))_iSignalSema,
|
||||
(void (*))_WaitSema,
|
||||
(void (*))_PollSema,
|
||||
(void (*))_PollSema,
|
||||
(void (*))_ReferSemaStatus,
|
||||
(void (*))_ReferSemaStatus,
|
||||
(void (*))_iDeleteSema,
|
||||
(void (*))_SetOsdConfigParam,
|
||||
(void (*))_GetOsdConfigParam,
|
||||
(void (*))_GetGsHParam,
|
||||
(void (*))_GetGsVParam,
|
||||
(void (*))_SetGsHParam,
|
||||
(void (*))_SetGsVParam,
|
||||
(void (*))_CreateEventFlag, // 0x50
|
||||
(void (*))_DeleteEventFlag,
|
||||
(void (*))_SetEventFlag,
|
||||
(void (*))_iSetEventFlag,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_EnableIntcHandler,
|
||||
(void (*))_DisableIntcHandler,
|
||||
(void (*))_EnableDmacHandler,
|
||||
(void (*))_DisableDmacHandler,
|
||||
(void (*))_KSeg0, // 0x60
|
||||
(void (*))_EnableCache,
|
||||
(void (*))_DisableCache,
|
||||
(void (*))_GetCop0,
|
||||
(void (*))_FlushCache,
|
||||
(void (*))_105,
|
||||
(void (*))_CpuConfig,
|
||||
(void (*))_GetCop0,
|
||||
(void (*))_FlushCache,
|
||||
(void (*))_105,
|
||||
(void (*))_CpuConfig,
|
||||
(void (*))_SifStopDma, //_sceSifStopDma,
|
||||
(void (*))_SetCPUTimerHandler,
|
||||
(void (*))_SetCPUTimer,
|
||||
(void (*))0,//_SetOsdConfigParam2,
|
||||
(void (*))0,//_GetOsdConfigParam2,
|
||||
(void (*))_GsGetIMR, // 0x70
|
||||
(void (*))_GsPutIMR,
|
||||
(void (*))_SetPgifHandler,
|
||||
(void (*))_SetVSyncFlag,
|
||||
(void (*))_SetSYSCALL,
|
||||
(void (*))_print,
|
||||
(void (*))_SifDmaStat,
|
||||
(void (*))_SifSetDma,
|
||||
(void (*))_SifSetDChain,
|
||||
(void (*))_SifSetReg,
|
||||
(void (*))_SifGetReg,
|
||||
(void (*))_ExecOSD,
|
||||
(void (*))_RFU___,
|
||||
(void (*))_PSMode,
|
||||
(void (*))_MachineType,
|
||||
(void (*))_GetMemorySize
|
||||
};
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c) {
|
||||
while (*((u32*)0x1000f130) & 0x8000) { __asm__ ("nop\nnop\nnop\n"); }
|
||||
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
void __puts(u8 *s) {
|
||||
while (*s != 0) {
|
||||
__putc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
int __printf(const char *format, ...) {
|
||||
char buf[4096];
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf(buf, 4096, format, args);
|
||||
va_end(args);
|
||||
|
||||
__puts(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c) {
|
||||
while (*((u32*)0x1000f130) & 0x8000) { __asm__ ("nop\nnop\nnop\n"); }
|
||||
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
void __puts(u8 *s) {
|
||||
while (*s != 0) {
|
||||
__putc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
int __printf(const char *format, ...) {
|
||||
char buf[4096];
|
||||
va_list args;
|
||||
int ret;
|
||||
|
||||
va_start(args, format);
|
||||
ret = vsnprintf(buf, 4096, format, args);
|
||||
va_end(args);
|
||||
|
||||
__puts(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,423 +1,423 @@
|
|||
#include "romdir.h"
|
||||
#include "eedebug.h"
|
||||
|
||||
typedef struct {
|
||||
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
|
||||
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
|
||||
u16 e_machine; //Processor: 8=MIPS R3000
|
||||
u32 e_version; //Version: 1=current
|
||||
u32 e_entry; //Entry point address
|
||||
u32 e_phoff; //Start of program headers (offset from file start)
|
||||
u32 e_shoff; //Start of section headers (offset from file start)
|
||||
u32 e_flags; //Processor specific flags = 0x20924001 noreorder, mips
|
||||
u16 e_ehsize; //ELF header size (0x34 = 52 bytes)
|
||||
u16 e_phentsize; //Program headers entry size
|
||||
u16 e_phnum; //Number of program headers
|
||||
u16 e_shentsize; //Section headers entry size
|
||||
u16 e_shnum; //Number of section headers
|
||||
u16 e_shstrndx; //Section header stringtable index
|
||||
} ELF_HEADER;
|
||||
|
||||
typedef struct {
|
||||
u32 p_type; //see notes1
|
||||
u32 p_offset; //Offset from file start to program segment.
|
||||
u32 p_vaddr; //Virtual address of the segment
|
||||
u32 p_paddr; //Physical address of the segment
|
||||
u32 p_filesz; //Number of bytes in the file image of the segment
|
||||
u32 p_memsz; //Number of bytes in the memory image of the segment
|
||||
u32 p_flags; //Flags for segment
|
||||
u32 p_align; //Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
||||
} ELF_PHR;
|
||||
|
||||
/*
|
||||
notes1
|
||||
------
|
||||
0=Inactive
|
||||
1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
||||
2=Dynamic linking
|
||||
3=Interpreter. The array element must specify a path name
|
||||
4=Note. The array element must specify the location and size of aux. info
|
||||
5=reserved
|
||||
6=The array element must specify location and size of the program header table.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u32 sh_name; //No. to the index of the Section header stringtable index
|
||||
u32 sh_type; //See notes2
|
||||
u32 sh_flags; //see notes3
|
||||
u32 sh_addr; //Section start address
|
||||
u32 sh_offset; //Offset from start of file to section
|
||||
u32 sh_size; //Size of section
|
||||
u32 sh_link; //Section header table index link
|
||||
u32 sh_info; //Info
|
||||
u32 sh_addralign; //Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
||||
u32 sh_entsize; //Fixed size entries.
|
||||
} ELF_SHR;
|
||||
/*
|
||||
notes 2
|
||||
-------
|
||||
Type:
|
||||
0=Inactive
|
||||
1=PROGBITS
|
||||
2=SYMTAB symbol table
|
||||
3=STRTAB string table
|
||||
4=RELA relocation entries
|
||||
5=HASH hash table
|
||||
6=DYNAMIC dynamic linking information
|
||||
7=NOTE
|
||||
8=NOBITS
|
||||
9=REL relocation entries
|
||||
10=SHLIB
|
||||
0x70000000=LOPROC processor specifc
|
||||
0x7fffffff=HIPROC
|
||||
0x80000000=LOUSER lower bound
|
||||
0xffffffff=HIUSER upper bound
|
||||
|
||||
notes 3
|
||||
-------
|
||||
Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
||||
1=Write section contains data the is be writeable during execution.
|
||||
2=Alloc section occupies memory during execution
|
||||
4=Exec section contains executable instructions
|
||||
0xf0000000=Mask bits processor-specific
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u32 st_name;
|
||||
u32 st_value;
|
||||
u32 st_size;
|
||||
u8 st_info;
|
||||
u8 st_other;
|
||||
u16 st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
||||
|
||||
typedef struct {
|
||||
u32 r_offset;
|
||||
u32 r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
char *sections_names;
|
||||
|
||||
ELF_HEADER *elfHeader;
|
||||
ELF_PHR *elfProgH;
|
||||
ELF_SHR *elfSectH;
|
||||
u8 *elfdata;
|
||||
int elfsize;
|
||||
|
||||
|
||||
static void __memcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int loadHeaders() {
|
||||
elfHeader = (ELF_HEADER*)elfdata;
|
||||
|
||||
if ((elfHeader->e_shentsize != sizeof(ELF_SHR)) && (elfHeader->e_shnum > 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "type: " );
|
||||
#endif
|
||||
switch( elfHeader->e_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown %x", elfHeader->e_type );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x0:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "no file type" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "relocatable" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "executable" );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "\n" );
|
||||
ELF_LOG( "machine: " );
|
||||
#endif
|
||||
switch ( elfHeader->e_machine )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "mips_rs3000" );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("version: %d\n",elfHeader->e_version);
|
||||
ELF_LOG("entry: %08x\n",elfHeader->e_entry);
|
||||
ELF_LOG("flags: %08x\n",elfHeader->e_flags);
|
||||
ELF_LOG("eh size: %08x\n",elfHeader->e_ehsize);
|
||||
ELF_LOG("ph off: %08x\n",elfHeader->e_phoff);
|
||||
ELF_LOG("ph entsiz: %08x\n",elfHeader->e_phentsize);
|
||||
ELF_LOG("ph num: %08x\n",elfHeader->e_phnum);
|
||||
ELF_LOG("sh off: %08x\n",elfHeader->e_shoff);
|
||||
ELF_LOG("sh entsiz: %08x\n",elfHeader->e_shentsize);
|
||||
ELF_LOG("sh num: %08x\n",elfHeader->e_shnum);
|
||||
ELF_LOG("sh strndx: %08x\n",elfHeader->e_shstrndx);
|
||||
|
||||
ELF_LOG("\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int loadProgramHeaders() {
|
||||
int i;
|
||||
|
||||
if (elfHeader->e_phnum == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (elfHeader->e_phentsize != sizeof(ELF_PHR)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elfProgH = (ELF_PHR*)&elfdata[elfHeader->e_phoff];
|
||||
|
||||
for ( i = 0 ; i < elfHeader->e_phnum ; i++ )
|
||||
{
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "Elf32 Program Header\n" );
|
||||
ELF_LOG( "type: " );
|
||||
#endif
|
||||
switch ( elfProgH[ i ].p_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown %x", (int)elfProgH[ i ].p_type );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("load");
|
||||
#endif
|
||||
/* if ( elfHeader->e_shnum == 0 ) {*/
|
||||
if (elfProgH[ i ].p_offset < elfsize) {
|
||||
int size;
|
||||
|
||||
if ((elfProgH[ i ].p_filesz + elfProgH[ i ].p_offset) > elfsize) {
|
||||
size = elfsize - elfProgH[ i ].p_offset;
|
||||
} else {
|
||||
size = elfProgH[ i ].p_filesz;
|
||||
}
|
||||
// __printf("loading program to %x\n", elfProgH[ i ].p_paddr + elfbase);
|
||||
__memcpy(elfProgH[ i ].p_paddr,
|
||||
&elfdata[elfProgH[ i ].p_offset],
|
||||
size);
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\t*LOADED*");
|
||||
#endif
|
||||
// }
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("offset: %08x\n",(int)elfProgH[i].p_offset);
|
||||
ELF_LOG("vaddr: %08x\n",(int)elfProgH[i].p_vaddr);
|
||||
ELF_LOG("paddr: %08x\n",elfProgH[i].p_paddr);
|
||||
ELF_LOG("file size: %08x\n",elfProgH[i].p_filesz);
|
||||
ELF_LOG("mem size: %08x\n",elfProgH[i].p_memsz);
|
||||
ELF_LOG("flags: %08x\n",elfProgH[i].p_flags);
|
||||
ELF_LOG("palign: %08x\n",elfProgH[i].p_align);
|
||||
ELF_LOG("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loadSectionHeaders() {
|
||||
int i;
|
||||
int i_st = -1;
|
||||
int i_dt = -1;
|
||||
|
||||
if (elfHeader->e_shnum == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elfSectH = (ELF_SHR*)&elfdata[elfHeader->e_shoff];
|
||||
|
||||
if ( elfHeader->e_shstrndx < elfHeader->e_shnum ) {
|
||||
sections_names = (char *)&elfdata[elfSectH[ elfHeader->e_shstrndx ].sh_offset];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < elfHeader->e_shnum ; i++ )
|
||||
{
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "Elf32 Section Header [%x] %s", i, §ions_names[ elfSectH[ i ].sh_name ] );
|
||||
#endif
|
||||
/* if ( elfSectH[i].sh_flags & 0x2 ) {
|
||||
if (elfSectH[i].sh_offset < elfsize) {
|
||||
int size;
|
||||
|
||||
if ((elfSectH[i].sh_size + elfSectH[i].sh_offset) > elfsize) {
|
||||
size = elfsize - elfSectH[i].sh_offset;
|
||||
} else {
|
||||
size = elfSectH[i].sh_size;
|
||||
}
|
||||
memcpy(&psM[ elfSectH[ i ].sh_addr &0x1ffffff ],
|
||||
&elfdata[elfSectH[i].sh_offset],
|
||||
size);
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "\t*LOADED*" );
|
||||
#endif
|
||||
}*/
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("type: ");
|
||||
#endif
|
||||
switch ( elfSectH[ i ].sh_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("unknown %08x",elfSectH[i].sh_type);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x0:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("null");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("progbits");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("symtab");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("strtab");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("rela");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("no bits");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("rel");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("flags: %08x\n", elfSectH[i].sh_flags);
|
||||
ELF_LOG("addr: %08x\n", elfSectH[i].sh_addr);
|
||||
ELF_LOG("offset: %08x\n", elfSectH[i].sh_offset);
|
||||
ELF_LOG("size: %08x\n", elfSectH[i].sh_size);
|
||||
ELF_LOG("link: %08x\n", elfSectH[i].sh_link);
|
||||
ELF_LOG("info: %08x\n", elfSectH[i].sh_info);
|
||||
ELF_LOG("addralign: %08x\n", elfSectH[i].sh_addralign);
|
||||
ELF_LOG("entsize: %08x\n", elfSectH[i].sh_entsize);
|
||||
#endif
|
||||
// dump symbol table
|
||||
|
||||
if (elfSectH[i].sh_type == 0x02) {
|
||||
i_st = i; i_dt = elfSectH[i].sh_link;
|
||||
}
|
||||
/*
|
||||
if (elfSectH[i].sh_type == 0x01) {
|
||||
int size = elfSectH[i].sh_size / 4;
|
||||
u32 *ptr = (u32*)&psxM[(elfSectH[i].sh_addr + irx_addr) & 0x1fffff];
|
||||
|
||||
while (size) {
|
||||
|
||||
if (*ptr == 0x41e00000) { // import func
|
||||
int ret = iopSetImportFunc(ptr+1);
|
||||
size-= ret; ptr+= ret;
|
||||
}
|
||||
|
||||
if (*ptr == 0x41c00000) { // export func
|
||||
int ret = iopSetExportFunc(ptr+1);
|
||||
size-= ret; ptr+= ret;
|
||||
}
|
||||
|
||||
size--; ptr++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* if (!strcmp(".data", §ions_names[elfSectH[i].sh_name])) {
|
||||
// seems so..
|
||||
|
||||
psxRegs.GPR.n.gp = 0x8000 + irx_addr + elfSectH[i].sh_addr;
|
||||
}*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 loadElfFile(char *filename, struct elfinfo *info) {
|
||||
struct rominfo ri;
|
||||
char str[256];
|
||||
char str2[256];
|
||||
int i;
|
||||
|
||||
__printf("loadElfFile: %s\n", filename);
|
||||
|
||||
if (romdirGetFile(filename, &ri) == NULL) {
|
||||
__printf("file %s not found!!\n", filename);
|
||||
return -1;
|
||||
}
|
||||
elfdata = (u8*)(0xbfc00000 + ri.fileOffset);
|
||||
elfsize = ri.fileSize;
|
||||
|
||||
loadHeaders();
|
||||
loadProgramHeaders();
|
||||
loadSectionHeaders();
|
||||
|
||||
// __printf("loadElfFile: e_entry=%x\n", elfHeader->e_entry);
|
||||
return elfHeader->e_entry;
|
||||
}
|
||||
|
||||
#include "romdir.h"
|
||||
#include "eedebug.h"
|
||||
|
||||
typedef struct {
|
||||
u8 e_ident[16]; //0x7f,"ELF" (ELF file identifier)
|
||||
u16 e_type; //ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
|
||||
u16 e_machine; //Processor: 8=MIPS R3000
|
||||
u32 e_version; //Version: 1=current
|
||||
u32 e_entry; //Entry point address
|
||||
u32 e_phoff; //Start of program headers (offset from file start)
|
||||
u32 e_shoff; //Start of section headers (offset from file start)
|
||||
u32 e_flags; //Processor specific flags = 0x20924001 noreorder, mips
|
||||
u16 e_ehsize; //ELF header size (0x34 = 52 bytes)
|
||||
u16 e_phentsize; //Program headers entry size
|
||||
u16 e_phnum; //Number of program headers
|
||||
u16 e_shentsize; //Section headers entry size
|
||||
u16 e_shnum; //Number of section headers
|
||||
u16 e_shstrndx; //Section header stringtable index
|
||||
} ELF_HEADER;
|
||||
|
||||
typedef struct {
|
||||
u32 p_type; //see notes1
|
||||
u32 p_offset; //Offset from file start to program segment.
|
||||
u32 p_vaddr; //Virtual address of the segment
|
||||
u32 p_paddr; //Physical address of the segment
|
||||
u32 p_filesz; //Number of bytes in the file image of the segment
|
||||
u32 p_memsz; //Number of bytes in the memory image of the segment
|
||||
u32 p_flags; //Flags for segment
|
||||
u32 p_align; //Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
||||
} ELF_PHR;
|
||||
|
||||
/*
|
||||
notes1
|
||||
------
|
||||
0=Inactive
|
||||
1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
||||
2=Dynamic linking
|
||||
3=Interpreter. The array element must specify a path name
|
||||
4=Note. The array element must specify the location and size of aux. info
|
||||
5=reserved
|
||||
6=The array element must specify location and size of the program header table.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u32 sh_name; //No. to the index of the Section header stringtable index
|
||||
u32 sh_type; //See notes2
|
||||
u32 sh_flags; //see notes3
|
||||
u32 sh_addr; //Section start address
|
||||
u32 sh_offset; //Offset from start of file to section
|
||||
u32 sh_size; //Size of section
|
||||
u32 sh_link; //Section header table index link
|
||||
u32 sh_info; //Info
|
||||
u32 sh_addralign; //Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
||||
u32 sh_entsize; //Fixed size entries.
|
||||
} ELF_SHR;
|
||||
/*
|
||||
notes 2
|
||||
-------
|
||||
Type:
|
||||
0=Inactive
|
||||
1=PROGBITS
|
||||
2=SYMTAB symbol table
|
||||
3=STRTAB string table
|
||||
4=RELA relocation entries
|
||||
5=HASH hash table
|
||||
6=DYNAMIC dynamic linking information
|
||||
7=NOTE
|
||||
8=NOBITS
|
||||
9=REL relocation entries
|
||||
10=SHLIB
|
||||
0x70000000=LOPROC processor specifc
|
||||
0x7fffffff=HIPROC
|
||||
0x80000000=LOUSER lower bound
|
||||
0xffffffff=HIUSER upper bound
|
||||
|
||||
notes 3
|
||||
-------
|
||||
Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
||||
1=Write section contains data the is be writeable during execution.
|
||||
2=Alloc section occupies memory during execution
|
||||
4=Exec section contains executable instructions
|
||||
0xf0000000=Mask bits processor-specific
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u32 st_name;
|
||||
u32 st_value;
|
||||
u32 st_size;
|
||||
u8 st_info;
|
||||
u8 st_other;
|
||||
u16 st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
||||
|
||||
typedef struct {
|
||||
u32 r_offset;
|
||||
u32 r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
char *sections_names;
|
||||
|
||||
ELF_HEADER *elfHeader;
|
||||
ELF_PHR *elfProgH;
|
||||
ELF_SHR *elfSectH;
|
||||
u8 *elfdata;
|
||||
int elfsize;
|
||||
|
||||
|
||||
static void __memcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int loadHeaders() {
|
||||
elfHeader = (ELF_HEADER*)elfdata;
|
||||
|
||||
if ((elfHeader->e_shentsize != sizeof(ELF_SHR)) && (elfHeader->e_shnum > 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "type: " );
|
||||
#endif
|
||||
switch( elfHeader->e_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown %x", elfHeader->e_type );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x0:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "no file type" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "relocatable" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "executable" );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "\n" );
|
||||
ELF_LOG( "machine: " );
|
||||
#endif
|
||||
switch ( elfHeader->e_machine )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown" );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "mips_rs3000" );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("version: %d\n",elfHeader->e_version);
|
||||
ELF_LOG("entry: %08x\n",elfHeader->e_entry);
|
||||
ELF_LOG("flags: %08x\n",elfHeader->e_flags);
|
||||
ELF_LOG("eh size: %08x\n",elfHeader->e_ehsize);
|
||||
ELF_LOG("ph off: %08x\n",elfHeader->e_phoff);
|
||||
ELF_LOG("ph entsiz: %08x\n",elfHeader->e_phentsize);
|
||||
ELF_LOG("ph num: %08x\n",elfHeader->e_phnum);
|
||||
ELF_LOG("sh off: %08x\n",elfHeader->e_shoff);
|
||||
ELF_LOG("sh entsiz: %08x\n",elfHeader->e_shentsize);
|
||||
ELF_LOG("sh num: %08x\n",elfHeader->e_shnum);
|
||||
ELF_LOG("sh strndx: %08x\n",elfHeader->e_shstrndx);
|
||||
|
||||
ELF_LOG("\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int loadProgramHeaders() {
|
||||
int i;
|
||||
|
||||
if (elfHeader->e_phnum == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (elfHeader->e_phentsize != sizeof(ELF_PHR)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elfProgH = (ELF_PHR*)&elfdata[elfHeader->e_phoff];
|
||||
|
||||
for ( i = 0 ; i < elfHeader->e_phnum ; i++ )
|
||||
{
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "Elf32 Program Header\n" );
|
||||
ELF_LOG( "type: " );
|
||||
#endif
|
||||
switch ( elfProgH[ i ].p_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "unknown %x", (int)elfProgH[ i ].p_type );
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("load");
|
||||
#endif
|
||||
/* if ( elfHeader->e_shnum == 0 ) {*/
|
||||
if (elfProgH[ i ].p_offset < elfsize) {
|
||||
int size;
|
||||
|
||||
if ((elfProgH[ i ].p_filesz + elfProgH[ i ].p_offset) > elfsize) {
|
||||
size = elfsize - elfProgH[ i ].p_offset;
|
||||
} else {
|
||||
size = elfProgH[ i ].p_filesz;
|
||||
}
|
||||
// __printf("loading program to %x\n", elfProgH[ i ].p_paddr + elfbase);
|
||||
__memcpy(elfProgH[ i ].p_paddr,
|
||||
&elfdata[elfProgH[ i ].p_offset],
|
||||
size);
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\t*LOADED*");
|
||||
#endif
|
||||
// }
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("offset: %08x\n",(int)elfProgH[i].p_offset);
|
||||
ELF_LOG("vaddr: %08x\n",(int)elfProgH[i].p_vaddr);
|
||||
ELF_LOG("paddr: %08x\n",elfProgH[i].p_paddr);
|
||||
ELF_LOG("file size: %08x\n",elfProgH[i].p_filesz);
|
||||
ELF_LOG("mem size: %08x\n",elfProgH[i].p_memsz);
|
||||
ELF_LOG("flags: %08x\n",elfProgH[i].p_flags);
|
||||
ELF_LOG("palign: %08x\n",elfProgH[i].p_align);
|
||||
ELF_LOG("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loadSectionHeaders() {
|
||||
int i;
|
||||
int i_st = -1;
|
||||
int i_dt = -1;
|
||||
|
||||
if (elfHeader->e_shnum == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elfSectH = (ELF_SHR*)&elfdata[elfHeader->e_shoff];
|
||||
|
||||
if ( elfHeader->e_shstrndx < elfHeader->e_shnum ) {
|
||||
sections_names = (char *)&elfdata[elfSectH[ elfHeader->e_shstrndx ].sh_offset];
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < elfHeader->e_shnum ; i++ )
|
||||
{
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "Elf32 Section Header [%x] %s", i, §ions_names[ elfSectH[ i ].sh_name ] );
|
||||
#endif
|
||||
/* if ( elfSectH[i].sh_flags & 0x2 ) {
|
||||
if (elfSectH[i].sh_offset < elfsize) {
|
||||
int size;
|
||||
|
||||
if ((elfSectH[i].sh_size + elfSectH[i].sh_offset) > elfsize) {
|
||||
size = elfsize - elfSectH[i].sh_offset;
|
||||
} else {
|
||||
size = elfSectH[i].sh_size;
|
||||
}
|
||||
memcpy(&psM[ elfSectH[ i ].sh_addr &0x1ffffff ],
|
||||
&elfdata[elfSectH[i].sh_offset],
|
||||
size);
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG( "\t*LOADED*" );
|
||||
#endif
|
||||
}*/
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("type: ");
|
||||
#endif
|
||||
switch ( elfSectH[ i ].sh_type )
|
||||
{
|
||||
default:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("unknown %08x",elfSectH[i].sh_type);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x0:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("null");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("progbits");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("symtab");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("strtab");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("rela");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("no bits");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("rel");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef ELF_LOG
|
||||
ELF_LOG("\n");
|
||||
ELF_LOG("flags: %08x\n", elfSectH[i].sh_flags);
|
||||
ELF_LOG("addr: %08x\n", elfSectH[i].sh_addr);
|
||||
ELF_LOG("offset: %08x\n", elfSectH[i].sh_offset);
|
||||
ELF_LOG("size: %08x\n", elfSectH[i].sh_size);
|
||||
ELF_LOG("link: %08x\n", elfSectH[i].sh_link);
|
||||
ELF_LOG("info: %08x\n", elfSectH[i].sh_info);
|
||||
ELF_LOG("addralign: %08x\n", elfSectH[i].sh_addralign);
|
||||
ELF_LOG("entsize: %08x\n", elfSectH[i].sh_entsize);
|
||||
#endif
|
||||
// dump symbol table
|
||||
|
||||
if (elfSectH[i].sh_type == 0x02) {
|
||||
i_st = i; i_dt = elfSectH[i].sh_link;
|
||||
}
|
||||
/*
|
||||
if (elfSectH[i].sh_type == 0x01) {
|
||||
int size = elfSectH[i].sh_size / 4;
|
||||
u32 *ptr = (u32*)&psxM[(elfSectH[i].sh_addr + irx_addr) & 0x1fffff];
|
||||
|
||||
while (size) {
|
||||
|
||||
if (*ptr == 0x41e00000) { // import func
|
||||
int ret = iopSetImportFunc(ptr+1);
|
||||
size-= ret; ptr+= ret;
|
||||
}
|
||||
|
||||
if (*ptr == 0x41c00000) { // export func
|
||||
int ret = iopSetExportFunc(ptr+1);
|
||||
size-= ret; ptr+= ret;
|
||||
}
|
||||
|
||||
size--; ptr++;
|
||||
}
|
||||
}
|
||||
*/
|
||||
/* if (!strcmp(".data", §ions_names[elfSectH[i].sh_name])) {
|
||||
// seems so..
|
||||
|
||||
psxRegs.GPR.n.gp = 0x8000 + irx_addr + elfSectH[i].sh_addr;
|
||||
}*/
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u32 loadElfFile(char *filename, struct elfinfo *info) {
|
||||
struct rominfo ri;
|
||||
char str[256];
|
||||
char str2[256];
|
||||
int i;
|
||||
|
||||
__printf("loadElfFile: %s\n", filename);
|
||||
|
||||
if (romdirGetFile(filename, &ri) == NULL) {
|
||||
__printf("file %s not found!!\n", filename);
|
||||
return -1;
|
||||
}
|
||||
elfdata = (u8*)(0xbfc00000 + ri.fileOffset);
|
||||
elfsize = ri.fileSize;
|
||||
|
||||
loadHeaders();
|
||||
loadProgramHeaders();
|
||||
loadSectionHeaders();
|
||||
|
||||
// __printf("loadElfFile: e_entry=%x\n", elfHeader->e_entry);
|
||||
return elfHeader->e_entry;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,336 +1,336 @@
|
|||
// EE core interrupt and exception handlers
|
||||
// most functions here can only use $at, $k0, and $k1
|
||||
// [made by] [RO]man, zerofrog
|
||||
|
||||
#include "eekernel.h"
|
||||
#include "eeirq.h"
|
||||
|
||||
|
||||
#define LOAD_KERNELSTACK \
|
||||
"lui $sp, %hi(g_kernelstackend)\n" \
|
||||
"addiu $sp, %lo(g_kernelstackend)\n"
|
||||
|
||||
__asm__(".org 0x0000");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
void CpuException0() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedT9)\n"
|
||||
"sd $25, %lo(SavedT9)($26)\n"
|
||||
|
||||
"mfc0 $25, $13\n"
|
||||
"andi $25, 0x7C\n"
|
||||
"lui $26, %hi(VCRTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VCRTable)($26)\n"
|
||||
|
||||
"lui $25, %hi(SavedT9)\n"
|
||||
"jr $26\n"
|
||||
"ld $25, %lo(SavedT9)($25)\n"
|
||||
);
|
||||
}
|
||||
|
||||
__asm__(".org 0x0180");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
void CpuException() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedT9)\n"
|
||||
"sd $25, %lo(SavedT9)($26)\n"
|
||||
|
||||
"mfc0 $25, $13\n"
|
||||
"andi $25, 0x7C\n"
|
||||
"lui $26, %hi(VCRTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VCRTable)($26)\n"
|
||||
|
||||
"lui $25, %hi(SavedT9)\n"
|
||||
"jr $26\n"
|
||||
"ld $25, %lo(SavedT9)($25)\n"
|
||||
);
|
||||
}
|
||||
|
||||
__asm__(".org 0x0200");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
__asm__(".set noat");
|
||||
void CpuException2() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"sq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"sq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"sq $1, %lo(SavedAT)($26)\n"
|
||||
|
||||
"mfc0 $1, $13\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"and $1, $26\n"
|
||||
"srl $1, 8\n"
|
||||
"andi $1, 0xFF\n"
|
||||
|
||||
"plzcw $26, $1\n"
|
||||
"andi $26, 0xFF\n"
|
||||
"ori $1, $0, 0x1E\n"
|
||||
"subu $1, $26\n"
|
||||
"sll $1, 2\n"
|
||||
"lui $26, %hi(VIntTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VIntTable)($26)\n"
|
||||
"jr $26\n"
|
||||
"nop\n"
|
||||
);
|
||||
}
|
||||
|
||||
extern char call_used_regs[];
|
||||
extern char fixed_regs[];
|
||||
|
||||
__asm__(".org 0x0280");
|
||||
__asm__(".set noreorder");
|
||||
|
||||
void SyscException()
|
||||
{
|
||||
const register int code __asm__("$3"); // $v1
|
||||
|
||||
if (code < 0) {
|
||||
__asm__(
|
||||
"addiu $sp, -0x10\n"
|
||||
"sw $31, 0($sp)\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"addiu $26, 4\n"
|
||||
"sw $26, 4($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n");
|
||||
|
||||
table_SYSCALL[-code]();
|
||||
|
||||
__asm__(
|
||||
"lw $26, 4($sp)\n"
|
||||
"lw $31, 0($sp)\n"
|
||||
"addiu $sp, 0x10\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
if (code == 0x7c) {
|
||||
_Deci2Call();
|
||||
return;
|
||||
}
|
||||
|
||||
__asm__(
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"sq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"sq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"sq $1, %lo(SavedAT)($26)\n"
|
||||
|
||||
"mfc0 $1, $12\n"
|
||||
"addiu $26, $0, 0xFFE4\n"
|
||||
"and $1, $26\n"
|
||||
"mtc0 $1, $12\n"
|
||||
"sync\n"
|
||||
|
||||
"move $26, $sp\n"
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"sw $31, 0($sp)\n"
|
||||
"sw $26, 4($sp)\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"addiu $26, 4\n"
|
||||
"sw $26, 8($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n");
|
||||
|
||||
table_SYSCALL[code]();
|
||||
|
||||
__asm__(
|
||||
"lw $26, 8($sp)\n"
|
||||
"lw $31, 0($sp)\n"
|
||||
"lw $sp, 4($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
void _Deci2Call() {
|
||||
__puts("_Deci2Call called\n");
|
||||
}
|
||||
|
||||
void __ThreadHandler();
|
||||
|
||||
void INTCException() {
|
||||
u32 code;
|
||||
u32 temp;
|
||||
|
||||
code = INTC_STAT & INTC_MASK;
|
||||
if (code & 0xC0) {
|
||||
int VpuStat;
|
||||
|
||||
__asm__("cfc2 %0, $29\n" : "=r"(VpuStat) : );
|
||||
if (VpuStat & 0x202) {
|
||||
__asm__(
|
||||
".set noat\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n");
|
||||
__exception();
|
||||
}
|
||||
}
|
||||
__asm__ (
|
||||
"mfc0 $26, $14\n"
|
||||
"li $27, 0xFFFFFFE4\n"
|
||||
"and $26, $27\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"sw $26, 0($sp)\n"
|
||||
);
|
||||
saveContext2();
|
||||
|
||||
__asm__ (
|
||||
"plzcw %0, %1"
|
||||
: "=r"(temp) : "r"(code)
|
||||
);
|
||||
temp = 0x1e - (temp & 0xff);
|
||||
INTC_STAT = 1 << temp;
|
||||
threadStatus = 0;
|
||||
|
||||
INTCTable[temp](temp);
|
||||
|
||||
restoreContext2();
|
||||
|
||||
__asm__ (
|
||||
".set noat\n"
|
||||
"lw $26, 0($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"lq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"lq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n"
|
||||
);
|
||||
|
||||
if (!threadStatus) {
|
||||
__asm__ (
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
);
|
||||
}
|
||||
__asm__(LOAD_KERNELSTACK);
|
||||
threadStatus = 0;
|
||||
|
||||
__ThreadHandler();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//800004C0
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DMACException() {
|
||||
unsigned int code;
|
||||
unsigned int temp;
|
||||
|
||||
code = (DMAC_STAT >> 16) | 0x8000;
|
||||
code&= DMAC_STAT & 0xFFFF;
|
||||
if (code & 0x80) {
|
||||
//__printf("%s: code & 0x80\n", __FUNCTION__);
|
||||
__asm__(
|
||||
".set noat\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n");
|
||||
__exception1();
|
||||
}
|
||||
__asm__ (
|
||||
"mfc0 $26, $14\n"
|
||||
"li $27, 0xFFFFFFE4\n"
|
||||
"and $26, $27\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"sw $26, 0($sp)\n"
|
||||
);
|
||||
saveContext2();
|
||||
|
||||
__asm__ (
|
||||
"plzcw %0, %1"
|
||||
: "=r"(temp) : "r"(code)
|
||||
);
|
||||
temp = 0x1e - (temp & 0xff);
|
||||
DMAC_STAT = 1 << temp;
|
||||
threadStatus = 0;
|
||||
|
||||
DMACTable[temp](temp);
|
||||
|
||||
restoreContext2();
|
||||
|
||||
__asm__ (
|
||||
".set noat\n"
|
||||
"lw $26, 0($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"lq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"lq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n"
|
||||
);
|
||||
|
||||
if (!threadStatus) {
|
||||
__asm__ (
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
);
|
||||
}
|
||||
__asm__(LOAD_KERNELSTACK);
|
||||
threadStatus = 0;
|
||||
|
||||
__ThreadHandler();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000600
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TIMERException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000700
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void setINTCHandler(int n, void (*phandler)(int))
|
||||
{
|
||||
INTCTable[n] = phandler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000780
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void setDMACHandler(int n, void (*phandler)(int))
|
||||
{
|
||||
DMACTable[n] = phandler;
|
||||
}
|
||||
// EE core interrupt and exception handlers
|
||||
// most functions here can only use $at, $k0, and $k1
|
||||
// [made by] [RO]man, zerofrog
|
||||
|
||||
#include "eekernel.h"
|
||||
#include "eeirq.h"
|
||||
|
||||
|
||||
#define LOAD_KERNELSTACK \
|
||||
"lui $sp, %hi(g_kernelstackend)\n" \
|
||||
"addiu $sp, %lo(g_kernelstackend)\n"
|
||||
|
||||
__asm__(".org 0x0000");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
void CpuException0() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedT9)\n"
|
||||
"sd $25, %lo(SavedT9)($26)\n"
|
||||
|
||||
"mfc0 $25, $13\n"
|
||||
"andi $25, 0x7C\n"
|
||||
"lui $26, %hi(VCRTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VCRTable)($26)\n"
|
||||
|
||||
"lui $25, %hi(SavedT9)\n"
|
||||
"jr $26\n"
|
||||
"ld $25, %lo(SavedT9)($25)\n"
|
||||
);
|
||||
}
|
||||
|
||||
__asm__(".org 0x0180");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
void CpuException() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedT9)\n"
|
||||
"sd $25, %lo(SavedT9)($26)\n"
|
||||
|
||||
"mfc0 $25, $13\n"
|
||||
"andi $25, 0x7C\n"
|
||||
"lui $26, %hi(VCRTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VCRTable)($26)\n"
|
||||
|
||||
"lui $25, %hi(SavedT9)\n"
|
||||
"jr $26\n"
|
||||
"ld $25, %lo(SavedT9)($25)\n"
|
||||
);
|
||||
}
|
||||
|
||||
__asm__(".org 0x0200");
|
||||
|
||||
__asm__(".set noreorder");
|
||||
__asm__(".set noat");
|
||||
void CpuException2() {
|
||||
__asm__ (
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"sq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"sq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"sq $1, %lo(SavedAT)($26)\n"
|
||||
|
||||
"mfc0 $1, $13\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"and $1, $26\n"
|
||||
"srl $1, 8\n"
|
||||
"andi $1, 0xFF\n"
|
||||
|
||||
"plzcw $26, $1\n"
|
||||
"andi $26, 0xFF\n"
|
||||
"ori $1, $0, 0x1E\n"
|
||||
"subu $1, $26\n"
|
||||
"sll $1, 2\n"
|
||||
"lui $26, %hi(VIntTable)\n"
|
||||
"addu $26, $25\n"
|
||||
"lw $26, %lo(VIntTable)($26)\n"
|
||||
"jr $26\n"
|
||||
"nop\n"
|
||||
);
|
||||
}
|
||||
|
||||
extern char call_used_regs[];
|
||||
extern char fixed_regs[];
|
||||
|
||||
__asm__(".org 0x0280");
|
||||
__asm__(".set noreorder");
|
||||
|
||||
void SyscException()
|
||||
{
|
||||
const register int code __asm__("$3"); // $v1
|
||||
|
||||
if (code < 0) {
|
||||
__asm__(
|
||||
"addiu $sp, -0x10\n"
|
||||
"sw $31, 0($sp)\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"addiu $26, 4\n"
|
||||
"sw $26, 4($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n");
|
||||
|
||||
table_SYSCALL[-code]();
|
||||
|
||||
__asm__(
|
||||
"lw $26, 4($sp)\n"
|
||||
"lw $31, 0($sp)\n"
|
||||
"addiu $sp, 0x10\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
if (code == 0x7c) {
|
||||
_Deci2Call();
|
||||
return;
|
||||
}
|
||||
|
||||
__asm__(
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"sq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"sq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"sq $1, %lo(SavedAT)($26)\n"
|
||||
|
||||
"mfc0 $1, $12\n"
|
||||
"addiu $26, $0, 0xFFE4\n"
|
||||
"and $1, $26\n"
|
||||
"mtc0 $1, $12\n"
|
||||
"sync\n"
|
||||
|
||||
"move $26, $sp\n"
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"sw $31, 0($sp)\n"
|
||||
"sw $26, 4($sp)\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"addiu $26, 4\n"
|
||||
"sw $26, 8($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n");
|
||||
|
||||
table_SYSCALL[code]();
|
||||
|
||||
__asm__(
|
||||
"lw $26, 8($sp)\n"
|
||||
"lw $31, 0($sp)\n"
|
||||
"lw $sp, 4($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
"nop\n");
|
||||
}
|
||||
|
||||
void _Deci2Call() {
|
||||
__puts("_Deci2Call called\n");
|
||||
}
|
||||
|
||||
void __ThreadHandler();
|
||||
|
||||
void INTCException() {
|
||||
u32 code;
|
||||
u32 temp;
|
||||
|
||||
code = INTC_STAT & INTC_MASK;
|
||||
if (code & 0xC0) {
|
||||
int VpuStat;
|
||||
|
||||
__asm__("cfc2 %0, $29\n" : "=r"(VpuStat) : );
|
||||
if (VpuStat & 0x202) {
|
||||
__asm__(
|
||||
".set noat\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n");
|
||||
__exception();
|
||||
}
|
||||
}
|
||||
__asm__ (
|
||||
"mfc0 $26, $14\n"
|
||||
"li $27, 0xFFFFFFE4\n"
|
||||
"and $26, $27\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"sw $26, 0($sp)\n"
|
||||
);
|
||||
saveContext2();
|
||||
|
||||
__asm__ (
|
||||
"plzcw %0, %1"
|
||||
: "=r"(temp) : "r"(code)
|
||||
);
|
||||
temp = 0x1e - (temp & 0xff);
|
||||
INTC_STAT = 1 << temp;
|
||||
threadStatus = 0;
|
||||
|
||||
INTCTable[temp](temp);
|
||||
|
||||
restoreContext2();
|
||||
|
||||
__asm__ (
|
||||
".set noat\n"
|
||||
"lw $26, 0($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"lq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"lq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n"
|
||||
);
|
||||
|
||||
if (!threadStatus) {
|
||||
__asm__ (
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
);
|
||||
}
|
||||
__asm__(LOAD_KERNELSTACK);
|
||||
threadStatus = 0;
|
||||
|
||||
__ThreadHandler();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//800004C0
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DMACException() {
|
||||
unsigned int code;
|
||||
unsigned int temp;
|
||||
|
||||
code = (DMAC_STAT >> 16) | 0x8000;
|
||||
code&= DMAC_STAT & 0xFFFF;
|
||||
if (code & 0x80) {
|
||||
//__printf("%s: code & 0x80\n", __FUNCTION__);
|
||||
__asm__(
|
||||
".set noat\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n");
|
||||
__exception1();
|
||||
}
|
||||
__asm__ (
|
||||
"mfc0 $26, $14\n"
|
||||
"li $27, 0xFFFFFFE4\n"
|
||||
"and $26, $27\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"sync\n"
|
||||
|
||||
LOAD_KERNELSTACK
|
||||
"addiu $sp, -0x10\n"
|
||||
"mfc0 $26, $14\n"
|
||||
"sw $26, 0($sp)\n"
|
||||
);
|
||||
saveContext2();
|
||||
|
||||
__asm__ (
|
||||
"plzcw %0, %1"
|
||||
: "=r"(temp) : "r"(code)
|
||||
);
|
||||
temp = 0x1e - (temp & 0xff);
|
||||
DMAC_STAT = 1 << temp;
|
||||
threadStatus = 0;
|
||||
|
||||
DMACTable[temp](temp);
|
||||
|
||||
restoreContext2();
|
||||
|
||||
__asm__ (
|
||||
".set noat\n"
|
||||
"lw $26, 0($sp)\n"
|
||||
"mtc0 $26, $14\n"
|
||||
"lui $26, %hi(SavedSP)\n"
|
||||
"lq $sp, %lo(SavedSP)($26)\n"
|
||||
"lui $26, %hi(SavedRA)\n"
|
||||
"lq $31, %lo(SavedRA)($26)\n"
|
||||
"lui $26, %hi(SavedAT)\n"
|
||||
"lq $1, %lo(SavedAT)($26)\n"
|
||||
".set at\n"
|
||||
);
|
||||
|
||||
if (!threadStatus) {
|
||||
__asm__ (
|
||||
"mfc0 $26, $12\n"
|
||||
"ori $26, 0x13\n"
|
||||
"mtc0 $26, $12\n"
|
||||
"sync\n"
|
||||
"eret\n"
|
||||
);
|
||||
}
|
||||
__asm__(LOAD_KERNELSTACK);
|
||||
threadStatus = 0;
|
||||
|
||||
__ThreadHandler();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000600
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TIMERException()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000700
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void setINTCHandler(int n, void (*phandler)(int))
|
||||
{
|
||||
INTCTable[n] = phandler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//80000780
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void setDMACHandler(int n, void (*phandler)(int))
|
||||
{
|
||||
DMACTable[n] = phandler;
|
||||
}
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eeload.h"
|
||||
#include "eeinit.h"
|
||||
#include "eedebug.h"
|
||||
|
||||
void __attribute__((noreturn)) eeload_start() {
|
||||
void (*entry)();
|
||||
__puts("EELOAD start\n");
|
||||
|
||||
__printf("about to SifInitRpc(0)\n");
|
||||
SifInitRpc(0);
|
||||
__printf("done rpc\n");
|
||||
|
||||
entry = (void (*)())loadElfFile("INTRO");
|
||||
entry();
|
||||
|
||||
entry = (void (*)())loadElfFile("LOADER");
|
||||
entry();
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
void Kmemcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "eeload.h"
|
||||
#include "eeinit.h"
|
||||
#include "eedebug.h"
|
||||
|
||||
void __attribute__((noreturn)) eeload_start() {
|
||||
void (*entry)();
|
||||
__puts("EELOAD start\n");
|
||||
|
||||
__printf("about to SifInitRpc(0)\n");
|
||||
SifInitRpc(0);
|
||||
__printf("done rpc\n");
|
||||
|
||||
entry = (void (*)())loadElfFile("INTRO");
|
||||
entry();
|
||||
|
||||
entry = (void (*)())loadElfFile("LOADER");
|
||||
entry();
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
void Kmemcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef __EEDEBUG_H__
|
||||
#define __EEDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
int __printf(const char *format, ...);
|
||||
|
||||
#endif /* __EEDEBUG_H__ */
|
||||
#ifndef __EEDEBUG_H__
|
||||
#define __EEDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
int __printf(const char *format, ...);
|
||||
|
||||
#endif /* __EEDEBUG_H__ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __EEELF_H__
|
||||
#define __EEELF_H__
|
||||
|
||||
u32 loadElfFile(char *filename);
|
||||
|
||||
#endif
|
||||
#ifndef __EEELF_H__
|
||||
#define __EEELF_H__
|
||||
|
||||
u32 loadElfFile(char *filename);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef __EEINIT_H__
|
||||
#define __EEINIT_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void TlbInit();
|
||||
|
||||
#endif /* __EEINIT_H__ */
|
||||
#ifndef __EEINIT_H__
|
||||
#define __EEINIT_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void TlbInit();
|
||||
|
||||
#endif /* __EEINIT_H__ */
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
#ifndef __EEIRQ_H__
|
||||
#define __EEIRQ_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void CpuException0();
|
||||
void CpuException();
|
||||
void CpuException2();
|
||||
void SyscException();
|
||||
void _Deci2Call();
|
||||
void INTCException();
|
||||
void DMACException();
|
||||
void TIMERException();
|
||||
void setINTCHandler(int n, void (*phandler)(int));
|
||||
void setDMACHandler(int n, void (*phandler)(int));
|
||||
|
||||
#endif /* __EEIRQ_H__ */
|
||||
#ifndef __EEIRQ_H__
|
||||
#define __EEIRQ_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void CpuException0();
|
||||
void CpuException();
|
||||
void CpuException2();
|
||||
void SyscException();
|
||||
void _Deci2Call();
|
||||
void INTCException();
|
||||
void DMACException();
|
||||
void TIMERException();
|
||||
void setINTCHandler(int n, void (*phandler)(int));
|
||||
void setDMACHandler(int n, void (*phandler)(int));
|
||||
|
||||
#endif /* __EEIRQ_H__ */
|
||||
|
|
|
@ -1,447 +1,447 @@
|
|||
#ifndef __EEKERNEL_H__
|
||||
#define __EEKERNEL_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
#define RCNT0_COUNT *(volatile int*)0xB0000000
|
||||
#define RCNT0_MODE *(volatile int*)0xB0000010
|
||||
#define RCNT0_TARGET *(volatile int*)0xB0000020
|
||||
#define RCNT0_HOLD *(volatile int*)0xB0000030
|
||||
|
||||
#define RCNT1_COUNT *(volatile int*)0xB0000800
|
||||
#define RCNT1_MODE *(volatile int*)0xB0000810
|
||||
#define RCNT1_TARGET *(volatile int*)0xB0000820
|
||||
#define RCNT1_HOLD *(volatile int*)0xB0000830
|
||||
|
||||
#define RCNT2_COUNT *(volatile int*)0xB0001000
|
||||
#define RCNT2_MODE *(volatile int*)0xB0001010
|
||||
#define RCNT2_TARGET *(volatile int*)0xB0001020
|
||||
|
||||
#define RCNT3_COUNT *(volatile int*)0xB0001800
|
||||
#define RCNT3_MODE *(volatile int*)0xB0001810
|
||||
#define RCNT3_TARGET *(volatile int*)0xB0001820
|
||||
|
||||
#define GIF_CTRL *(volatile int*)0xB0003000
|
||||
|
||||
#define GIF_FIFO *(volatile u128*)0xB0006000
|
||||
|
||||
//SIF0
|
||||
#define D5_CHCR *(volatile int*)0xB000C000
|
||||
#define D5_MADR *(volatile int*)0xB000C010
|
||||
#define D5_QWC *(volatile int*)0xB000C020
|
||||
|
||||
//SIF1
|
||||
#define D6_CHCR *(volatile int*)0xB000C400
|
||||
#define D6_MADR *(volatile int*)0xB000C410
|
||||
#define D6_QWC *(volatile int*)0xB000C420
|
||||
#define D6_TAG *(volatile int*)0xB000C430
|
||||
|
||||
#define DMAC_CTRL *(volatile int*)0xB000E000
|
||||
#define DMAC_STAT *(volatile int*)0xB000E010
|
||||
#define DMAC_PCR *(volatile int*)0xB000E020
|
||||
#define DMAC_SQWC *(volatile int*)0xB000E030
|
||||
#define DMAC_RBSR *(volatile int*)0xB000E040
|
||||
#define DMAC_RBOR *(volatile int*)0xB000E050
|
||||
#define DMAC_STADR *(volatile int*)0xB000E060
|
||||
|
||||
#define INTC_STAT *(volatile int*)0xB000F000
|
||||
#define INTC_MASK *(volatile int*)0xB000F010
|
||||
|
||||
#define SBUS_MSFLG *(volatile int*)0xB000F220
|
||||
#define SBUS_SMFLG *(volatile int*)0xB000F230
|
||||
#define SBUS_F240 *(volatile int*)0xB000F240
|
||||
|
||||
#define DMAC_ENABLER *(volatile int*)0xB000F520
|
||||
#define DMAC_ENABLEW *(volatile int*)0xB000F590
|
||||
|
||||
#define SBFLG_IOPALIVE 0x10000
|
||||
#define SBFLG_IOPSYNC 0x40000
|
||||
|
||||
#define GS_PMODE *(volatile u64*)0xB2000000
|
||||
#define GS_SMODE1 *(volatile u64*)0xB2000010
|
||||
#define GS_SMODE2 *(volatile u64*)0xB2000020
|
||||
#define GS_SRFSH *(volatile u64*)0xB2000030
|
||||
#define GS_SYNCH1 *(volatile u64*)0xB2000040
|
||||
#define GS_SYNCH2 *(volatile u64*)0xB2000050
|
||||
#define GS_SYNCV *(volatile u64*)0xB2000060
|
||||
#define GS_DISPFB1 *(volatile u64*)0xB2000070
|
||||
#define GS_DISPLAY1 *(volatile u64*)0xB2000080
|
||||
#define GS_DISPFB2 *(volatile u64*)0xB2000090
|
||||
#define GS_DISPLAY2 *(volatile u64*)0xB20000A0
|
||||
#define GS_EXTBUF *(volatile u64*)0xB20000B0
|
||||
#define GS_EXTDATA *(volatile u64*)0xB20000C0
|
||||
#define GS_EXTWRITE *(volatile u64*)0xB20000D0
|
||||
#define GS_BGCOLOR *(volatile u64*)0xB20000E0
|
||||
#define GS_CSR *(volatile u64*)0xB2001000
|
||||
#define GS_IMR *(volatile u64*)0xB2001010
|
||||
#define GS_BUSDIR *(volatile u64*)0xB2001040
|
||||
#define GS_SIGLBLID *(volatile u64*)0xB2001080
|
||||
|
||||
#define INTC_GS 0
|
||||
#define INTC_SBUS 1
|
||||
#define INTC_VBLANK_S 2
|
||||
#define INTC_VBLANK_E 3
|
||||
#define INTC_VIF0 4
|
||||
#define INTC_VIF1 5
|
||||
#define INTC_VU0 6
|
||||
#define INTC_VU1 7
|
||||
#define INTC_IPU 8
|
||||
#define INTC_TIM0 9
|
||||
#define INTC_TIM1 10
|
||||
#define INTC_TIM2 11
|
||||
#define INTC_TIM3 12 //threads
|
||||
//#define INTC_13 13 //not used
|
||||
//#define INTC_14 14 //not used
|
||||
|
||||
#define DMAC_VIF0 0
|
||||
#define DMAC_VIF1 1
|
||||
#define DMAC_GIF 2
|
||||
#define DMAC_FROM_IPU 3
|
||||
#define DMAC_TO_IPU 4
|
||||
#define DMAC_SIF0 5
|
||||
#define DMAC_SIF1 6
|
||||
#define DMAC_SIF2 7
|
||||
#define DMAC_FROM_SPR 8
|
||||
#define DMAC_TO_SPR 9
|
||||
//#define DMAC_10 10 //not used
|
||||
//#define DMAC_11 11 //not used
|
||||
//#define DMAC_12 12 //not used
|
||||
//#define DMAC_13 13 //not used
|
||||
//#define DMAC_14 14 //not used
|
||||
#define DMAC_ERROR 15
|
||||
|
||||
///////////////////////
|
||||
// DMA TAG REGISTERS //
|
||||
///////////////////////
|
||||
#define DMA_TAG_REFE 0x00
|
||||
#define DMA_TAG_CNT 0x01
|
||||
#define DMA_TAG_NEXT 0x02
|
||||
#define DMA_TAG_REF 0x03
|
||||
#define DMA_TAG_REFS 0x04
|
||||
#define DMA_TAG_CALL 0x05
|
||||
#define DMA_TAG_RET 0x06
|
||||
#define DMA_TAG_END 0x07
|
||||
|
||||
// Modes for DMA transfers
|
||||
#define SIF_DMA_FROM_IOP 0x0
|
||||
#define SIF_DMA_TO_IOP 0x1
|
||||
#define SIF_DMA_FROM_EE 0x0
|
||||
#define SIF_DMA_TO_EE 0x1
|
||||
|
||||
#define SIF_DMA_INT_I 0x2
|
||||
#define SIF_DMA_INT_O 0x4
|
||||
#define SIF_DMA_SPR 0x8
|
||||
#define SIF_DMA_BSN 0x10 /* ? what is this? */
|
||||
#define SIF_DMA_TAG 0x20
|
||||
#define SIF_DMA_ERT 0x40
|
||||
#define DMA_TAG_IRQ 0x80000000
|
||||
#define DMA_TAG_PCE 0x0C000000
|
||||
|
||||
#define KSEG1_ADDR(x) (((u32)(x))|0xA0000000)
|
||||
#define KUSEG_ADDR(x) (((u32)(x))&0x1FFFFFFF)
|
||||
|
||||
#define MAX_SEMAS 256
|
||||
#define STACK_RES 0x2A0
|
||||
|
||||
//?
|
||||
#define SRInitVal 0x70030C13
|
||||
#define ConfigInitVal 0x73003
|
||||
|
||||
enum {
|
||||
THS_RUN = 0x01,
|
||||
THS_READY = 0x02,
|
||||
THS_WAIT = 0x04,
|
||||
THS_SUSPEND = 0x08,
|
||||
THS_DORMANT = 0x10,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u128 gpr[24]; // v0-t9 (skip r0,at,k0-ra)
|
||||
u128 gp;
|
||||
u128 fp;
|
||||
u128 hi;
|
||||
u128 lo;
|
||||
u32 sa;
|
||||
} eeRegs;
|
||||
|
||||
struct ThreadParam {
|
||||
int status;
|
||||
void (*entry)(void*);
|
||||
void *stack;
|
||||
int stackSize;
|
||||
void *gpReg;
|
||||
int initPriority;
|
||||
int currentPriority;
|
||||
u32 attr;
|
||||
u32 option;
|
||||
int waitSema; // waitType?
|
||||
int waitId;
|
||||
int wakeupCount;
|
||||
};
|
||||
|
||||
struct TCB { //internal struct
|
||||
struct TCB *next; //+00
|
||||
struct TCB *prev; //+04
|
||||
int status;//+08
|
||||
void (*entry)(void*); //+0C
|
||||
void *stack_res; //+10 initial $sp
|
||||
void *gpReg; //+14
|
||||
short currentPriority; //+18
|
||||
short initPriority; //+1A
|
||||
int waitSema, //+1C waitType?
|
||||
semaId, //+20
|
||||
wakeupCount, //+24
|
||||
attr, //+28
|
||||
option; //+2C
|
||||
void (*entry_)(void*); //+30
|
||||
int argc; //+34
|
||||
char *argstring;//+38
|
||||
void *stack;//+3C
|
||||
int stackSize; //+40
|
||||
int (*root)(); //+44
|
||||
void* heap_base; //+48
|
||||
};
|
||||
|
||||
struct threadCtx {
|
||||
u128 gpr[25]; // at-t9, (skip r0,k0-ra)
|
||||
u128 gp; //+190
|
||||
u128 sp; //+1A0
|
||||
u128 fp; //+1B0
|
||||
u128 ra; //+1C0
|
||||
u128 hi; //+1D0
|
||||
u128 lo; //+1E0
|
||||
u32 sa; //+1F0
|
||||
u32 cf31;//+1F4
|
||||
u32 acc; //+1F8
|
||||
u32 res; //+1FC
|
||||
u32 fpr[32];//+200
|
||||
};
|
||||
|
||||
typedef struct tag_ARGS{
|
||||
int argc;
|
||||
char *argv[16];
|
||||
char args[256];
|
||||
} ARGS;
|
||||
|
||||
struct SemaParam {
|
||||
int count;
|
||||
int max_count;
|
||||
int init_count;
|
||||
int wait_threads;
|
||||
int attr;
|
||||
u32 option;
|
||||
};
|
||||
|
||||
struct kSema { // internal struct
|
||||
struct kSema *free;//+00
|
||||
int count;//+04
|
||||
int max_count;//+08
|
||||
int attr;//+0C
|
||||
int option;//+10
|
||||
int wait_threads;//+14
|
||||
struct TCB *wait_next,//+18
|
||||
*wait_prev;//+1C
|
||||
};
|
||||
|
||||
struct ll { struct ll *next, *prev; }; //linked list
|
||||
|
||||
//internal struct
|
||||
struct IDhandl { //intc dmac handler
|
||||
struct ll *next, //+00
|
||||
*prev; //+04
|
||||
int (*handler)(int); //+08
|
||||
u32 gp; //+0C
|
||||
void *arg; //+10
|
||||
int flag; //+14
|
||||
};
|
||||
|
||||
//internal struct
|
||||
struct HCinfo{ //handler cause info
|
||||
int count;
|
||||
struct ll l;
|
||||
};
|
||||
|
||||
extern u128 SavedSP;
|
||||
extern u128 SavedRA;
|
||||
extern u128 SavedAT;
|
||||
extern u64 SavedT9;
|
||||
|
||||
extern eeRegs SavedRegs;
|
||||
|
||||
extern u32 excepRA;
|
||||
extern u32 excepSP;
|
||||
|
||||
extern u32 (*table_CpuConfig[6])(u32);
|
||||
extern void (*table_SYSCALL[0x80])();
|
||||
|
||||
extern void (*VCRTable[14])();
|
||||
extern void (*VIntTable[8])();
|
||||
extern void (*INTCTable[16])(int);
|
||||
extern void (*DMACTable[16])(int);
|
||||
|
||||
extern int threadId;
|
||||
extern int threadPrio;
|
||||
extern int threadStatus;
|
||||
|
||||
extern u64 hvParam;
|
||||
|
||||
extern u32 machineType;
|
||||
extern u64 gsIMR;
|
||||
extern u32 memorySize;
|
||||
|
||||
extern u32 g_kernelstackend;
|
||||
|
||||
extern u32 dmac_CHCR[10];
|
||||
|
||||
extern int VSyncFlag0;
|
||||
extern int VSyncFlag1;
|
||||
|
||||
extern int _HandlersCount;
|
||||
extern struct ll handler_ll_free, *ihandlers_last, *ihandlers_first;
|
||||
extern struct HCinfo intcs_array[14];
|
||||
extern struct ll *dhandlers_last, *dhandlers_first;
|
||||
extern struct HCinfo dmacs_array[15];
|
||||
extern struct IDhandl pgifhandlers_array[161];
|
||||
extern void (*sbus_handlers[32])(int ca);
|
||||
|
||||
extern int rcnt3Code;
|
||||
extern int rcnt3TargetTable[0x142];
|
||||
extern u8 rcnt3TargetNum[0x40];
|
||||
extern int threads_count;
|
||||
extern struct ll thread_ll_free;
|
||||
extern struct ll thread_ll_priorities[128];
|
||||
extern int semas_count;
|
||||
extern struct kSema* semas_last;
|
||||
|
||||
extern struct TCB threads_array[256];
|
||||
extern struct kSema semas_array[256];
|
||||
|
||||
extern char tagindex;
|
||||
extern short transferscount;
|
||||
extern struct TAG{
|
||||
int id_qwc;
|
||||
int addr;
|
||||
int unk[2];
|
||||
} tadrptr[31];
|
||||
extern int extrastorage[(16/4) * 8][31];
|
||||
|
||||
extern int osdConfigParam;
|
||||
|
||||
// syscalls
|
||||
// Every syscall is officially prefixed with _ (to avoid clashing with ps2sdk)
|
||||
void _SetSYSCALL(int num, int address);
|
||||
int __EnableIntc(int ch);
|
||||
int __DisableIntc(int ch);
|
||||
int __EnableDmac(int ch);
|
||||
int __DisableDmac(int ch);
|
||||
void *_SetVTLBRefillHandler(int cause, void (*handler)());
|
||||
void *_SetVCommonHandler(int cause, void (*handler)());
|
||||
void *_SetVInterruptHandler(int cause, void (*handler)());
|
||||
void _PSMode();
|
||||
u32 _MachineType();
|
||||
u32 _SetMemorySize(u32 size);
|
||||
u32 _GetMemorySize();
|
||||
u64 _GsGetIMR();
|
||||
u64 _GsPutIMR(u64 val);
|
||||
int _Exit(); // 3
|
||||
void _RFU___(); // 0
|
||||
void _SetVSyncFlag(int flag0, int flag1);
|
||||
int _AddIntcHandler(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _AddIntcHandler2(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _RemoveIntcHandler(int cause, int hid);
|
||||
int _AddDmacHandler(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _AddDmacHandler2(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _RemoveDmacHandler(int code, int hid);
|
||||
int _AddSbusIntcHandler(int cause, void (*handler)(int ca));
|
||||
int _RemoveSbusIntcHandler(int cause);
|
||||
int _Interrupt2Iop(int cause);
|
||||
void _RFU005();
|
||||
int _GetCop0(int reg);
|
||||
int _ExecPS2(void *, void *, int, char **);
|
||||
int _DeleteThread(int tid);
|
||||
int _StartThread(int tid, void *arg);
|
||||
int _ExitThread();
|
||||
int _ExitDeleteThread();
|
||||
int _SleepThread();
|
||||
int _WakeupThread(int tid);
|
||||
int _WaitSema(int sid);
|
||||
void _ChangeThreadPriority(int tid, int prio);
|
||||
int _CreateThread(struct ThreadParam *param);
|
||||
int _iChangeThreadPriority(int tid, int prio);
|
||||
int _GetThreadId();
|
||||
int _ReferThreadStatus(int tid, struct ThreadParam *info);
|
||||
int _iWakeupThread(int tid);
|
||||
int _SuspendThread(int thid);
|
||||
int _iResumeThread(int tid);
|
||||
int _CancelWakeupThread(int tid);
|
||||
int _CreateEventFlag();
|
||||
int _CreateSema(struct SemaParam *sema);
|
||||
int _RFU073(int sid);
|
||||
int _iSignalSema(int sid);
|
||||
int _PollSema(int sid);
|
||||
int _ReferSemaStatus(int sid, struct SemaParam *sema);
|
||||
int _DeleteEventFlag();
|
||||
void*_InitializeMainThread(u32 gp, void *stack, int stack_size,
|
||||
char *args, int root);
|
||||
void *_InitializeHeapArea(void *heap_base, int heap_size);
|
||||
void *_EndOfHeap();
|
||||
int _LoadPS2Exe(char *filename, int argc, char **argv);
|
||||
int _ExecOSD(int argc, char **argv);
|
||||
void _SifSetDChain();
|
||||
void _SifStopDma();
|
||||
u32 _SifSetDma(SifDmaTransfer_t *sdd, int len);
|
||||
void _SetGsCrt(short arg0, short arg1, short arg2); // 2
|
||||
void _GetGsHParam(int *p0, int *p1, int *p2, int *p3);
|
||||
int _GetGsVParam();
|
||||
void _SetGsVParam(int VParam);
|
||||
void _GetOsdConfigParam(int *result);
|
||||
void _SetOsdConfigParam(int *param);
|
||||
int _ResetEE(int init); // 1
|
||||
int _TlbWriteRandom(u32 PageMask, u32 EntryHi, u32 EntryLo0, u32 EntryLo1);
|
||||
int _SetAlarm(short a0, int a1, int a2);
|
||||
void _ReleaseAlarm();
|
||||
int _TerminateThread(int tid);
|
||||
void _RotateThreadReadyQueue(int prio);
|
||||
int _iTerminateThread(int tid);
|
||||
int _DisableDispatchThread();
|
||||
int _EnableDispatchThread();
|
||||
int _iRotateThreadReadyQueue(int prio);
|
||||
void _ReleaseWaitThread(int tid);
|
||||
int _iReleaseWaitThread(int tid);
|
||||
int _ResumeThread(int tid);
|
||||
int _iResumeThread(int tid);
|
||||
void _JoinThread();
|
||||
int _DeleteSema(int sid);
|
||||
int _iDeleteSema(int sid);
|
||||
void _SignalSema(int sid);
|
||||
void _SetGsHParam(int a0, int a1, int a2, int a3);
|
||||
int _SetEventFlag(int ef, u32 bits); // bits is EF_X
|
||||
int _iSetEventFlag(int ef, u32 bits);
|
||||
void _EnableIntcHandler(u32 id);
|
||||
void _DisableIntcHandler(u32 id);
|
||||
void _EnableDmacHandler(u32 id);
|
||||
void _DisableDmacHandler(u32 id);
|
||||
void _KSeg0(u32 arg);
|
||||
int _EnableCache(int cache);
|
||||
int _DisableCache(int cache);
|
||||
void _FlushCache(int op);
|
||||
void _105(int op1, int op2);
|
||||
u32 _CpuConfig(u32 op);
|
||||
void _SetCPUTimerHandler(void (*handler)());
|
||||
void _SetCPUTimer(int compval);
|
||||
void _SetPgifHandler(void (*handler)(int));
|
||||
void _print();
|
||||
int _SifDmaStat(int id);
|
||||
|
||||
int _SifGetReg(int reg);
|
||||
int _SifSetReg(int reg, u32 val);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// KERNEL BSS //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __EEKERNEL_H__
|
||||
#define __EEKERNEL_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include <kernel.h>
|
||||
|
||||
|
||||
#define RCNT0_COUNT *(volatile int*)0xB0000000
|
||||
#define RCNT0_MODE *(volatile int*)0xB0000010
|
||||
#define RCNT0_TARGET *(volatile int*)0xB0000020
|
||||
#define RCNT0_HOLD *(volatile int*)0xB0000030
|
||||
|
||||
#define RCNT1_COUNT *(volatile int*)0xB0000800
|
||||
#define RCNT1_MODE *(volatile int*)0xB0000810
|
||||
#define RCNT1_TARGET *(volatile int*)0xB0000820
|
||||
#define RCNT1_HOLD *(volatile int*)0xB0000830
|
||||
|
||||
#define RCNT2_COUNT *(volatile int*)0xB0001000
|
||||
#define RCNT2_MODE *(volatile int*)0xB0001010
|
||||
#define RCNT2_TARGET *(volatile int*)0xB0001020
|
||||
|
||||
#define RCNT3_COUNT *(volatile int*)0xB0001800
|
||||
#define RCNT3_MODE *(volatile int*)0xB0001810
|
||||
#define RCNT3_TARGET *(volatile int*)0xB0001820
|
||||
|
||||
#define GIF_CTRL *(volatile int*)0xB0003000
|
||||
|
||||
#define GIF_FIFO *(volatile u128*)0xB0006000
|
||||
|
||||
//SIF0
|
||||
#define D5_CHCR *(volatile int*)0xB000C000
|
||||
#define D5_MADR *(volatile int*)0xB000C010
|
||||
#define D5_QWC *(volatile int*)0xB000C020
|
||||
|
||||
//SIF1
|
||||
#define D6_CHCR *(volatile int*)0xB000C400
|
||||
#define D6_MADR *(volatile int*)0xB000C410
|
||||
#define D6_QWC *(volatile int*)0xB000C420
|
||||
#define D6_TAG *(volatile int*)0xB000C430
|
||||
|
||||
#define DMAC_CTRL *(volatile int*)0xB000E000
|
||||
#define DMAC_STAT *(volatile int*)0xB000E010
|
||||
#define DMAC_PCR *(volatile int*)0xB000E020
|
||||
#define DMAC_SQWC *(volatile int*)0xB000E030
|
||||
#define DMAC_RBSR *(volatile int*)0xB000E040
|
||||
#define DMAC_RBOR *(volatile int*)0xB000E050
|
||||
#define DMAC_STADR *(volatile int*)0xB000E060
|
||||
|
||||
#define INTC_STAT *(volatile int*)0xB000F000
|
||||
#define INTC_MASK *(volatile int*)0xB000F010
|
||||
|
||||
#define SBUS_MSFLG *(volatile int*)0xB000F220
|
||||
#define SBUS_SMFLG *(volatile int*)0xB000F230
|
||||
#define SBUS_F240 *(volatile int*)0xB000F240
|
||||
|
||||
#define DMAC_ENABLER *(volatile int*)0xB000F520
|
||||
#define DMAC_ENABLEW *(volatile int*)0xB000F590
|
||||
|
||||
#define SBFLG_IOPALIVE 0x10000
|
||||
#define SBFLG_IOPSYNC 0x40000
|
||||
|
||||
#define GS_PMODE *(volatile u64*)0xB2000000
|
||||
#define GS_SMODE1 *(volatile u64*)0xB2000010
|
||||
#define GS_SMODE2 *(volatile u64*)0xB2000020
|
||||
#define GS_SRFSH *(volatile u64*)0xB2000030
|
||||
#define GS_SYNCH1 *(volatile u64*)0xB2000040
|
||||
#define GS_SYNCH2 *(volatile u64*)0xB2000050
|
||||
#define GS_SYNCV *(volatile u64*)0xB2000060
|
||||
#define GS_DISPFB1 *(volatile u64*)0xB2000070
|
||||
#define GS_DISPLAY1 *(volatile u64*)0xB2000080
|
||||
#define GS_DISPFB2 *(volatile u64*)0xB2000090
|
||||
#define GS_DISPLAY2 *(volatile u64*)0xB20000A0
|
||||
#define GS_EXTBUF *(volatile u64*)0xB20000B0
|
||||
#define GS_EXTDATA *(volatile u64*)0xB20000C0
|
||||
#define GS_EXTWRITE *(volatile u64*)0xB20000D0
|
||||
#define GS_BGCOLOR *(volatile u64*)0xB20000E0
|
||||
#define GS_CSR *(volatile u64*)0xB2001000
|
||||
#define GS_IMR *(volatile u64*)0xB2001010
|
||||
#define GS_BUSDIR *(volatile u64*)0xB2001040
|
||||
#define GS_SIGLBLID *(volatile u64*)0xB2001080
|
||||
|
||||
#define INTC_GS 0
|
||||
#define INTC_SBUS 1
|
||||
#define INTC_VBLANK_S 2
|
||||
#define INTC_VBLANK_E 3
|
||||
#define INTC_VIF0 4
|
||||
#define INTC_VIF1 5
|
||||
#define INTC_VU0 6
|
||||
#define INTC_VU1 7
|
||||
#define INTC_IPU 8
|
||||
#define INTC_TIM0 9
|
||||
#define INTC_TIM1 10
|
||||
#define INTC_TIM2 11
|
||||
#define INTC_TIM3 12 //threads
|
||||
//#define INTC_13 13 //not used
|
||||
//#define INTC_14 14 //not used
|
||||
|
||||
#define DMAC_VIF0 0
|
||||
#define DMAC_VIF1 1
|
||||
#define DMAC_GIF 2
|
||||
#define DMAC_FROM_IPU 3
|
||||
#define DMAC_TO_IPU 4
|
||||
#define DMAC_SIF0 5
|
||||
#define DMAC_SIF1 6
|
||||
#define DMAC_SIF2 7
|
||||
#define DMAC_FROM_SPR 8
|
||||
#define DMAC_TO_SPR 9
|
||||
//#define DMAC_10 10 //not used
|
||||
//#define DMAC_11 11 //not used
|
||||
//#define DMAC_12 12 //not used
|
||||
//#define DMAC_13 13 //not used
|
||||
//#define DMAC_14 14 //not used
|
||||
#define DMAC_ERROR 15
|
||||
|
||||
///////////////////////
|
||||
// DMA TAG REGISTERS //
|
||||
///////////////////////
|
||||
#define DMA_TAG_REFE 0x00
|
||||
#define DMA_TAG_CNT 0x01
|
||||
#define DMA_TAG_NEXT 0x02
|
||||
#define DMA_TAG_REF 0x03
|
||||
#define DMA_TAG_REFS 0x04
|
||||
#define DMA_TAG_CALL 0x05
|
||||
#define DMA_TAG_RET 0x06
|
||||
#define DMA_TAG_END 0x07
|
||||
|
||||
// Modes for DMA transfers
|
||||
#define SIF_DMA_FROM_IOP 0x0
|
||||
#define SIF_DMA_TO_IOP 0x1
|
||||
#define SIF_DMA_FROM_EE 0x0
|
||||
#define SIF_DMA_TO_EE 0x1
|
||||
|
||||
#define SIF_DMA_INT_I 0x2
|
||||
#define SIF_DMA_INT_O 0x4
|
||||
#define SIF_DMA_SPR 0x8
|
||||
#define SIF_DMA_BSN 0x10 /* ? what is this? */
|
||||
#define SIF_DMA_TAG 0x20
|
||||
#define SIF_DMA_ERT 0x40
|
||||
#define DMA_TAG_IRQ 0x80000000
|
||||
#define DMA_TAG_PCE 0x0C000000
|
||||
|
||||
#define KSEG1_ADDR(x) (((u32)(x))|0xA0000000)
|
||||
#define KUSEG_ADDR(x) (((u32)(x))&0x1FFFFFFF)
|
||||
|
||||
#define MAX_SEMAS 256
|
||||
#define STACK_RES 0x2A0
|
||||
|
||||
//?
|
||||
#define SRInitVal 0x70030C13
|
||||
#define ConfigInitVal 0x73003
|
||||
|
||||
enum {
|
||||
THS_RUN = 0x01,
|
||||
THS_READY = 0x02,
|
||||
THS_WAIT = 0x04,
|
||||
THS_SUSPEND = 0x08,
|
||||
THS_DORMANT = 0x10,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
u128 gpr[24]; // v0-t9 (skip r0,at,k0-ra)
|
||||
u128 gp;
|
||||
u128 fp;
|
||||
u128 hi;
|
||||
u128 lo;
|
||||
u32 sa;
|
||||
} eeRegs;
|
||||
|
||||
struct ThreadParam {
|
||||
int status;
|
||||
void (*entry)(void*);
|
||||
void *stack;
|
||||
int stackSize;
|
||||
void *gpReg;
|
||||
int initPriority;
|
||||
int currentPriority;
|
||||
u32 attr;
|
||||
u32 option;
|
||||
int waitSema; // waitType?
|
||||
int waitId;
|
||||
int wakeupCount;
|
||||
};
|
||||
|
||||
struct TCB { //internal struct
|
||||
struct TCB *next; //+00
|
||||
struct TCB *prev; //+04
|
||||
int status;//+08
|
||||
void (*entry)(void*); //+0C
|
||||
void *stack_res; //+10 initial $sp
|
||||
void *gpReg; //+14
|
||||
short currentPriority; //+18
|
||||
short initPriority; //+1A
|
||||
int waitSema, //+1C waitType?
|
||||
semaId, //+20
|
||||
wakeupCount, //+24
|
||||
attr, //+28
|
||||
option; //+2C
|
||||
void (*entry_)(void*); //+30
|
||||
int argc; //+34
|
||||
char *argstring;//+38
|
||||
void *stack;//+3C
|
||||
int stackSize; //+40
|
||||
int (*root)(); //+44
|
||||
void* heap_base; //+48
|
||||
};
|
||||
|
||||
struct threadCtx {
|
||||
u128 gpr[25]; // at-t9, (skip r0,k0-ra)
|
||||
u128 gp; //+190
|
||||
u128 sp; //+1A0
|
||||
u128 fp; //+1B0
|
||||
u128 ra; //+1C0
|
||||
u128 hi; //+1D0
|
||||
u128 lo; //+1E0
|
||||
u32 sa; //+1F0
|
||||
u32 cf31;//+1F4
|
||||
u32 acc; //+1F8
|
||||
u32 res; //+1FC
|
||||
u32 fpr[32];//+200
|
||||
};
|
||||
|
||||
typedef struct tag_ARGS{
|
||||
int argc;
|
||||
char *argv[16];
|
||||
char args[256];
|
||||
} ARGS;
|
||||
|
||||
struct SemaParam {
|
||||
int count;
|
||||
int max_count;
|
||||
int init_count;
|
||||
int wait_threads;
|
||||
int attr;
|
||||
u32 option;
|
||||
};
|
||||
|
||||
struct kSema { // internal struct
|
||||
struct kSema *free;//+00
|
||||
int count;//+04
|
||||
int max_count;//+08
|
||||
int attr;//+0C
|
||||
int option;//+10
|
||||
int wait_threads;//+14
|
||||
struct TCB *wait_next,//+18
|
||||
*wait_prev;//+1C
|
||||
};
|
||||
|
||||
struct ll { struct ll *next, *prev; }; //linked list
|
||||
|
||||
//internal struct
|
||||
struct IDhandl { //intc dmac handler
|
||||
struct ll *next, //+00
|
||||
*prev; //+04
|
||||
int (*handler)(int); //+08
|
||||
u32 gp; //+0C
|
||||
void *arg; //+10
|
||||
int flag; //+14
|
||||
};
|
||||
|
||||
//internal struct
|
||||
struct HCinfo{ //handler cause info
|
||||
int count;
|
||||
struct ll l;
|
||||
};
|
||||
|
||||
extern u128 SavedSP;
|
||||
extern u128 SavedRA;
|
||||
extern u128 SavedAT;
|
||||
extern u64 SavedT9;
|
||||
|
||||
extern eeRegs SavedRegs;
|
||||
|
||||
extern u32 excepRA;
|
||||
extern u32 excepSP;
|
||||
|
||||
extern u32 (*table_CpuConfig[6])(u32);
|
||||
extern void (*table_SYSCALL[0x80])();
|
||||
|
||||
extern void (*VCRTable[14])();
|
||||
extern void (*VIntTable[8])();
|
||||
extern void (*INTCTable[16])(int);
|
||||
extern void (*DMACTable[16])(int);
|
||||
|
||||
extern int threadId;
|
||||
extern int threadPrio;
|
||||
extern int threadStatus;
|
||||
|
||||
extern u64 hvParam;
|
||||
|
||||
extern u32 machineType;
|
||||
extern u64 gsIMR;
|
||||
extern u32 memorySize;
|
||||
|
||||
extern u32 g_kernelstackend;
|
||||
|
||||
extern u32 dmac_CHCR[10];
|
||||
|
||||
extern int VSyncFlag0;
|
||||
extern int VSyncFlag1;
|
||||
|
||||
extern int _HandlersCount;
|
||||
extern struct ll handler_ll_free, *ihandlers_last, *ihandlers_first;
|
||||
extern struct HCinfo intcs_array[14];
|
||||
extern struct ll *dhandlers_last, *dhandlers_first;
|
||||
extern struct HCinfo dmacs_array[15];
|
||||
extern struct IDhandl pgifhandlers_array[161];
|
||||
extern void (*sbus_handlers[32])(int ca);
|
||||
|
||||
extern int rcnt3Code;
|
||||
extern int rcnt3TargetTable[0x142];
|
||||
extern u8 rcnt3TargetNum[0x40];
|
||||
extern int threads_count;
|
||||
extern struct ll thread_ll_free;
|
||||
extern struct ll thread_ll_priorities[128];
|
||||
extern int semas_count;
|
||||
extern struct kSema* semas_last;
|
||||
|
||||
extern struct TCB threads_array[256];
|
||||
extern struct kSema semas_array[256];
|
||||
|
||||
extern char tagindex;
|
||||
extern short transferscount;
|
||||
extern struct TAG{
|
||||
int id_qwc;
|
||||
int addr;
|
||||
int unk[2];
|
||||
} tadrptr[31];
|
||||
extern int extrastorage[(16/4) * 8][31];
|
||||
|
||||
extern int osdConfigParam;
|
||||
|
||||
// syscalls
|
||||
// Every syscall is officially prefixed with _ (to avoid clashing with ps2sdk)
|
||||
void _SetSYSCALL(int num, int address);
|
||||
int __EnableIntc(int ch);
|
||||
int __DisableIntc(int ch);
|
||||
int __EnableDmac(int ch);
|
||||
int __DisableDmac(int ch);
|
||||
void *_SetVTLBRefillHandler(int cause, void (*handler)());
|
||||
void *_SetVCommonHandler(int cause, void (*handler)());
|
||||
void *_SetVInterruptHandler(int cause, void (*handler)());
|
||||
void _PSMode();
|
||||
u32 _MachineType();
|
||||
u32 _SetMemorySize(u32 size);
|
||||
u32 _GetMemorySize();
|
||||
u64 _GsGetIMR();
|
||||
u64 _GsPutIMR(u64 val);
|
||||
int _Exit(); // 3
|
||||
void _RFU___(); // 0
|
||||
void _SetVSyncFlag(int flag0, int flag1);
|
||||
int _AddIntcHandler(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _AddIntcHandler2(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _RemoveIntcHandler(int cause, int hid);
|
||||
int _AddDmacHandler(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _AddDmacHandler2(int cause, int (*handler)(int), int next, void *arg);
|
||||
int _RemoveDmacHandler(int code, int hid);
|
||||
int _AddSbusIntcHandler(int cause, void (*handler)(int ca));
|
||||
int _RemoveSbusIntcHandler(int cause);
|
||||
int _Interrupt2Iop(int cause);
|
||||
void _RFU005();
|
||||
int _GetCop0(int reg);
|
||||
int _ExecPS2(void *, void *, int, char **);
|
||||
int _DeleteThread(int tid);
|
||||
int _StartThread(int tid, void *arg);
|
||||
int _ExitThread();
|
||||
int _ExitDeleteThread();
|
||||
int _SleepThread();
|
||||
int _WakeupThread(int tid);
|
||||
int _WaitSema(int sid);
|
||||
void _ChangeThreadPriority(int tid, int prio);
|
||||
int _CreateThread(struct ThreadParam *param);
|
||||
int _iChangeThreadPriority(int tid, int prio);
|
||||
int _GetThreadId();
|
||||
int _ReferThreadStatus(int tid, struct ThreadParam *info);
|
||||
int _iWakeupThread(int tid);
|
||||
int _SuspendThread(int thid);
|
||||
int _iResumeThread(int tid);
|
||||
int _CancelWakeupThread(int tid);
|
||||
int _CreateEventFlag();
|
||||
int _CreateSema(struct SemaParam *sema);
|
||||
int _RFU073(int sid);
|
||||
int _iSignalSema(int sid);
|
||||
int _PollSema(int sid);
|
||||
int _ReferSemaStatus(int sid, struct SemaParam *sema);
|
||||
int _DeleteEventFlag();
|
||||
void*_InitializeMainThread(u32 gp, void *stack, int stack_size,
|
||||
char *args, int root);
|
||||
void *_InitializeHeapArea(void *heap_base, int heap_size);
|
||||
void *_EndOfHeap();
|
||||
int _LoadPS2Exe(char *filename, int argc, char **argv);
|
||||
int _ExecOSD(int argc, char **argv);
|
||||
void _SifSetDChain();
|
||||
void _SifStopDma();
|
||||
u32 _SifSetDma(SifDmaTransfer_t *sdd, int len);
|
||||
void _SetGsCrt(short arg0, short arg1, short arg2); // 2
|
||||
void _GetGsHParam(int *p0, int *p1, int *p2, int *p3);
|
||||
int _GetGsVParam();
|
||||
void _SetGsVParam(int VParam);
|
||||
void _GetOsdConfigParam(int *result);
|
||||
void _SetOsdConfigParam(int *param);
|
||||
int _ResetEE(int init); // 1
|
||||
int _TlbWriteRandom(u32 PageMask, u32 EntryHi, u32 EntryLo0, u32 EntryLo1);
|
||||
int _SetAlarm(short a0, int a1, int a2);
|
||||
void _ReleaseAlarm();
|
||||
int _TerminateThread(int tid);
|
||||
void _RotateThreadReadyQueue(int prio);
|
||||
int _iTerminateThread(int tid);
|
||||
int _DisableDispatchThread();
|
||||
int _EnableDispatchThread();
|
||||
int _iRotateThreadReadyQueue(int prio);
|
||||
void _ReleaseWaitThread(int tid);
|
||||
int _iReleaseWaitThread(int tid);
|
||||
int _ResumeThread(int tid);
|
||||
int _iResumeThread(int tid);
|
||||
void _JoinThread();
|
||||
int _DeleteSema(int sid);
|
||||
int _iDeleteSema(int sid);
|
||||
void _SignalSema(int sid);
|
||||
void _SetGsHParam(int a0, int a1, int a2, int a3);
|
||||
int _SetEventFlag(int ef, u32 bits); // bits is EF_X
|
||||
int _iSetEventFlag(int ef, u32 bits);
|
||||
void _EnableIntcHandler(u32 id);
|
||||
void _DisableIntcHandler(u32 id);
|
||||
void _EnableDmacHandler(u32 id);
|
||||
void _DisableDmacHandler(u32 id);
|
||||
void _KSeg0(u32 arg);
|
||||
int _EnableCache(int cache);
|
||||
int _DisableCache(int cache);
|
||||
void _FlushCache(int op);
|
||||
void _105(int op1, int op2);
|
||||
u32 _CpuConfig(u32 op);
|
||||
void _SetCPUTimerHandler(void (*handler)());
|
||||
void _SetCPUTimer(int compval);
|
||||
void _SetPgifHandler(void (*handler)(int));
|
||||
void _print();
|
||||
int _SifDmaStat(int id);
|
||||
|
||||
int _SifGetReg(int reg);
|
||||
int _SifSetReg(int reg, u32 val);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// KERNEL BSS //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __EELOAD_H__
|
||||
#define __EELOAD_H__
|
||||
|
||||
#endif /* __EELOAD_H__ */
|
||||
#ifndef __EELOAD_H__
|
||||
#define __EELOAD_H__
|
||||
|
||||
#endif /* __EELOAD_H__ */
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#ifndef __ROMDIR_H__
|
||||
#define __ROMDIR_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
struct romdir {
|
||||
/*following variable must place in designed order*/
|
||||
u8 fileName[10];
|
||||
u16 extInfoSize;
|
||||
u32 fileSize;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rominfo {
|
||||
u32 fileOffset;
|
||||
u32 fileSize;
|
||||
};
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri);
|
||||
|
||||
#endif /* __ROMDIR_H__ */
|
||||
#ifndef __ROMDIR_H__
|
||||
#define __ROMDIR_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
struct romdir {
|
||||
/*following variable must place in designed order*/
|
||||
u8 fileName[10];
|
||||
u16 extInfoSize;
|
||||
u32 fileSize;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct rominfo {
|
||||
u32 fileOffset;
|
||||
u32 fileSize;
|
||||
};
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri);
|
||||
|
||||
#endif /* __ROMDIR_H__ */
|
||||
|
|
|
@ -1,47 +1,47 @@
|
|||
/***************************************************************
|
||||
* romdir.c, based over Alex Lau (http://alexlau.8k.com) RomDir *
|
||||
****************************************************************/
|
||||
#include "romdir.h"
|
||||
|
||||
struct romdir *base = NULL;
|
||||
|
||||
struct romdir *romdirInit() {
|
||||
u8 *mem;
|
||||
|
||||
for (mem=(u8*)0xbfc00000; (u32)mem<0xbfc01000; mem++) {
|
||||
if (mem[0] == 'R' && mem[1] == 'E' &&
|
||||
mem[2] == 'S' && mem[3] == 'E' &&
|
||||
mem[4] == 'T')
|
||||
break;
|
||||
}
|
||||
if ((u32)mem == 0xbfc01000) return NULL;
|
||||
|
||||
return (struct romdir*)mem;
|
||||
}
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri) {
|
||||
struct romdir *rd;
|
||||
// struct romdir *base;
|
||||
int i;
|
||||
|
||||
if (base == NULL) {
|
||||
base = romdirInit();
|
||||
if (base == NULL) return NULL;
|
||||
}
|
||||
|
||||
ri->fileOffset = 0;
|
||||
for (rd = base; rd->fileName[0] != 0; rd++) {
|
||||
for (i=0; i<10 && name[i] != 0; i++) {
|
||||
if (rd->fileName[i] != name[i]) break;
|
||||
}
|
||||
if (rd->fileName[i] != name[i]) {
|
||||
ri->fileOffset+= (rd->fileSize + 15) & ~0xF;
|
||||
continue;
|
||||
}
|
||||
|
||||
ri->fileSize = rd->fileSize;
|
||||
return ri;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
/***************************************************************
|
||||
* romdir.c, based over Alex Lau (http://alexlau.8k.com) RomDir *
|
||||
****************************************************************/
|
||||
#include "romdir.h"
|
||||
|
||||
struct romdir *base = NULL;
|
||||
|
||||
struct romdir *romdirInit() {
|
||||
u8 *mem;
|
||||
|
||||
for (mem=(u8*)0xbfc00000; (u32)mem<0xbfc01000; mem++) {
|
||||
if (mem[0] == 'R' && mem[1] == 'E' &&
|
||||
mem[2] == 'S' && mem[3] == 'E' &&
|
||||
mem[4] == 'T')
|
||||
break;
|
||||
}
|
||||
if ((u32)mem == 0xbfc01000) return NULL;
|
||||
|
||||
return (struct romdir*)mem;
|
||||
}
|
||||
|
||||
struct rominfo *romdirGetFile(char *name, struct rominfo *ri) {
|
||||
struct romdir *rd;
|
||||
// struct romdir *base;
|
||||
int i;
|
||||
|
||||
if (base == NULL) {
|
||||
base = romdirInit();
|
||||
if (base == NULL) return NULL;
|
||||
}
|
||||
|
||||
ri->fileOffset = 0;
|
||||
for (rd = base; rd->fileName[0] != 0; rd++) {
|
||||
for (i=0; i<10 && name[i] != 0; i++) {
|
||||
if (rd->fileName[i] != name[i]) break;
|
||||
}
|
||||
if (rd->fileName[i] != name[i]) {
|
||||
ri->fileOffset+= (rd->fileSize + 15) & ~0xF;
|
||||
continue;
|
||||
}
|
||||
|
||||
ri->fileSize = rd->fileSize;
|
||||
return ri;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
#include <tamtypes.h>
|
||||
#include "romdir.h"
|
||||
|
||||
static void Kputc(u8 c) {
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
static void Kputs(u8 *s) {
|
||||
while (*s != 0) {
|
||||
Kputc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
static void Kmemcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n > 0) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
void _eestart() {
|
||||
struct rominfo ri;
|
||||
u8 *str;
|
||||
|
||||
romdirGetFile("ROMVER", &ri);
|
||||
str = (u8*)(0xbfc00000 + ri.fileOffset);
|
||||
Kputs("fps2bios v");
|
||||
Kputc(str[1]); Kputc('.'); Kputc(str[3]); Kputc('\n');
|
||||
|
||||
romdirGetFile("EELOAD", &ri);
|
||||
|
||||
Kputs("loading EELOAD to 0x80000000\n");
|
||||
|
||||
Kmemcpy((void*)0x80000000, (void*)(0xbfc00000 + ri.fileOffset), ri.fileSize);
|
||||
|
||||
__asm__ (
|
||||
"li $26, 0x80001000\n"
|
||||
"jr $26\n");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
__asm__ (
|
||||
".global eestart\n"
|
||||
"eestart:\n"
|
||||
"li $sp, 0x80010000\n"
|
||||
"j _eestart\n");
|
||||
|
||||
|
||||
#include <tamtypes.h>
|
||||
#include "romdir.h"
|
||||
|
||||
static void Kputc(u8 c) {
|
||||
*((u8*)0x1000f180) = c;
|
||||
}
|
||||
|
||||
static void Kputs(u8 *s) {
|
||||
while (*s != 0) {
|
||||
Kputc(*s++);
|
||||
}
|
||||
}
|
||||
|
||||
static void Kmemcpy(void *dest, const void *src, int n) {
|
||||
const u8 *s = (u8*)src;
|
||||
u8 *d = (u8*)dest;
|
||||
|
||||
while (n > 0) {
|
||||
*d++ = *s++; n--;
|
||||
}
|
||||
}
|
||||
|
||||
void _eestart() {
|
||||
struct rominfo ri;
|
||||
u8 *str;
|
||||
|
||||
romdirGetFile("ROMVER", &ri);
|
||||
str = (u8*)(0xbfc00000 + ri.fileOffset);
|
||||
Kputs("fps2bios v");
|
||||
Kputc(str[1]); Kputc('.'); Kputc(str[3]); Kputc('\n');
|
||||
|
||||
romdirGetFile("EELOAD", &ri);
|
||||
|
||||
Kputs("loading EELOAD to 0x80000000\n");
|
||||
|
||||
Kmemcpy((void*)0x80000000, (void*)(0xbfc00000 + ri.fileOffset), ri.fileSize);
|
||||
|
||||
__asm__ (
|
||||
"li $26, 0x80001000\n"
|
||||
"jr $26\n");
|
||||
for (;;);
|
||||
}
|
||||
|
||||
__asm__ (
|
||||
".global eestart\n"
|
||||
"eestart:\n"
|
||||
"li $sp, 0x80010000\n"
|
||||
"j _eestart\n");
|
||||
|
||||
|
||||
|
|
|
@ -1,67 +1,67 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: iopload
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -nostartfiles -L$(PS2LIB)/iop/lib
|
||||
LDADD =
|
||||
OBJECTS = romdir.o iopelf.o iopdebug.o
|
||||
DIRS = iopboot sysmem loadcore excepman intrman stdio timrman \
|
||||
dmacman sifman sifcmd ssbusc sysclib heaplib \
|
||||
vblank threadman sio2man
|
||||
|
||||
iopload: $(OBJECTS)
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: iopload
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -nostartfiles -L$(PS2LIB)/iop/lib
|
||||
LDADD =
|
||||
OBJECTS = romdir.o iopelf.o iopdebug.o
|
||||
DIRS = iopboot sysmem loadcore excepman intrman stdio timrman \
|
||||
dmacman sifman sifcmd ssbusc sysclib heaplib \
|
||||
vblank threadman sio2man
|
||||
|
||||
iopload: $(OBJECTS)
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make; cd ..) \
|
||||
done;
|
||||
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
|
||||
clean:
|
||||
for i in $(DIRS); do \
|
||||
(cd $$i; make clean; cd ..) \
|
||||
done;
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
IOPASFLAGS := -EL -G0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: dmacman
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/iop/lib -L$(NEWLIB)/lib
|
||||
LDADD =
|
||||
OBJECTS = dmacman.o ../iopdebug.o ../libkernel/iop_loadcore.o \
|
||||
../libkernel/iop_intrman.o ../libkernel/iop_sysmem.o
|
||||
|
||||
dmacman: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/DMACMAN
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
IOPASFLAGS := -EL -G0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: dmacman
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/iop/lib -L$(NEWLIB)/lib
|
||||
LDADD =
|
||||
OBJECTS = dmacman.o ../iopdebug.o ../libkernel/iop_loadcore.o \
|
||||
../libkernel/iop_intrman.o ../libkernel/iop_sysmem.o
|
||||
|
||||
dmacman: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/DMACMAN
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,60 +1,60 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc -nostartfiles
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: excepman
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS =
|
||||
LDADD =
|
||||
OBJECTS = excepman.o ../libkernel/iop_loadcore.o ex_handler.o ../iopdebug.o
|
||||
|
||||
excepman: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/EXCEPMAN
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc -nostartfiles
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: excepman
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS =
|
||||
LDADD =
|
||||
OBJECTS = excepman.o ../libkernel/iop_loadcore.o ex_handler.o ../iopdebug.o
|
||||
|
||||
excepman: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/EXCEPMAN
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include -I$(NEWLIB)/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
IOPASFLAGS := -EL -G0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: heaplib
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/iop/lib -L$(NEWLIB)/lib
|
||||
LDADD =
|
||||
OBJECTS = heaplib.o ../iopdebug.o ../libkernel/iop_loadcore.o ../libkernel/iop_sysmem.o
|
||||
|
||||
heaplib: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/HEAPLIB
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
# _____ ___ ____
|
||||
# ____| | ____| PSX2 OpenSource Project
|
||||
# | ___| |____ (C)2002, David Ryan ( Oobles@hotmail.com )
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# Generated automatically from Makefile.in by configure.
|
||||
#.SUFFIXES: .S .c .o .s .elf .irx
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# COMPILERS
|
||||
|
||||
IOPCC = iop-gcc
|
||||
IOPAR = iop-ar
|
||||
IOPLD = iop-ld
|
||||
IOPAS = iop-as
|
||||
EECC = ee-gcc
|
||||
EEAR = ee-ar
|
||||
EELD = ee-gcc
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# DIRECTORY PATHS & FLAGS
|
||||
|
||||
|
||||
EECFLAGS = -O2 -fomit-frame-pointer -mips3 -EL -nostartfiles
|
||||
EEINCLUDES = -I. -Iinclude -I$(PS2LIB)/common/include -I$(PS2LIB)/ee/include -I$(NEWLIB)/include
|
||||
|
||||
IOPCFLAGS = -O2 -fomit-frame-pointer -nostartfiles -G0
|
||||
IOPINCLUDES = -I. -I../include -I$(PS2LIB)/common/include -I$(PS2LIB)/iop/include
|
||||
IOPCOMPILE = $(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS)
|
||||
IOPLINK = $(IOPLD) -dc
|
||||
IOPASFLAGS := -EL -G0
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# PROJECTS TO BUILD
|
||||
|
||||
all: heaplib
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# KERNEL BUILD INSTRUCTIONS
|
||||
|
||||
LDFLAGS = -L$(PS2LIB)/iop/lib -L$(NEWLIB)/lib
|
||||
LDADD =
|
||||
OBJECTS = heaplib.o ../iopdebug.o ../libkernel/iop_loadcore.o ../libkernel/iop_sysmem.o
|
||||
|
||||
heaplib: $(OBJECTS)
|
||||
$(IOPLINK) $(OBJECTS) $(LDFLAGS) $(LDADD) -o ../../../build/HEAPLIB
|
||||
|
||||
%.o: %.c
|
||||
$(IOPCC) $(IOPINCLUDES) $(IOPCFLAGS) -o $@ -c $<
|
||||
|
||||
%.o : %.s
|
||||
$(IOPAS) $(IOPASFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS)
|
||||
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
//[module] HEAPLIB
|
||||
//[processor] IOP
|
||||
//[type] ELF-IRX
|
||||
//[name] Heap_lib
|
||||
//[version] 0x101
|
||||
//[memory map] -
|
||||
//[handlers] -
|
||||
//[entry point] heaplib_start, heaplib_stub
|
||||
//[made by] [RO]man (roman_ps2dev@hotmail.com) 26 January 2003
|
||||
|
||||
#include "sysmem.h"
|
||||
#include "kloadcore.h"
|
||||
#include "kheaplib.h"
|
||||
#include "iopdebug.h"
|
||||
|
||||
static int debug=1;
|
||||
|
||||
#define _dprintf(fmt, args...) \
|
||||
if (debug > 0) __printf("\033[0;32m" "heaplib: " "\033[0m" fmt, ## args)
|
||||
|
||||
int _start(int argc, char* argv[]);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_reset(struct ll *l){
|
||||
l->prev=l->next=l;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
int ll_one(struct ll *l){
|
||||
return (l == l->next);
|
||||
// return (l ^ l->next) < 1; //l==l->next
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_remove(struct ll *l){
|
||||
l->next->prev=l->prev;
|
||||
l->prev->next=l->next;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/*int ll_one_two(struct ll *l){
|
||||
return (l->prev ^ l->next) < 1; //l->prev==l->next
|
||||
}*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_add(struct ll *l, struct ll *n){
|
||||
n->next=l;
|
||||
n->prev=l->prev;
|
||||
l->prev=n;
|
||||
n->prev->next=n;
|
||||
}
|
||||
|
||||
void HeapPrepare(void *mem, int size) {
|
||||
struct Chunk *_chunk = (struct Chunk*)mem;
|
||||
|
||||
if (mem == NULL || size < 41) return;
|
||||
|
||||
_chunk->_mem=(long)mem-1;
|
||||
_chunk->freesize=size;
|
||||
_chunk->usedsize=0;
|
||||
_chunk->mem_16 = (u32)mem+16;
|
||||
_chunk->unk5=((size-16)>>3)-1;
|
||||
_chunk->unk4=(long)_chunk+8+((size-16)&~7);
|
||||
((struct ll*)_chunk->unk4)->next=(void*)_chunk->mem_16;
|
||||
((struct ll*)_chunk->unk4)->prev=0;
|
||||
}
|
||||
|
||||
int HeapChunkSize(void *chunk) {
|
||||
// int size = (chunk[1] - 16) >> 3;
|
||||
// return ((size - chunk[2]) - 1) << 3;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void* CreateHeap(int chunkSize, int memoryType){
|
||||
struct Heap *_heap;
|
||||
|
||||
_dprintf("%s\n", __FUNCTION__);
|
||||
chunkSize = (chunkSize+3) & ~3;
|
||||
_heap = AllocSysMemory(memoryType & 2 ? ALLOC_LAST : ALLOC_FIRST, chunkSize, NULL);
|
||||
if (_heap == NULL) return NULL;
|
||||
|
||||
_heap->plus_one=(long)_heap + 1;
|
||||
if (memoryType & 1) _heap->size2free=chunkSize;
|
||||
else _heap->size2free=0;
|
||||
_heap->size2free |= ((memoryType>>1) & 1);
|
||||
ll_reset(&_heap->l);
|
||||
|
||||
HeapPrepare(&_heap->mem, chunkSize-4*sizeof(int));
|
||||
return (void*)_heap;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
int DestroyHeap(void *heap){
|
||||
register struct ll *tmp, *p;
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
|
||||
if (_heap->plus_one != (long)_heap+1) return (long)_heap+1;
|
||||
_heap->plus_one=0;
|
||||
|
||||
for (p=&_heap->l; p != &_heap->l; p=tmp){
|
||||
tmp=p->next;
|
||||
((int*)p)[2]=0; //p->mem
|
||||
FreeSysMemory(p);
|
||||
}
|
||||
_heap->mem=0;
|
||||
return FreeSysMemory(_heap);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void* HeapMalloc(void *heap, int size) {
|
||||
#if 0
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
void *p;
|
||||
|
||||
if (_heap->plus_one != (long)_heap+1) return NULL;
|
||||
|
||||
for (;;) {
|
||||
p = HeapChunk13((u32)_heap->l.next+8, size);
|
||||
if (p != NULL) return p;
|
||||
|
||||
if (_heap->l.next->next == _heap->l.next) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int HeapFree(void *heap, void *mem) {
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
struct Heap *h;
|
||||
|
||||
if (heap == NULL ||
|
||||
_heap->plus_one != (long)_heap+1) return -4;
|
||||
|
||||
for (h = (struct Heap*)_heap->l.next; h != &_heap->l; h = (struct Heap*)h->l.next) {
|
||||
if (HeapChunk14(h->l, mem) != NULL) continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((struct ll*)h == &_heap->l) return 0;
|
||||
if (HeapChunk12() == 0) return 0;
|
||||
ll_one(h);
|
||||
h->l.next = 0;
|
||||
FreeSysMemory(h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HeapSize(void *heap) {
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
|
||||
if (heap == NULL ||
|
||||
_heap->plus_one != (long)_heap+1) return -4;
|
||||
|
||||
for (;; _heap = _heap->plus_one) {
|
||||
if (_heap->l.next == &_heap->l)
|
||||
break;
|
||||
}
|
||||
|
||||
return HeapChunkSize(_heap->l.next+8);
|
||||
}
|
||||
|
||||
void HeapChunk12() {
|
||||
}
|
||||
|
||||
void HeapChunk13() {
|
||||
}
|
||||
|
||||
void HeapChunk14() {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void _retonly(){}
|
||||
|
||||
struct export heaplib_stub={
|
||||
0x41C00000,
|
||||
0,
|
||||
VER(1, 1), // 1.1 => 0x101
|
||||
0,
|
||||
"heaplib",
|
||||
(func)_start, // entrypoint
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)CreateHeap,
|
||||
(func)DestroyHeap,
|
||||
(func)HeapMalloc,
|
||||
(func)HeapFree,
|
||||
(func)HeapSize,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)HeapPrepare,
|
||||
(func)HeapChunk12,
|
||||
(func)HeapChunk13,
|
||||
(func)HeapChunk14,
|
||||
(func)HeapChunkSize,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////entrypoint///////////////////////////////
|
||||
int _start(int argc, char* argv[]){
|
||||
return RegisterLibraryEntries(&heaplib_stub);
|
||||
}
|
||||
|
||||
//[module] HEAPLIB
|
||||
//[processor] IOP
|
||||
//[type] ELF-IRX
|
||||
//[name] Heap_lib
|
||||
//[version] 0x101
|
||||
//[memory map] -
|
||||
//[handlers] -
|
||||
//[entry point] heaplib_start, heaplib_stub
|
||||
//[made by] [RO]man (roman_ps2dev@hotmail.com) 26 January 2003
|
||||
|
||||
#include "sysmem.h"
|
||||
#include "kloadcore.h"
|
||||
#include "kheaplib.h"
|
||||
#include "iopdebug.h"
|
||||
|
||||
static int debug=1;
|
||||
|
||||
#define _dprintf(fmt, args...) \
|
||||
if (debug > 0) __printf("\033[0;32m" "heaplib: " "\033[0m" fmt, ## args)
|
||||
|
||||
int _start(int argc, char* argv[]);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_reset(struct ll *l){
|
||||
l->prev=l->next=l;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
int ll_one(struct ll *l){
|
||||
return (l == l->next);
|
||||
// return (l ^ l->next) < 1; //l==l->next
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_remove(struct ll *l){
|
||||
l->next->prev=l->prev;
|
||||
l->prev->next=l->next;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
/*int ll_one_two(struct ll *l){
|
||||
return (l->prev ^ l->next) < 1; //l->prev==l->next
|
||||
}*/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void ll_add(struct ll *l, struct ll *n){
|
||||
n->next=l;
|
||||
n->prev=l->prev;
|
||||
l->prev=n;
|
||||
n->prev->next=n;
|
||||
}
|
||||
|
||||
void HeapPrepare(void *mem, int size) {
|
||||
struct Chunk *_chunk = (struct Chunk*)mem;
|
||||
|
||||
if (mem == NULL || size < 41) return;
|
||||
|
||||
_chunk->_mem=(long)mem-1;
|
||||
_chunk->freesize=size;
|
||||
_chunk->usedsize=0;
|
||||
_chunk->mem_16 = (u32)mem+16;
|
||||
_chunk->unk5=((size-16)>>3)-1;
|
||||
_chunk->unk4=(long)_chunk+8+((size-16)&~7);
|
||||
((struct ll*)_chunk->unk4)->next=(void*)_chunk->mem_16;
|
||||
((struct ll*)_chunk->unk4)->prev=0;
|
||||
}
|
||||
|
||||
int HeapChunkSize(void *chunk) {
|
||||
// int size = (chunk[1] - 16) >> 3;
|
||||
// return ((size - chunk[2]) - 1) << 3;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void* CreateHeap(int chunkSize, int memoryType){
|
||||
struct Heap *_heap;
|
||||
|
||||
_dprintf("%s\n", __FUNCTION__);
|
||||
chunkSize = (chunkSize+3) & ~3;
|
||||
_heap = AllocSysMemory(memoryType & 2 ? ALLOC_LAST : ALLOC_FIRST, chunkSize, NULL);
|
||||
if (_heap == NULL) return NULL;
|
||||
|
||||
_heap->plus_one=(long)_heap + 1;
|
||||
if (memoryType & 1) _heap->size2free=chunkSize;
|
||||
else _heap->size2free=0;
|
||||
_heap->size2free |= ((memoryType>>1) & 1);
|
||||
ll_reset(&_heap->l);
|
||||
|
||||
HeapPrepare(&_heap->mem, chunkSize-4*sizeof(int));
|
||||
return (void*)_heap;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
int DestroyHeap(void *heap){
|
||||
register struct ll *tmp, *p;
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
|
||||
if (_heap->plus_one != (long)_heap+1) return (long)_heap+1;
|
||||
_heap->plus_one=0;
|
||||
|
||||
for (p=&_heap->l; p != &_heap->l; p=tmp){
|
||||
tmp=p->next;
|
||||
((int*)p)[2]=0; //p->mem
|
||||
FreeSysMemory(p);
|
||||
}
|
||||
_heap->mem=0;
|
||||
return FreeSysMemory(_heap);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void* HeapMalloc(void *heap, int size) {
|
||||
#if 0
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
void *p;
|
||||
|
||||
if (_heap->plus_one != (long)_heap+1) return NULL;
|
||||
|
||||
for (;;) {
|
||||
p = HeapChunk13((u32)_heap->l.next+8, size);
|
||||
if (p != NULL) return p;
|
||||
|
||||
if (_heap->l.next->next == _heap->l.next) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int HeapFree(void *heap, void *mem) {
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
struct Heap *h;
|
||||
|
||||
if (heap == NULL ||
|
||||
_heap->plus_one != (long)_heap+1) return -4;
|
||||
|
||||
for (h = (struct Heap*)_heap->l.next; h != &_heap->l; h = (struct Heap*)h->l.next) {
|
||||
if (HeapChunk14(h->l, mem) != NULL) continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if ((struct ll*)h == &_heap->l) return 0;
|
||||
if (HeapChunk12() == 0) return 0;
|
||||
ll_one(h);
|
||||
h->l.next = 0;
|
||||
FreeSysMemory(h);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HeapSize(void *heap) {
|
||||
struct Heap *_heap = (struct Heap*)heap;
|
||||
|
||||
if (heap == NULL ||
|
||||
_heap->plus_one != (long)_heap+1) return -4;
|
||||
|
||||
for (;; _heap = _heap->plus_one) {
|
||||
if (_heap->l.next == &_heap->l)
|
||||
break;
|
||||
}
|
||||
|
||||
return HeapChunkSize(_heap->l.next+8);
|
||||
}
|
||||
|
||||
void HeapChunk12() {
|
||||
}
|
||||
|
||||
void HeapChunk13() {
|
||||
}
|
||||
|
||||
void HeapChunk14() {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
void _retonly(){}
|
||||
|
||||
struct export heaplib_stub={
|
||||
0x41C00000,
|
||||
0,
|
||||
VER(1, 1), // 1.1 => 0x101
|
||||
0,
|
||||
"heaplib",
|
||||
(func)_start, // entrypoint
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)CreateHeap,
|
||||
(func)DestroyHeap,
|
||||
(func)HeapMalloc,
|
||||
(func)HeapFree,
|
||||
(func)HeapSize,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
(func)HeapPrepare,
|
||||
(func)HeapChunk12,
|
||||
(func)HeapChunk13,
|
||||
(func)HeapChunk14,
|
||||
(func)HeapChunkSize,
|
||||
(func)_retonly,
|
||||
(func)_retonly,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////entrypoint///////////////////////////////
|
||||
int _start(int argc, char* argv[]){
|
||||
return RegisterLibraryEntries(&heaplib_stub);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
#ifndef __ERR_H__
|
||||
#define __ERR_H__
|
||||
|
||||
//#define ERR_VER 0x
|
||||
|
||||
#define ERROR_OK 0
|
||||
#define ERROR_UNK -1
|
||||
//bad exception code
|
||||
#define ERROR_BAD_EXCODE -50
|
||||
|
||||
//no exception handler for that code
|
||||
#define ERROR_EXCODE_NOTFOUND -51
|
||||
|
||||
//already used
|
||||
#define ERROR_USED_EXCODE -52
|
||||
#define ERROR_INTR_CONTEXT -100
|
||||
#define ERROR_DOES_EXIST -104
|
||||
#define ERROR_DOESNOT_EXIST -105
|
||||
#define ERROR_NO_TIMER -150
|
||||
#define ERROR_NOT_IRX -201
|
||||
#define ERROR_FILE_NOT_FOUND -203
|
||||
#define ERROR_FILE_ERROR -204
|
||||
#define ERROR_NO_MEM -400
|
||||
#define ERROR_SEMACOUNT_ZERO -400
|
||||
|
||||
// what should these be? Used in intrman.c
|
||||
#define ERROR_ILLEGAL_INTRCODE ERROR_UNK
|
||||
#define ERROR_CPUDI ERROR_UNK
|
||||
|
||||
#endif//__ERR_H__
|
||||
#ifndef __ERR_H__
|
||||
#define __ERR_H__
|
||||
|
||||
//#define ERR_VER 0x
|
||||
|
||||
#define ERROR_OK 0
|
||||
#define ERROR_UNK -1
|
||||
//bad exception code
|
||||
#define ERROR_BAD_EXCODE -50
|
||||
|
||||
//no exception handler for that code
|
||||
#define ERROR_EXCODE_NOTFOUND -51
|
||||
|
||||
//already used
|
||||
#define ERROR_USED_EXCODE -52
|
||||
#define ERROR_INTR_CONTEXT -100
|
||||
#define ERROR_DOES_EXIST -104
|
||||
#define ERROR_DOESNOT_EXIST -105
|
||||
#define ERROR_NO_TIMER -150
|
||||
#define ERROR_NOT_IRX -201
|
||||
#define ERROR_FILE_NOT_FOUND -203
|
||||
#define ERROR_FILE_ERROR -204
|
||||
#define ERROR_NO_MEM -400
|
||||
#define ERROR_SEMACOUNT_ZERO -400
|
||||
|
||||
// what should these be? Used in intrman.c
|
||||
#define ERROR_ILLEGAL_INTRCODE ERROR_UNK
|
||||
#define ERROR_CPUDI ERROR_UNK
|
||||
|
||||
#endif//__ERR_H__
|
||||
|
|
|
@ -1,143 +1,143 @@
|
|||
/* errno is not a global variable, because that would make using it
|
||||
non-reentrant. Instead, its address is returned by the function
|
||||
__errno. */
|
||||
|
||||
#ifndef _SYS_ERRNO_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define _SYS_ERRNO_H_
|
||||
|
||||
|
||||
#define EPERM 1 /* Not super-user */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Arg list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No children */
|
||||
#define EAGAIN 11 /* No more processes */
|
||||
#define ENOMEM 12 /* Not enough core */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Mount device busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* Too many open files in system */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math arg out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
#define ENOMSG 35 /* No message of desired type */
|
||||
#define EIDRM 36 /* Identifier removed */
|
||||
#define ECHRNG 37 /* Channel number out of range */
|
||||
#define EL2NSYNC 38 /* Level 2 not synchronized */
|
||||
#define EL3HLT 39 /* Level 3 halted */
|
||||
#define EL3RST 40 /* Level 3 reset */
|
||||
#define ELNRNG 41 /* Link number out of range */
|
||||
#define EUNATCH 42 /* Protocol driver not attached */
|
||||
#define ENOCSI 43 /* No CSI structure available */
|
||||
#define EL2HLT 44 /* Level 2 halted */
|
||||
#define EDEADLK 45 /* Deadlock condition */
|
||||
#define ENOLCK 46 /* No record locks available */
|
||||
#define EBADE 50 /* Invalid exchange */
|
||||
#define EBADR 51 /* Invalid request descriptor */
|
||||
#define EXFULL 52 /* Exchange full */
|
||||
#define ENOANO 53 /* No anode */
|
||||
#define EBADRQC 54 /* Invalid request code */
|
||||
#define EBADSLT 55 /* Invalid slot */
|
||||
#define EDEADLOCK 56 /* File locking deadlock error */
|
||||
#define EBFONT 57 /* Bad font file fmt */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data (for no delay io) */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* The object is remote */
|
||||
#define ENOLINK 67 /* The link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 74 /* Multihop attempted */
|
||||
#define ELBIN 75 /* Inode is remote (not really error) */
|
||||
#define EDOTDOT 76 /* Cross mount point (not really error) */
|
||||
#define EBADMSG 77 /* Trying to read unreadable message */
|
||||
#define EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define ENOTUNIQ 80 /* Given log. name not unique */
|
||||
#define EBADFD 81 /* f.d. invalid for this operation */
|
||||
#define EREMCHG 82 /* Remote address changed */
|
||||
#define ELIBACC 83 /* Can't access a needed shared lib */
|
||||
#define ELIBBAD 84 /* Accessing a corrupted shared lib */
|
||||
#define ELIBSCN 85 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 86 /* Attempting to link in too many libs */
|
||||
#define ELIBEXEC 87 /* Attempting to exec a shared library */
|
||||
#define ENOSYS 88 /* Function not implemented */
|
||||
#define ENMFILE 89 /* No more files */
|
||||
#define ENOTEMPTY 90 /* Directory not empty */
|
||||
#define ENAMETOOLONG 91 /* File or path name too long */
|
||||
#define ELOOP 92 /* Too many symbolic links */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
|
||||
#define EPROTOTYPE 107 /* Protocol wrong type for socket */
|
||||
#define ENOTSOCK 108 /* Socket operation on non-socket */
|
||||
#define ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define ESHUTDOWN 110 /* Can't send after socket shutdown */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EADDRINUSE 112 /* Address already in use */
|
||||
#define ECONNABORTED 113 /* Connection aborted */
|
||||
#define ENETUNREACH 114 /* Network is unreachable */
|
||||
#define ENETDOWN 115 /* Network interface is not configured */
|
||||
#define ETIMEDOUT 116 /* Connection timed out */
|
||||
#define EHOSTDOWN 117 /* Host is down */
|
||||
#define EHOSTUNREACH 118 /* Host is unreachable */
|
||||
#define EINPROGRESS 119 /* Connection already in progress */
|
||||
#define EALREADY 120 /* Socket already connected */
|
||||
#define EDESTADDRREQ 121 /* Destination address required */
|
||||
#define EMSGSIZE 122 /* Message too long */
|
||||
#define EPROTONOSUPPORT 123 /* Unknown protocol */
|
||||
#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
|
||||
#define EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define ENETRESET 126
|
||||
#define EISCONN 127 /* Socket is already connected */
|
||||
#define ENOTCONN 128 /* Socket is not connected */
|
||||
#define ETOOMANYREFS 129
|
||||
#define EPROCLIM 130
|
||||
#define EUSERS 131
|
||||
#define EDQUOT 132
|
||||
#define ESTALE 133
|
||||
#define ENOTSUP 134 /* Not supported */
|
||||
#define ENOMEDIUM 135 /* No medium (in tape drive) */
|
||||
#define ENOSHARE 136 /* No such host or network path */
|
||||
#define ECASECLASH 137 /* Filename exists with different case */
|
||||
#define EILSEQ 138
|
||||
#define EOVERFLOW 139 /* Value too large for defined data type */
|
||||
|
||||
/* From cygwin32. */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
|
||||
#define __ELASTERROR 2000 /* Users can add values starting here */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _SYS_ERRNO_H */
|
||||
/* errno is not a global variable, because that would make using it
|
||||
non-reentrant. Instead, its address is returned by the function
|
||||
__errno. */
|
||||
|
||||
#ifndef _SYS_ERRNO_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#define _SYS_ERRNO_H_
|
||||
|
||||
|
||||
#define EPERM 1 /* Not super-user */
|
||||
#define ENOENT 2 /* No such file or directory */
|
||||
#define ESRCH 3 /* No such process */
|
||||
#define EINTR 4 /* Interrupted system call */
|
||||
#define EIO 5 /* I/O error */
|
||||
#define ENXIO 6 /* No such device or address */
|
||||
#define E2BIG 7 /* Arg list too long */
|
||||
#define ENOEXEC 8 /* Exec format error */
|
||||
#define EBADF 9 /* Bad file number */
|
||||
#define ECHILD 10 /* No children */
|
||||
#define EAGAIN 11 /* No more processes */
|
||||
#define ENOMEM 12 /* Not enough core */
|
||||
#define EACCES 13 /* Permission denied */
|
||||
#define EFAULT 14 /* Bad address */
|
||||
#define ENOTBLK 15 /* Block device required */
|
||||
#define EBUSY 16 /* Mount device busy */
|
||||
#define EEXIST 17 /* File exists */
|
||||
#define EXDEV 18 /* Cross-device link */
|
||||
#define ENODEV 19 /* No such device */
|
||||
#define ENOTDIR 20 /* Not a directory */
|
||||
#define EISDIR 21 /* Is a directory */
|
||||
#define EINVAL 22 /* Invalid argument */
|
||||
#define ENFILE 23 /* Too many open files in system */
|
||||
#define EMFILE 24 /* Too many open files */
|
||||
#define ENOTTY 25 /* Not a typewriter */
|
||||
#define ETXTBSY 26 /* Text file busy */
|
||||
#define EFBIG 27 /* File too large */
|
||||
#define ENOSPC 28 /* No space left on device */
|
||||
#define ESPIPE 29 /* Illegal seek */
|
||||
#define EROFS 30 /* Read only file system */
|
||||
#define EMLINK 31 /* Too many links */
|
||||
#define EPIPE 32 /* Broken pipe */
|
||||
#define EDOM 33 /* Math arg out of domain of func */
|
||||
#define ERANGE 34 /* Math result not representable */
|
||||
#define ENOMSG 35 /* No message of desired type */
|
||||
#define EIDRM 36 /* Identifier removed */
|
||||
#define ECHRNG 37 /* Channel number out of range */
|
||||
#define EL2NSYNC 38 /* Level 2 not synchronized */
|
||||
#define EL3HLT 39 /* Level 3 halted */
|
||||
#define EL3RST 40 /* Level 3 reset */
|
||||
#define ELNRNG 41 /* Link number out of range */
|
||||
#define EUNATCH 42 /* Protocol driver not attached */
|
||||
#define ENOCSI 43 /* No CSI structure available */
|
||||
#define EL2HLT 44 /* Level 2 halted */
|
||||
#define EDEADLK 45 /* Deadlock condition */
|
||||
#define ENOLCK 46 /* No record locks available */
|
||||
#define EBADE 50 /* Invalid exchange */
|
||||
#define EBADR 51 /* Invalid request descriptor */
|
||||
#define EXFULL 52 /* Exchange full */
|
||||
#define ENOANO 53 /* No anode */
|
||||
#define EBADRQC 54 /* Invalid request code */
|
||||
#define EBADSLT 55 /* Invalid slot */
|
||||
#define EDEADLOCK 56 /* File locking deadlock error */
|
||||
#define EBFONT 57 /* Bad font file fmt */
|
||||
#define ENOSTR 60 /* Device not a stream */
|
||||
#define ENODATA 61 /* No data (for no delay io) */
|
||||
#define ETIME 62 /* Timer expired */
|
||||
#define ENOSR 63 /* Out of streams resources */
|
||||
#define ENONET 64 /* Machine is not on the network */
|
||||
#define ENOPKG 65 /* Package not installed */
|
||||
#define EREMOTE 66 /* The object is remote */
|
||||
#define ENOLINK 67 /* The link has been severed */
|
||||
#define EADV 68 /* Advertise error */
|
||||
#define ESRMNT 69 /* Srmount error */
|
||||
#define ECOMM 70 /* Communication error on send */
|
||||
#define EPROTO 71 /* Protocol error */
|
||||
#define EMULTIHOP 74 /* Multihop attempted */
|
||||
#define ELBIN 75 /* Inode is remote (not really error) */
|
||||
#define EDOTDOT 76 /* Cross mount point (not really error) */
|
||||
#define EBADMSG 77 /* Trying to read unreadable message */
|
||||
#define EFTYPE 79 /* Inappropriate file type or format */
|
||||
#define ENOTUNIQ 80 /* Given log. name not unique */
|
||||
#define EBADFD 81 /* f.d. invalid for this operation */
|
||||
#define EREMCHG 82 /* Remote address changed */
|
||||
#define ELIBACC 83 /* Can't access a needed shared lib */
|
||||
#define ELIBBAD 84 /* Accessing a corrupted shared lib */
|
||||
#define ELIBSCN 85 /* .lib section in a.out corrupted */
|
||||
#define ELIBMAX 86 /* Attempting to link in too many libs */
|
||||
#define ELIBEXEC 87 /* Attempting to exec a shared library */
|
||||
#define ENOSYS 88 /* Function not implemented */
|
||||
#define ENMFILE 89 /* No more files */
|
||||
#define ENOTEMPTY 90 /* Directory not empty */
|
||||
#define ENAMETOOLONG 91 /* File or path name too long */
|
||||
#define ELOOP 92 /* Too many symbolic links */
|
||||
#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
|
||||
#define EPFNOSUPPORT 96 /* Protocol family not supported */
|
||||
#define ECONNRESET 104 /* Connection reset by peer */
|
||||
#define ENOBUFS 105 /* No buffer space available */
|
||||
#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
|
||||
#define EPROTOTYPE 107 /* Protocol wrong type for socket */
|
||||
#define ENOTSOCK 108 /* Socket operation on non-socket */
|
||||
#define ENOPROTOOPT 109 /* Protocol not available */
|
||||
#define ESHUTDOWN 110 /* Can't send after socket shutdown */
|
||||
#define ECONNREFUSED 111 /* Connection refused */
|
||||
#define EADDRINUSE 112 /* Address already in use */
|
||||
#define ECONNABORTED 113 /* Connection aborted */
|
||||
#define ENETUNREACH 114 /* Network is unreachable */
|
||||
#define ENETDOWN 115 /* Network interface is not configured */
|
||||
#define ETIMEDOUT 116 /* Connection timed out */
|
||||
#define EHOSTDOWN 117 /* Host is down */
|
||||
#define EHOSTUNREACH 118 /* Host is unreachable */
|
||||
#define EINPROGRESS 119 /* Connection already in progress */
|
||||
#define EALREADY 120 /* Socket already connected */
|
||||
#define EDESTADDRREQ 121 /* Destination address required */
|
||||
#define EMSGSIZE 122 /* Message too long */
|
||||
#define EPROTONOSUPPORT 123 /* Unknown protocol */
|
||||
#define ESOCKTNOSUPPORT 124 /* Socket type not supported */
|
||||
#define EADDRNOTAVAIL 125 /* Address not available */
|
||||
#define ENETRESET 126
|
||||
#define EISCONN 127 /* Socket is already connected */
|
||||
#define ENOTCONN 128 /* Socket is not connected */
|
||||
#define ETOOMANYREFS 129
|
||||
#define EPROCLIM 130
|
||||
#define EUSERS 131
|
||||
#define EDQUOT 132
|
||||
#define ESTALE 133
|
||||
#define ENOTSUP 134 /* Not supported */
|
||||
#define ENOMEDIUM 135 /* No medium (in tape drive) */
|
||||
#define ENOSHARE 136 /* No such host or network path */
|
||||
#define ECASECLASH 137 /* Filename exists with different case */
|
||||
#define EILSEQ 138
|
||||
#define EOVERFLOW 139 /* Value too large for defined data type */
|
||||
|
||||
/* From cygwin32. */
|
||||
#define EWOULDBLOCK EAGAIN /* Operation would block */
|
||||
|
||||
#define __ELASTERROR 2000 /* Users can add values starting here */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* _SYS_ERRNO_H */
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef __IOPDEBUG_H__
|
||||
#define __IOPDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
void __printf(char *fmt, ...);
|
||||
|
||||
|
||||
#endif /* __IOPDEBUG_H__ */
|
||||
#ifndef __IOPDEBUG_H__
|
||||
#define __IOPDEBUG_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
void __putc(u8 c);
|
||||
void __puts(u8 *s);
|
||||
void __printf(char *fmt, ...);
|
||||
|
||||
|
||||
#endif /* __IOPDEBUG_H__ */
|
||||
|
|
|
@ -1,226 +1,226 @@
|
|||
#ifndef __IOPELF_H__
|
||||
#define __IOPELF_H__
|
||||
|
||||
#include "romdir.h"
|
||||
|
||||
#define MOD_TYPE_REL 1
|
||||
#define MOD_TYPE_2 2
|
||||
#define MOD_TYPE_DYN 3
|
||||
#define MOD_TYPE_CORE 4
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
short version;
|
||||
} moduleInfo;
|
||||
|
||||
// info about a module file
|
||||
typedef struct module_info {
|
||||
int type; // module type (MOD_TYPE_*)
|
||||
int (*entry)(void*);// module entry point address
|
||||
int gpValue; // module gp value
|
||||
int progVAddr; // programs virtual address
|
||||
int textSize; // size of text section
|
||||
int dataSize; // size of data section
|
||||
int bssSize; // size of bss section
|
||||
int progMemSize; // size of program memory
|
||||
int moduleInfo; // info about module ?
|
||||
} MODULE_INFO;
|
||||
|
||||
typedef struct {
|
||||
u32 ei_magic;
|
||||
u8 ei_class;
|
||||
u8 ei_data;
|
||||
u8 ei_version;
|
||||
u8 ei_pad[9];
|
||||
} E_IDENT;
|
||||
|
||||
typedef struct {
|
||||
u8 e_ident[16]; //+00 0x7f,"ELF" (ELF file identifier), E_IDENT*
|
||||
u16 e_type; //+10 ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
|
||||
u16 e_machine; //+12 Processor: 8=MIPS R3000
|
||||
u32 e_version; //+14 Version: 1=current
|
||||
u32 e_entry; //+18 Entry point address
|
||||
u32 e_phoff; //+1C Start of program headers (offset from file start)
|
||||
u32 e_shoff; //+20 Start of section headers (offset from file start)
|
||||
u32 e_flags; //+24 Processor specific flags = 0x20924001 noreorder, mips
|
||||
u16 e_ehsize; //+28 ELF header size (0x34 = 52 bytes)
|
||||
u16 e_phentsize; //+2A Program headers entry size
|
||||
u16 e_phnum; //+2C Number of program headers
|
||||
u16 e_shentsize; //+2E Section headers entry size
|
||||
u16 e_shnum; //+30 Number of section headers
|
||||
u16 e_shstrndx; //+32 Section header stringtable index
|
||||
} ELF_HEADER; //+34=sizeof
|
||||
#define ET_SCE_IOPRELEXEC 0xFF80
|
||||
#define PT_SCE_IOPMOD 0x70000080
|
||||
#define SHT_REL 9
|
||||
#define EM_MIPS 8
|
||||
|
||||
typedef struct tag_COFF_AOUTHDR {
|
||||
short magic; //+00
|
||||
short vstamp; //+02
|
||||
int tsize; //+04
|
||||
int dsize; //+08
|
||||
int bsize; //+0C
|
||||
int entry; //+10
|
||||
int text_start; //+14
|
||||
int data_start; //+18
|
||||
int bss_start; //+1C
|
||||
int field_20; //+20
|
||||
int field_24; //+24
|
||||
int field_28; //+28
|
||||
int field_2C; //+2C
|
||||
int moduleinfo; //+30
|
||||
int gp_value; //+34
|
||||
} COFF_AOUTHDR, COHDR; //=38
|
||||
|
||||
typedef struct tag_CHDR{
|
||||
short f_magic; //+00
|
||||
short f_nscns; //+02
|
||||
int f_timdat; //+04
|
||||
int f_symptr; //+08
|
||||
int f_nsyms; //+0C
|
||||
short f_opthdr; //+10
|
||||
short f_flags; //+12
|
||||
} CHDR; //=14
|
||||
|
||||
typedef struct tag_COFF_HEADER{ //same header as above
|
||||
short f_magic; //+00
|
||||
short f_nscns; //+02
|
||||
int f_timdat; //+04
|
||||
int f_symptr; //+08
|
||||
int f_nsyms; //+0C
|
||||
short f_opthdr; //+10
|
||||
short f_flags; //+12
|
||||
COFF_AOUTHDR opthdr; //+14
|
||||
} COFF_HEADER; //=4C
|
||||
|
||||
typedef struct tag_COFF_scnhdr
|
||||
{
|
||||
char s_name[8]; //+00
|
||||
int s_paddr; //+08
|
||||
int s_vaddr; //+0C
|
||||
int s_size; //+10
|
||||
int s_scnptr; //+14
|
||||
int s_relptr; //+18
|
||||
int s_lnnoptr; //+1C
|
||||
short s_nreloc; //+20
|
||||
short s_nlnno; //+22
|
||||
int s_flags; //+24
|
||||
} COFF_scnhdr, SHDR; //=28
|
||||
|
||||
typedef struct _fileInfo
|
||||
{
|
||||
u32 type, //+00
|
||||
entry, //+04
|
||||
gp_value, //+08
|
||||
p1_vaddr, //+0C
|
||||
text_size, //+10
|
||||
data_size, //+14
|
||||
bss_size, //+18
|
||||
p1_memsz; //+1C
|
||||
moduleInfo *moduleinfo; //+20
|
||||
} fileInfo;
|
||||
|
||||
typedef struct {
|
||||
u32 p_type; //+00 see notes1
|
||||
u32 p_offset; //+04 Offset from file start to program segment.
|
||||
u32 p_vaddr; //+08 Virtual address of the segment
|
||||
u32 p_paddr; //+0C Physical address of the segment
|
||||
u32 p_filesz; //+10 Number of bytes in the file image of the segment
|
||||
u32 p_memsz; //+14 Number of bytes in the memory image of the segment
|
||||
u32 p_flags; //+18 Flags for segment
|
||||
u32 p_align; //+1C Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
||||
} ELF_PHR;
|
||||
|
||||
//notes1
|
||||
//------
|
||||
//0=Inactive
|
||||
//1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
||||
//2=Dynamic linking
|
||||
//3=Interpreter. The array element must specify a path name
|
||||
//4=Note. The array element must specify the location and size of aux. info
|
||||
//5=reserved
|
||||
//6=The array element must specify location and size of the program header table.
|
||||
|
||||
typedef struct {
|
||||
u32 r_offset;
|
||||
u32 r_info;
|
||||
} ELF_REL;
|
||||
|
||||
typedef struct {
|
||||
char* moduleinfo;
|
||||
u32 entry; //+04
|
||||
u32 gp_value; //+08
|
||||
u32 text_size; //+0C
|
||||
u32 data_size; //+10
|
||||
u32 bss_size;//+14
|
||||
short moduleversion;//+18
|
||||
char* modulename; //+1A
|
||||
} ELF_IOPMOD;
|
||||
|
||||
typedef struct {
|
||||
u32 sh_name; //+00 No. to the index of the Section header stringtable index
|
||||
u32 sh_type; //+04 See notes2
|
||||
u32 sh_flags; //+08 see notes3
|
||||
u32 sh_addr; //+0C Section start address
|
||||
u32 sh_offset; //+10 Offset from start of file to section
|
||||
u32 sh_size; //+14 Size of section
|
||||
u32 sh_link; //+18 Section header table index link
|
||||
u32 sh_info; //+1C Info
|
||||
u32 sh_addralign; //+20 Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
||||
u32 sh_entsize; //+24 Fixed size entries.
|
||||
} ELF_SHR;
|
||||
|
||||
//notes 2
|
||||
//-------
|
||||
//Type:
|
||||
//0=Inactive
|
||||
//1=PROGBITS
|
||||
//2=SYMTAB symbol table
|
||||
//3=STRTAB string table
|
||||
//4=RELA relocation entries
|
||||
//5=HASH hash table
|
||||
//6=DYNAMIC dynamic linking information
|
||||
//7=NOTE
|
||||
//8=NOBITS
|
||||
//9=REL relocation entries
|
||||
//10=SHLIB
|
||||
//0x70000000=LOPROC processor specifc
|
||||
//0x7fffffff=HIPROC
|
||||
//0x80000000=LOUSER lower bound
|
||||
//0xffffffff=HIUSER upper bound
|
||||
//
|
||||
//notes 3
|
||||
//-------
|
||||
//Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
||||
//1=Write section contains data the is be writeable during execution.
|
||||
//2=Alloc section occupies memory during execution
|
||||
//4=Exec section contains executable instructions
|
||||
//0xf0000000=Mask bits processor-specific
|
||||
|
||||
|
||||
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
||||
|
||||
// special header for every iop module?
|
||||
typedef struct {
|
||||
u32 next; //+00
|
||||
char *name; //+04
|
||||
short version, //+08
|
||||
flags, //+0A
|
||||
modid, //+0C
|
||||
HE; //+0E
|
||||
u32 entry, //+10
|
||||
gp_value, //+14
|
||||
p1_vaddr, //+18
|
||||
text_size, //+1C
|
||||
data_size, //+20
|
||||
bss_size, //+24
|
||||
H28, //+28
|
||||
H2C; //+2C
|
||||
} imageInfo;
|
||||
|
||||
// pass in the memory to load the elf file from
|
||||
// elfoffset - offset to load elf file to
|
||||
void* loadElfFile(ROMFILE_INFO* ri, u32 elfoffset);
|
||||
|
||||
#endif
|
||||
#ifndef __IOPELF_H__
|
||||
#define __IOPELF_H__
|
||||
|
||||
#include "romdir.h"
|
||||
|
||||
#define MOD_TYPE_REL 1
|
||||
#define MOD_TYPE_2 2
|
||||
#define MOD_TYPE_DYN 3
|
||||
#define MOD_TYPE_CORE 4
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
short version;
|
||||
} moduleInfo;
|
||||
|
||||
// info about a module file
|
||||
typedef struct module_info {
|
||||
int type; // module type (MOD_TYPE_*)
|
||||
int (*entry)(void*);// module entry point address
|
||||
int gpValue; // module gp value
|
||||
int progVAddr; // programs virtual address
|
||||
int textSize; // size of text section
|
||||
int dataSize; // size of data section
|
||||
int bssSize; // size of bss section
|
||||
int progMemSize; // size of program memory
|
||||
int moduleInfo; // info about module ?
|
||||
} MODULE_INFO;
|
||||
|
||||
typedef struct {
|
||||
u32 ei_magic;
|
||||
u8 ei_class;
|
||||
u8 ei_data;
|
||||
u8 ei_version;
|
||||
u8 ei_pad[9];
|
||||
} E_IDENT;
|
||||
|
||||
typedef struct {
|
||||
u8 e_ident[16]; //+00 0x7f,"ELF" (ELF file identifier), E_IDENT*
|
||||
u16 e_type; //+10 ELF type: 0=NONE, 1=REL, 2=EXEC, 3=SHARED, 4=CORE
|
||||
u16 e_machine; //+12 Processor: 8=MIPS R3000
|
||||
u32 e_version; //+14 Version: 1=current
|
||||
u32 e_entry; //+18 Entry point address
|
||||
u32 e_phoff; //+1C Start of program headers (offset from file start)
|
||||
u32 e_shoff; //+20 Start of section headers (offset from file start)
|
||||
u32 e_flags; //+24 Processor specific flags = 0x20924001 noreorder, mips
|
||||
u16 e_ehsize; //+28 ELF header size (0x34 = 52 bytes)
|
||||
u16 e_phentsize; //+2A Program headers entry size
|
||||
u16 e_phnum; //+2C Number of program headers
|
||||
u16 e_shentsize; //+2E Section headers entry size
|
||||
u16 e_shnum; //+30 Number of section headers
|
||||
u16 e_shstrndx; //+32 Section header stringtable index
|
||||
} ELF_HEADER; //+34=sizeof
|
||||
#define ET_SCE_IOPRELEXEC 0xFF80
|
||||
#define PT_SCE_IOPMOD 0x70000080
|
||||
#define SHT_REL 9
|
||||
#define EM_MIPS 8
|
||||
|
||||
typedef struct tag_COFF_AOUTHDR {
|
||||
short magic; //+00
|
||||
short vstamp; //+02
|
||||
int tsize; //+04
|
||||
int dsize; //+08
|
||||
int bsize; //+0C
|
||||
int entry; //+10
|
||||
int text_start; //+14
|
||||
int data_start; //+18
|
||||
int bss_start; //+1C
|
||||
int field_20; //+20
|
||||
int field_24; //+24
|
||||
int field_28; //+28
|
||||
int field_2C; //+2C
|
||||
int moduleinfo; //+30
|
||||
int gp_value; //+34
|
||||
} COFF_AOUTHDR, COHDR; //=38
|
||||
|
||||
typedef struct tag_CHDR{
|
||||
short f_magic; //+00
|
||||
short f_nscns; //+02
|
||||
int f_timdat; //+04
|
||||
int f_symptr; //+08
|
||||
int f_nsyms; //+0C
|
||||
short f_opthdr; //+10
|
||||
short f_flags; //+12
|
||||
} CHDR; //=14
|
||||
|
||||
typedef struct tag_COFF_HEADER{ //same header as above
|
||||
short f_magic; //+00
|
||||
short f_nscns; //+02
|
||||
int f_timdat; //+04
|
||||
int f_symptr; //+08
|
||||
int f_nsyms; //+0C
|
||||
short f_opthdr; //+10
|
||||
short f_flags; //+12
|
||||
COFF_AOUTHDR opthdr; //+14
|
||||
} COFF_HEADER; //=4C
|
||||
|
||||
typedef struct tag_COFF_scnhdr
|
||||
{
|
||||
char s_name[8]; //+00
|
||||
int s_paddr; //+08
|
||||
int s_vaddr; //+0C
|
||||
int s_size; //+10
|
||||
int s_scnptr; //+14
|
||||
int s_relptr; //+18
|
||||
int s_lnnoptr; //+1C
|
||||
short s_nreloc; //+20
|
||||
short s_nlnno; //+22
|
||||
int s_flags; //+24
|
||||
} COFF_scnhdr, SHDR; //=28
|
||||
|
||||
typedef struct _fileInfo
|
||||
{
|
||||
u32 type, //+00
|
||||
entry, //+04
|
||||
gp_value, //+08
|
||||
p1_vaddr, //+0C
|
||||
text_size, //+10
|
||||
data_size, //+14
|
||||
bss_size, //+18
|
||||
p1_memsz; //+1C
|
||||
moduleInfo *moduleinfo; //+20
|
||||
} fileInfo;
|
||||
|
||||
typedef struct {
|
||||
u32 p_type; //+00 see notes1
|
||||
u32 p_offset; //+04 Offset from file start to program segment.
|
||||
u32 p_vaddr; //+08 Virtual address of the segment
|
||||
u32 p_paddr; //+0C Physical address of the segment
|
||||
u32 p_filesz; //+10 Number of bytes in the file image of the segment
|
||||
u32 p_memsz; //+14 Number of bytes in the memory image of the segment
|
||||
u32 p_flags; //+18 Flags for segment
|
||||
u32 p_align; //+1C Alignment. The address of 0x08 and 0x0C must fit this alignment. 0=no alignment
|
||||
} ELF_PHR;
|
||||
|
||||
//notes1
|
||||
//------
|
||||
//0=Inactive
|
||||
//1=Load the segment into memory, no. of bytes specified by 0x10 and 0x14
|
||||
//2=Dynamic linking
|
||||
//3=Interpreter. The array element must specify a path name
|
||||
//4=Note. The array element must specify the location and size of aux. info
|
||||
//5=reserved
|
||||
//6=The array element must specify location and size of the program header table.
|
||||
|
||||
typedef struct {
|
||||
u32 r_offset;
|
||||
u32 r_info;
|
||||
} ELF_REL;
|
||||
|
||||
typedef struct {
|
||||
char* moduleinfo;
|
||||
u32 entry; //+04
|
||||
u32 gp_value; //+08
|
||||
u32 text_size; //+0C
|
||||
u32 data_size; //+10
|
||||
u32 bss_size;//+14
|
||||
short moduleversion;//+18
|
||||
char* modulename; //+1A
|
||||
} ELF_IOPMOD;
|
||||
|
||||
typedef struct {
|
||||
u32 sh_name; //+00 No. to the index of the Section header stringtable index
|
||||
u32 sh_type; //+04 See notes2
|
||||
u32 sh_flags; //+08 see notes3
|
||||
u32 sh_addr; //+0C Section start address
|
||||
u32 sh_offset; //+10 Offset from start of file to section
|
||||
u32 sh_size; //+14 Size of section
|
||||
u32 sh_link; //+18 Section header table index link
|
||||
u32 sh_info; //+1C Info
|
||||
u32 sh_addralign; //+20 Alignment. The adress of 0x0C must fit this alignment. 0=no alignment.
|
||||
u32 sh_entsize; //+24 Fixed size entries.
|
||||
} ELF_SHR;
|
||||
|
||||
//notes 2
|
||||
//-------
|
||||
//Type:
|
||||
//0=Inactive
|
||||
//1=PROGBITS
|
||||
//2=SYMTAB symbol table
|
||||
//3=STRTAB string table
|
||||
//4=RELA relocation entries
|
||||
//5=HASH hash table
|
||||
//6=DYNAMIC dynamic linking information
|
||||
//7=NOTE
|
||||
//8=NOBITS
|
||||
//9=REL relocation entries
|
||||
//10=SHLIB
|
||||
//0x70000000=LOPROC processor specifc
|
||||
//0x7fffffff=HIPROC
|
||||
//0x80000000=LOUSER lower bound
|
||||
//0xffffffff=HIUSER upper bound
|
||||
//
|
||||
//notes 3
|
||||
//-------
|
||||
//Section Flags: (1 bit, you may combine them like 3 = alloc & write permission)
|
||||
//1=Write section contains data the is be writeable during execution.
|
||||
//2=Alloc section occupies memory during execution
|
||||
//4=Exec section contains executable instructions
|
||||
//0xf0000000=Mask bits processor-specific
|
||||
|
||||
|
||||
#define ELF32_ST_TYPE(i) ((i)&0xf)
|
||||
|
||||
// special header for every iop module?
|
||||
typedef struct {
|
||||
u32 next; //+00
|
||||
char *name; //+04
|
||||
short version, //+08
|
||||
flags, //+0A
|
||||
modid, //+0C
|
||||
HE; //+0E
|
||||
u32 entry, //+10
|
||||
gp_value, //+14
|
||||
p1_vaddr, //+18
|
||||
text_size, //+1C
|
||||
data_size, //+20
|
||||
bss_size, //+24
|
||||
H28, //+28
|
||||
H2C; //+2C
|
||||
} imageInfo;
|
||||
|
||||
// pass in the memory to load the elf file from
|
||||
// elfoffset - offset to load elf file to
|
||||
void* loadElfFile(ROMFILE_INFO* ri, u32 elfoffset);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
#ifndef __IOPLOAD_H__
|
||||
#define __IOPLOAD_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
extern char *iopModules[32];
|
||||
|
||||
void Kmemcpy(void *dest, const void *src, int n);
|
||||
|
||||
#define SBUS_MSFLG *(volatile int*)0xBD00F220
|
||||
#define SBUS_SMFLG *(volatile int*)0xBD00F230
|
||||
#define SBUS_F240 *(volatile int*)0xBD00F240
|
||||
|
||||
#define SBFLG_IOPALIVE 0x10000
|
||||
#define SBFLG_IOPSYNC 0x40000
|
||||
|
||||
|
||||
#endif /* __IOPLOAD_H__ */
|
||||
#ifndef __IOPLOAD_H__
|
||||
#define __IOPLOAD_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
extern char *iopModules[32];
|
||||
|
||||
void Kmemcpy(void *dest, const void *src, int n);
|
||||
|
||||
#define SBUS_MSFLG *(volatile int*)0xBD00F220
|
||||
#define SBUS_SMFLG *(volatile int*)0xBD00F230
|
||||
#define SBUS_F240 *(volatile int*)0xBD00F240
|
||||
|
||||
#define SBFLG_IOPALIVE 0x10000
|
||||
#define SBFLG_IOPSYNC 0x40000
|
||||
|
||||
|
||||
#endif /* __IOPLOAD_H__ */
|
||||
|
|
|
@ -1,116 +1,116 @@
|
|||
#ifndef __DMACMAN_H__
|
||||
#define __DMACMAN_H__
|
||||
|
||||
#define DMACMAN_VER 0x101
|
||||
|
||||
////////////////////////////// D_CHCR - DMA Channel Control Register
|
||||
#define DMAf_30 0x40000000 // unknown; set on 'to' direction
|
||||
#define DMAf_TR 0x01000000 // DMA transfer
|
||||
#define DMAf_LI 0x00000400 // Linked list GPU; also SPU & SIF0
|
||||
#define DMAf_CO 0x00000200 // Continuous stream
|
||||
#define DMAf_08 0x00000100 // unknown
|
||||
#define DMAf_DR 0x00000001 // Direction to=0/from=1
|
||||
// 31 24 23 16 15 8 7 0
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³?³ ³ ³ ³ ³ ³Tº ³ ³ ³ ³ ³ ³ ³ º ³ ³ ³ ³ ³L³C³?º ³ ³ ³ ³ ³ ³ ³Dº
|
||||
// º ³?³ ³ ³ ³ ³ ³Rº ³ ³ ³ ³ ³ ³ ³ º ³ ³ ³ ³ ³I³O³?º ³ ³ ³ ³ ³ ³ ³Rº
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// 30 24 10 9 8 0
|
||||
|
||||
////////////////////////////// DPCR - DMA Primary Control Register
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º 67 ³ DMA 6 º DMA 5 ³ DMA 4 º DMA 3 ³ DMA 2 º DMA 1 ³ DMA 0 º 0xBF8010F0 DPCR
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³ DMA85 º DMA12 ³ DMA11 º DMA10 ³ DMA 9 º DMA 8 ³ DMA 7 º 0xBF801570 DPCR_
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³ º ³ º ³ DMA15 º DMA14 ³ DMA13 º 0xBF8015F0 DPCR__
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
|
||||
////////// DPCR
|
||||
#define DMAch_MDECin 0
|
||||
#define DMAch_MDECout 1
|
||||
#define DMAch_GPU 2 // SIF2 both directions
|
||||
#define DMAch_CD 3
|
||||
#define DMAch_SPU 4
|
||||
#define DMAch_PIO 5
|
||||
#define DMAch_GPUotc 6
|
||||
|
||||
#define DMAch_67 67 // strange
|
||||
|
||||
////////// DPCR_
|
||||
#define DMAch_SPU2 7
|
||||
#define DMAch_8 8
|
||||
#define DMAch_SIF0 9 // SIFout IOP->EE
|
||||
#define DMAch_SIF1 10 // SIFin EE->IOP
|
||||
#define DMAch_SIO2in 11
|
||||
#define DMAch_SIO2out 12
|
||||
|
||||
#define DMAch_85 85 // stange, very strange
|
||||
|
||||
////////// DPCR__
|
||||
#define DMAch_13 13
|
||||
#define DMAch_14 14
|
||||
#define DMAch_15 15
|
||||
|
||||
int dmacman_start(int argc, char* argv[]); // 0
|
||||
int dmacman_deinit(); // 2
|
||||
|
||||
void dmacman_call4_SetD_MADR(unsigned int ch, int value); // 4
|
||||
int dmacman_call5_GetD_MADR(unsigned int ch); // 5
|
||||
void dmacman_call6_SetD_BCR(unsigned int ch, int value); // 6
|
||||
int dmacman_call7_GetD_BCR(unsigned int ch); // 7
|
||||
void dmacman_call8_SetD_CHCR(unsigned int ch, int value); // 8
|
||||
int dmacman_call9_GetD_CHCR(unsigned int ch); // 9
|
||||
void dmacman_call10_SetD_TADR(unsigned int ch, int value); //10
|
||||
int dmacman_call11_GetD_TADR(unsigned int ch); //11
|
||||
void dmacman_call12_Set_4_9_A(unsigned int ch, int value); //12
|
||||
int dmacman_call13_Get_4_9_A(unsigned int ch); //13
|
||||
void dmacman_call14_SetDPCR(int value); //14
|
||||
int dmacman_call15_GetDPCR(); //15
|
||||
void dmacman_call16_SetDPCR2(int value); //16
|
||||
int dmacman_call17_GetDPCR2(); //17
|
||||
void dmacman_call18_SetDPCR3(int value); //18
|
||||
int dmacman_call19_GetDPCR3(); //19
|
||||
void dmacman_call20_SetDICR(int value); //20
|
||||
int dmacman_call21_GetDICR(); //21
|
||||
void dmacman_call22_SetDICR2(int value); //22
|
||||
int dmacman_call23_GetDICR2(); //23
|
||||
void dmacman_call24_setBF80157C(int value); //24
|
||||
int dmacman_call25_getBF80157C(); //25
|
||||
void dmacman_call26_setBF801578(int value); //26
|
||||
int dmacman_call27_getBF801578(); //27
|
||||
int dmacman_call28_SetDMA(int ch, int address, int size, int count, int dir); //28
|
||||
int dmacman_call29_SetDMA_chainedSPU_SIF0(int ch, int size, int c);//29
|
||||
int dmacman_call30_SetDMA_SIF0(int ch, int size, int c); //30
|
||||
int dmacman_call31_SetDMA_SIF1(int ch, int size); //31
|
||||
void dmacman_call32_StartTransfer(int ch); //32
|
||||
void dmacman_call33_SetVal(int ch, int value); //33
|
||||
void dmacman_call34_EnableDMAch(int ch); //34
|
||||
void dmacman_call35_DisableDMAch(int ch); //35
|
||||
|
||||
//SIF2 DMA ch 2 (GPU)
|
||||
#define DMAch_SIF2_MADR (*(volatile int*)0xBF8010A0)
|
||||
#define DMAch_SIF2_BCR (*(volatile int*)0xBF8010A4)
|
||||
#define DMAch_SIF2_BCR_size (*(volatile short*)0xBF8010A4)
|
||||
#define DMAch_SIF2_BCR_count (*(volatile short*)0xBF8010A6)
|
||||
#define DMAch_SIF2_CHCR (*(volatile int*)0xBF8010A8)
|
||||
//SIF0 DMA ch 9
|
||||
#define DMAch_SIF9_MADR (*(volatile int*)0xBF801520)
|
||||
#define DMAch_SIF9_BCR (*(volatile int*)0xBF801524)
|
||||
#define DMAch_SIF9_BCR_size (*(volatile short*)0xBF801524)
|
||||
#define DMAch_SIF9_BCR_count (*(volatile short*)0xBF801526)
|
||||
#define DMAch_SIF9_CHCR (*(volatile int*)0xBF801528)
|
||||
#define DMAch_SIF9_TADR (*(volatile int*)0xBF80152C)
|
||||
//SIF1 DMA ch 10 (0xA)
|
||||
#define DMAch_SIFA_MADR (*(volatile int*)0xBF801530)
|
||||
#define DMAch_SIFA_BCR (*(volatile int*)0xBF801534)
|
||||
#define DMAch_SIFA_BCR_size (*(volatile short*)0xBF801534)
|
||||
#define DMAch_SIFA_BCR_count (*(volatile short*)0xBF801536)
|
||||
#define DMAch_SIFA_CHCR (*(volatile int*)0xBF801538)
|
||||
|
||||
#define DMAch_DPCR (*(volatile int*)0xBF8010F0)
|
||||
#define DMAch_DPCR2 (*(volatile int*)0xBF801570)
|
||||
|
||||
#endif//__DMACMAN_H__
|
||||
#ifndef __DMACMAN_H__
|
||||
#define __DMACMAN_H__
|
||||
|
||||
#define DMACMAN_VER 0x101
|
||||
|
||||
////////////////////////////// D_CHCR - DMA Channel Control Register
|
||||
#define DMAf_30 0x40000000 // unknown; set on 'to' direction
|
||||
#define DMAf_TR 0x01000000 // DMA transfer
|
||||
#define DMAf_LI 0x00000400 // Linked list GPU; also SPU & SIF0
|
||||
#define DMAf_CO 0x00000200 // Continuous stream
|
||||
#define DMAf_08 0x00000100 // unknown
|
||||
#define DMAf_DR 0x00000001 // Direction to=0/from=1
|
||||
// 31 24 23 16 15 8 7 0
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³?³ ³ ³ ³ ³ ³Tº ³ ³ ³ ³ ³ ³ ³ º ³ ³ ³ ³ ³L³C³?º ³ ³ ³ ³ ³ ³ ³Dº
|
||||
// º ³?³ ³ ³ ³ ³ ³Rº ³ ³ ³ ³ ³ ³ ³ º ³ ³ ³ ³ ³I³O³?º ³ ³ ³ ³ ³ ³ ³Rº
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// 30 24 10 9 8 0
|
||||
|
||||
////////////////////////////// DPCR - DMA Primary Control Register
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º 67 ³ DMA 6 º DMA 5 ³ DMA 4 º DMA 3 ³ DMA 2 º DMA 1 ³ DMA 0 º 0xBF8010F0 DPCR
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³ DMA85 º DMA12 ³ DMA11 º DMA10 ³ DMA 9 º DMA 8 ³ DMA 7 º 0xBF801570 DPCR_
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
// ÖÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÒÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ·
|
||||
// º ³ º ³ º ³ DMA15 º DMA14 ³ DMA13 º 0xBF8015F0 DPCR__
|
||||
// ÓÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÐÄÁÄÁÄÁÄÁÄÁÄÁÄÁĽ
|
||||
|
||||
////////// DPCR
|
||||
#define DMAch_MDECin 0
|
||||
#define DMAch_MDECout 1
|
||||
#define DMAch_GPU 2 // SIF2 both directions
|
||||
#define DMAch_CD 3
|
||||
#define DMAch_SPU 4
|
||||
#define DMAch_PIO 5
|
||||
#define DMAch_GPUotc 6
|
||||
|
||||
#define DMAch_67 67 // strange
|
||||
|
||||
////////// DPCR_
|
||||
#define DMAch_SPU2 7
|
||||
#define DMAch_8 8
|
||||
#define DMAch_SIF0 9 // SIFout IOP->EE
|
||||
#define DMAch_SIF1 10 // SIFin EE->IOP
|
||||
#define DMAch_SIO2in 11
|
||||
#define DMAch_SIO2out 12
|
||||
|
||||
#define DMAch_85 85 // stange, very strange
|
||||
|
||||
////////// DPCR__
|
||||
#define DMAch_13 13
|
||||
#define DMAch_14 14
|
||||
#define DMAch_15 15
|
||||
|
||||
int dmacman_start(int argc, char* argv[]); // 0
|
||||
int dmacman_deinit(); // 2
|
||||
|
||||
void dmacman_call4_SetD_MADR(unsigned int ch, int value); // 4
|
||||
int dmacman_call5_GetD_MADR(unsigned int ch); // 5
|
||||
void dmacman_call6_SetD_BCR(unsigned int ch, int value); // 6
|
||||
int dmacman_call7_GetD_BCR(unsigned int ch); // 7
|
||||
void dmacman_call8_SetD_CHCR(unsigned int ch, int value); // 8
|
||||
int dmacman_call9_GetD_CHCR(unsigned int ch); // 9
|
||||
void dmacman_call10_SetD_TADR(unsigned int ch, int value); //10
|
||||
int dmacman_call11_GetD_TADR(unsigned int ch); //11
|
||||
void dmacman_call12_Set_4_9_A(unsigned int ch, int value); //12
|
||||
int dmacman_call13_Get_4_9_A(unsigned int ch); //13
|
||||
void dmacman_call14_SetDPCR(int value); //14
|
||||
int dmacman_call15_GetDPCR(); //15
|
||||
void dmacman_call16_SetDPCR2(int value); //16
|
||||
int dmacman_call17_GetDPCR2(); //17
|
||||
void dmacman_call18_SetDPCR3(int value); //18
|
||||
int dmacman_call19_GetDPCR3(); //19
|
||||
void dmacman_call20_SetDICR(int value); //20
|
||||
int dmacman_call21_GetDICR(); //21
|
||||
void dmacman_call22_SetDICR2(int value); //22
|
||||
int dmacman_call23_GetDICR2(); //23
|
||||
void dmacman_call24_setBF80157C(int value); //24
|
||||
int dmacman_call25_getBF80157C(); //25
|
||||
void dmacman_call26_setBF801578(int value); //26
|
||||
int dmacman_call27_getBF801578(); //27
|
||||
int dmacman_call28_SetDMA(int ch, int address, int size, int count, int dir); //28
|
||||
int dmacman_call29_SetDMA_chainedSPU_SIF0(int ch, int size, int c);//29
|
||||
int dmacman_call30_SetDMA_SIF0(int ch, int size, int c); //30
|
||||
int dmacman_call31_SetDMA_SIF1(int ch, int size); //31
|
||||
void dmacman_call32_StartTransfer(int ch); //32
|
||||
void dmacman_call33_SetVal(int ch, int value); //33
|
||||
void dmacman_call34_EnableDMAch(int ch); //34
|
||||
void dmacman_call35_DisableDMAch(int ch); //35
|
||||
|
||||
//SIF2 DMA ch 2 (GPU)
|
||||
#define DMAch_SIF2_MADR (*(volatile int*)0xBF8010A0)
|
||||
#define DMAch_SIF2_BCR (*(volatile int*)0xBF8010A4)
|
||||
#define DMAch_SIF2_BCR_size (*(volatile short*)0xBF8010A4)
|
||||
#define DMAch_SIF2_BCR_count (*(volatile short*)0xBF8010A6)
|
||||
#define DMAch_SIF2_CHCR (*(volatile int*)0xBF8010A8)
|
||||
//SIF0 DMA ch 9
|
||||
#define DMAch_SIF9_MADR (*(volatile int*)0xBF801520)
|
||||
#define DMAch_SIF9_BCR (*(volatile int*)0xBF801524)
|
||||
#define DMAch_SIF9_BCR_size (*(volatile short*)0xBF801524)
|
||||
#define DMAch_SIF9_BCR_count (*(volatile short*)0xBF801526)
|
||||
#define DMAch_SIF9_CHCR (*(volatile int*)0xBF801528)
|
||||
#define DMAch_SIF9_TADR (*(volatile int*)0xBF80152C)
|
||||
//SIF1 DMA ch 10 (0xA)
|
||||
#define DMAch_SIFA_MADR (*(volatile int*)0xBF801530)
|
||||
#define DMAch_SIFA_BCR (*(volatile int*)0xBF801534)
|
||||
#define DMAch_SIFA_BCR_size (*(volatile short*)0xBF801534)
|
||||
#define DMAch_SIFA_BCR_count (*(volatile short*)0xBF801536)
|
||||
#define DMAch_SIFA_CHCR (*(volatile int*)0xBF801538)
|
||||
|
||||
#define DMAch_DPCR (*(volatile int*)0xBF8010F0)
|
||||
#define DMAch_DPCR2 (*(volatile int*)0xBF801570)
|
||||
|
||||
#endif//__DMACMAN_H__
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
#ifndef __EXCEPMAN_H__
|
||||
#define __EXCEPMAN_H__
|
||||
|
||||
#define EXCEPMAN_VER 0x101
|
||||
|
||||
#define EXCEP_MAX 16
|
||||
|
||||
struct exHandler {
|
||||
void *next; // next points to the next funccode :/
|
||||
int info;
|
||||
u32 funccode[0];
|
||||
};
|
||||
|
||||
void *GetExHandlersTable(); // 3
|
||||
|
||||
int RegisterExceptionHandler(int code, struct exHandler *handler); // 4
|
||||
int RegisterPriorityExceptionHandler(int code, int priority,
|
||||
struct exHandler *handler); // 5
|
||||
int RegisterDefaultExceptionHandler(struct exHandler *handler); // 6
|
||||
int ReleaseExceptionHandler(int excode, struct exHandler *handler); // 7
|
||||
int ReleaseDefaultExceptionHandler(struct exHandler *handler); // 8
|
||||
|
||||
#endif//__EXCEPMAN_H__
|
||||
#ifndef __EXCEPMAN_H__
|
||||
#define __EXCEPMAN_H__
|
||||
|
||||
#define EXCEPMAN_VER 0x101
|
||||
|
||||
#define EXCEP_MAX 16
|
||||
|
||||
struct exHandler {
|
||||
void *next; // next points to the next funccode :/
|
||||
int info;
|
||||
u32 funccode[0];
|
||||
};
|
||||
|
||||
void *GetExHandlersTable(); // 3
|
||||
|
||||
int RegisterExceptionHandler(int code, struct exHandler *handler); // 4
|
||||
int RegisterPriorityExceptionHandler(int code, int priority,
|
||||
struct exHandler *handler); // 5
|
||||
int RegisterDefaultExceptionHandler(struct exHandler *handler); // 6
|
||||
int ReleaseExceptionHandler(int excode, struct exHandler *handler); // 7
|
||||
int ReleaseDefaultExceptionHandler(struct exHandler *handler); // 8
|
||||
|
||||
#endif//__EXCEPMAN_H__
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
#ifndef __HEAPLIB_H__
|
||||
#define __HEAPLIB_H__
|
||||
|
||||
struct ll{ struct ll *next, *prev; }; //linked list
|
||||
|
||||
|
||||
struct Heap {
|
||||
long plus_one;
|
||||
int size2free;
|
||||
struct ll l;
|
||||
void *mem;
|
||||
};
|
||||
|
||||
struct Chunk {
|
||||
u32 _mem;
|
||||
int freesize;
|
||||
int usedsize;
|
||||
u32 mem_16;
|
||||
u32 unk4;
|
||||
u32 unk5;
|
||||
};
|
||||
|
||||
void *CreateHeap(int chunkSize, int memoryType );
|
||||
int DestroyHeap(void *heap);
|
||||
|
||||
void *HeapMalloc(void *heap, int size);
|
||||
int HeapFree(void *heap, void * mem);
|
||||
int HeapSize(void *heap);
|
||||
|
||||
#endif /* __HEAPLIB_H__ */
|
||||
#ifndef __HEAPLIB_H__
|
||||
#define __HEAPLIB_H__
|
||||
|
||||
struct ll{ struct ll *next, *prev; }; //linked list
|
||||
|
||||
|
||||
struct Heap {
|
||||
long plus_one;
|
||||
int size2free;
|
||||
struct ll l;
|
||||
void *mem;
|
||||
};
|
||||
|
||||
struct Chunk {
|
||||
u32 _mem;
|
||||
int freesize;
|
||||
int usedsize;
|
||||
u32 mem_16;
|
||||
u32 unk4;
|
||||
u32 unk5;
|
||||
};
|
||||
|
||||
void *CreateHeap(int chunkSize, int memoryType );
|
||||
int DestroyHeap(void *heap);
|
||||
|
||||
void *HeapMalloc(void *heap, int size);
|
||||
int HeapFree(void *heap, void * mem);
|
||||
int HeapSize(void *heap);
|
||||
|
||||
#endif /* __HEAPLIB_H__ */
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
#ifndef __INTRMAN_H__
|
||||
#define __INTRMAN_H__
|
||||
|
||||
#define INTRMAN_VER 0x102
|
||||
|
||||
#define INT_VBLANK 0x00
|
||||
|
||||
#define INT_CDROM 0x02
|
||||
|
||||
#define INT_RTC0 0x04
|
||||
#define INT_RTC1 0x05
|
||||
#define INT_RTC2 0x06
|
||||
|
||||
#define INT_EVBLANK 0x0B
|
||||
|
||||
#define INT_RTC3 0x0E
|
||||
#define INT_RTC4 0x0F
|
||||
#define INT_RTC5 0x10
|
||||
|
||||
#define INT_DMA9 0x2A //sif0
|
||||
#define INT_DMA10 0x2B //sif1
|
||||
|
||||
#define IMODE_DMA_IRM 0x100
|
||||
#define IMODE_DMA_IQE 0x200
|
||||
|
||||
typedef int (*intrh_func)(void*);
|
||||
|
||||
int RegisterIntrHandler(int interrupt, int, intrh_func intrh, void*);
|
||||
//4 (13,18)
|
||||
int ReleaseIntrHandler(int interrupt); //5 (18)
|
||||
int EnableIntr(int interrupt); //6 (13,18)
|
||||
int DisableIntr(int interrupt, int *oldstat); //7 (18)
|
||||
int CpuEnableIntr(); //9 (18,21,26)
|
||||
int CpuSuspendIntr(u32* ictrl); //17(05,06,07,13,14,18,26)
|
||||
int CpuResumeIntr(u32 ictrl); //18(05,06,07,13,14,18,26)
|
||||
int QueryIntrContext(); //23(07,13)
|
||||
|
||||
#endif//__INTRMAN_H__
|
||||
#ifndef __INTRMAN_H__
|
||||
#define __INTRMAN_H__
|
||||
|
||||
#define INTRMAN_VER 0x102
|
||||
|
||||
#define INT_VBLANK 0x00
|
||||
|
||||
#define INT_CDROM 0x02
|
||||
|
||||
#define INT_RTC0 0x04
|
||||
#define INT_RTC1 0x05
|
||||
#define INT_RTC2 0x06
|
||||
|
||||
#define INT_EVBLANK 0x0B
|
||||
|
||||
#define INT_RTC3 0x0E
|
||||
#define INT_RTC4 0x0F
|
||||
#define INT_RTC5 0x10
|
||||
|
||||
#define INT_DMA9 0x2A //sif0
|
||||
#define INT_DMA10 0x2B //sif1
|
||||
|
||||
#define IMODE_DMA_IRM 0x100
|
||||
#define IMODE_DMA_IQE 0x200
|
||||
|
||||
typedef int (*intrh_func)(void*);
|
||||
|
||||
int RegisterIntrHandler(int interrupt, int, intrh_func intrh, void*);
|
||||
//4 (13,18)
|
||||
int ReleaseIntrHandler(int interrupt); //5 (18)
|
||||
int EnableIntr(int interrupt); //6 (13,18)
|
||||
int DisableIntr(int interrupt, int *oldstat); //7 (18)
|
||||
int CpuEnableIntr(); //9 (18,21,26)
|
||||
int CpuSuspendIntr(u32* ictrl); //17(05,06,07,13,14,18,26)
|
||||
int CpuResumeIntr(u32 ictrl); //18(05,06,07,13,14,18,26)
|
||||
int QueryIntrContext(); //23(07,13)
|
||||
|
||||
#endif//__INTRMAN_H__
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
#ifndef __IOMAN_H__
|
||||
#define __IOMAN_H__
|
||||
|
||||
#define IOMAN_VER 0x102
|
||||
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
|
||||
struct ioman_FUNCS{
|
||||
int init(struct ioman_DRV *drv); //00
|
||||
void term(struct ioman_DRV *drv); //01
|
||||
int format(char *filename); //02
|
||||
int open(int fd, char *filename, int flag); //03
|
||||
int close(int fd); //04
|
||||
int read(int fd, void *buf, int nbyte); //05
|
||||
int write(int fd, void *buf, int nbyte); //06
|
||||
int lseek(int fd, int offset, int whence); //07
|
||||
int ioctl(int fd, int request, int arg); //08
|
||||
int remove(char *filename); //09
|
||||
int mkdir(char *filename); //10
|
||||
int rmdir(char *filename); //11
|
||||
int dopen(char *filename); //12
|
||||
int dclose(int fd); //13
|
||||
int dread(int fd, void *buf); //14
|
||||
int getstat(char *filename, void *buf); //15
|
||||
int chstat(char *filename, void *buf, unsigned int mask); //16
|
||||
};
|
||||
|
||||
struct ioman_DRV{ //struct fileio_driver from ps2lib
|
||||
char *driver; //+00
|
||||
int unk1; //+04
|
||||
int version; //+08
|
||||
char *description; //+0C
|
||||
struct ioman_FUNCS *f_list; //+10
|
||||
}; //=14
|
||||
|
||||
int open(char *filename, int flag); // 4(26)
|
||||
int close(int fd); // 5(26)
|
||||
int read(int fd, void *buf, long count); // 6(17,26)
|
||||
int write(int fd, void *buf, long count); // 7(17,26)
|
||||
int lseek(int fd, int offset, int whence); // 8(26)
|
||||
int ioctl(int fd, int request, int arg); // 9(26)
|
||||
int remove(char *filename); //10(26)
|
||||
int mkdir(char *filename); //11(26)
|
||||
int rmdir(char *filename); //12(26)
|
||||
int dopen(char *filename); //13(26)
|
||||
int dclose(int fd); //14(26)
|
||||
int dread(int fd, void *buf); //15(26)
|
||||
int getstat(char *filename, void *buf); //16(26)
|
||||
int chstat(char *filename, void *buf, unsigned int mask); //17(26)
|
||||
int format(char *filename); //18(26)
|
||||
int AddDrv(struct ioman_DRV *drv); //20(26)
|
||||
int DelDrv(char *device); //21(26)
|
||||
|
||||
#endif//__IOMAN_H__
|
||||
|
||||
#ifndef __IOMAN_H__
|
||||
#define __IOMAN_H__
|
||||
|
||||
#define IOMAN_VER 0x102
|
||||
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
|
||||
struct ioman_FUNCS{
|
||||
int init(struct ioman_DRV *drv); //00
|
||||
void term(struct ioman_DRV *drv); //01
|
||||
int format(char *filename); //02
|
||||
int open(int fd, char *filename, int flag); //03
|
||||
int close(int fd); //04
|
||||
int read(int fd, void *buf, int nbyte); //05
|
||||
int write(int fd, void *buf, int nbyte); //06
|
||||
int lseek(int fd, int offset, int whence); //07
|
||||
int ioctl(int fd, int request, int arg); //08
|
||||
int remove(char *filename); //09
|
||||
int mkdir(char *filename); //10
|
||||
int rmdir(char *filename); //11
|
||||
int dopen(char *filename); //12
|
||||
int dclose(int fd); //13
|
||||
int dread(int fd, void *buf); //14
|
||||
int getstat(char *filename, void *buf); //15
|
||||
int chstat(char *filename, void *buf, unsigned int mask); //16
|
||||
};
|
||||
|
||||
struct ioman_DRV{ //struct fileio_driver from ps2lib
|
||||
char *driver; //+00
|
||||
int unk1; //+04
|
||||
int version; //+08
|
||||
char *description; //+0C
|
||||
struct ioman_FUNCS *f_list; //+10
|
||||
}; //=14
|
||||
|
||||
int open(char *filename, int flag); // 4(26)
|
||||
int close(int fd); // 5(26)
|
||||
int read(int fd, void *buf, long count); // 6(17,26)
|
||||
int write(int fd, void *buf, long count); // 7(17,26)
|
||||
int lseek(int fd, int offset, int whence); // 8(26)
|
||||
int ioctl(int fd, int request, int arg); // 9(26)
|
||||
int remove(char *filename); //10(26)
|
||||
int mkdir(char *filename); //11(26)
|
||||
int rmdir(char *filename); //12(26)
|
||||
int dopen(char *filename); //13(26)
|
||||
int dclose(int fd); //14(26)
|
||||
int dread(int fd, void *buf); //15(26)
|
||||
int getstat(char *filename, void *buf); //16(26)
|
||||
int chstat(char *filename, void *buf, unsigned int mask); //17(26)
|
||||
int format(char *filename); //18(26)
|
||||
int AddDrv(struct ioman_DRV *drv); //20(26)
|
||||
int DelDrv(char *device); //21(26)
|
||||
|
||||
#endif//__IOMAN_H__
|
||||
|
||||
|
|
|
@ -1,89 +1,89 @@
|
|||
#ifndef __LOADCORE_H__
|
||||
#define __LOADCORE_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
#define LOADCORE_VER 0x101
|
||||
|
||||
typedef int (*func)();
|
||||
|
||||
#define VER(major, minor) ((((major) & 0xFF)<<8) + ((minor) & 0xFF))
|
||||
|
||||
#define MODULE_RESIDENT_END 0
|
||||
#define MODULE_NO_RESIDENT_END 1
|
||||
|
||||
struct func_stub {
|
||||
int jr_ra; //jump instruction
|
||||
int addiu0; //addiu zero, number
|
||||
};
|
||||
|
||||
// defined by irx.h in the sdk
|
||||
//#define IMPORT_MAGIC 0x41E00000
|
||||
//#define EXPORT_MAGIC 0x41C00000
|
||||
|
||||
#define FLAG_EXPORT_QUEUED 1
|
||||
#define FLAG_IMPORT_QUEUED 2
|
||||
|
||||
#define FLAG_NO_AUTO_LINK 1
|
||||
|
||||
#define INS_JR 2
|
||||
#define INS_ADDIU 9
|
||||
#define INS_JR_RA 0x03E00008
|
||||
#define INS_J 0x08000000
|
||||
|
||||
enum tag_BOOTUPCB_PRIO{
|
||||
BOOTUPCB_FIRST = 0,
|
||||
BOOTUPCB_RUN_UDNL = 1,
|
||||
BOOTUPCB_NORMAL = 2,
|
||||
BOOTUPCB_LAST = 3,
|
||||
BOOTUPCB_PRIORITIES
|
||||
} BOOTUPCB_PRIO;
|
||||
|
||||
struct import {
|
||||
u32 magic; //0x41E00000
|
||||
struct import *next;
|
||||
short version; //mjmi (mj=major, mi=minor version numbers)
|
||||
short flags; //=0
|
||||
char name[8];
|
||||
struct func_stub func[0]; //the last one is 0, 0 (i.e. nop, nop)
|
||||
};
|
||||
|
||||
struct export {
|
||||
u32 magic_link; //0x41C00000, prev
|
||||
struct export *next;
|
||||
short version; //mjmi (mj=major, mi=minor version numbers)
|
||||
short flags; //=0
|
||||
char name[8];
|
||||
func func[45]; //usually module entry point (allways?)
|
||||
// func1
|
||||
// func2
|
||||
// func3
|
||||
// funcs // more functions: the services provided my module
|
||||
};
|
||||
|
||||
struct bootmode {
|
||||
short unk0;
|
||||
char id;
|
||||
char len;
|
||||
int data[0];
|
||||
};
|
||||
|
||||
typedef struct boot_params {
|
||||
int ramMBSize; //+00/0 size of iop ram in megabytes (2 or 8)
|
||||
int bootInfo; //+04/1 ==QueryBootMode(KEY_IOPbootinfo)
|
||||
char* udnlString; //+08/2 points to the undl reboot string, NULL if no string
|
||||
u32 firstModuleAddr;//+0C/3 the load address of the first module (sysmem)
|
||||
int pos; //+10/4
|
||||
int size; //+14/5
|
||||
int numConfLines; //+18/6 number of lines in IOPBTCONF
|
||||
u32** moduleAddrs; //+1C/7 pointer to an array of addresses to load modules from
|
||||
} BOOT_PARAMS; //=20
|
||||
|
||||
void FlushIcache(); //4 (14)
|
||||
void FlushDcache(); //5 (14,21,26)
|
||||
int RegisterLibraryEntries(struct export*); //6 (05,06,07,13,14,17,18,28)
|
||||
u32* QueryBootMode(int code); //12(11,21,25,26,28)
|
||||
int loadcore_call20_registerFunc(int (*function)(int *, int), int a1, int *result);
|
||||
//20(28)
|
||||
|
||||
#endif//__LOADCORE_H__
|
||||
#ifndef __LOADCORE_H__
|
||||
#define __LOADCORE_H__
|
||||
|
||||
#include <tamtypes.h>
|
||||
|
||||
#define LOADCORE_VER 0x101
|
||||
|
||||
typedef int (*func)();
|
||||
|
||||
#define VER(major, minor) ((((major) & 0xFF)<<8) + ((minor) & 0xFF))
|
||||
|
||||
#define MODULE_RESIDENT_END 0
|
||||
#define MODULE_NO_RESIDENT_END 1
|
||||
|
||||
struct func_stub {
|
||||
int jr_ra; //jump instruction
|
||||
int addiu0; //addiu zero, number
|
||||
};
|
||||
|
||||
// defined by irx.h in the sdk
|
||||
//#define IMPORT_MAGIC 0x41E00000
|
||||
//#define EXPORT_MAGIC 0x41C00000
|
||||
|
||||
#define FLAG_EXPORT_QUEUED 1
|
||||
#define FLAG_IMPORT_QUEUED 2
|
||||
|
||||
#define FLAG_NO_AUTO_LINK 1
|
||||
|
||||
#define INS_JR 2
|
||||
#define INS_ADDIU 9
|
||||
#define INS_JR_RA 0x03E00008
|
||||
#define INS_J 0x08000000
|
||||
|
||||
enum tag_BOOTUPCB_PRIO{
|
||||
BOOTUPCB_FIRST = 0,
|
||||
BOOTUPCB_RUN_UDNL = 1,
|
||||
BOOTUPCB_NORMAL = 2,
|
||||
BOOTUPCB_LAST = 3,
|
||||
BOOTUPCB_PRIORITIES
|
||||
} BOOTUPCB_PRIO;
|
||||
|
||||
struct import {
|
||||
u32 magic; //0x41E00000
|
||||
struct import *next;
|
||||
short version; //mjmi (mj=major, mi=minor version numbers)
|
||||
short flags; //=0
|
||||
char name[8];
|
||||
struct func_stub func[0]; //the last one is 0, 0 (i.e. nop, nop)
|
||||
};
|
||||
|
||||
struct export {
|
||||
u32 magic_link; //0x41C00000, prev
|
||||
struct export *next;
|
||||
short version; //mjmi (mj=major, mi=minor version numbers)
|
||||
short flags; //=0
|
||||
char name[8];
|
||||
func func[45]; //usually module entry point (allways?)
|
||||
// func1
|
||||
// func2
|
||||
// func3
|
||||
// funcs // more functions: the services provided my module
|
||||
};
|
||||
|
||||
struct bootmode {
|
||||
short unk0;
|
||||
char id;
|
||||
char len;
|
||||
int data[0];
|
||||
};
|
||||
|
||||
typedef struct boot_params {
|
||||
int ramMBSize; //+00/0 size of iop ram in megabytes (2 or 8)
|
||||
int bootInfo; //+04/1 ==QueryBootMode(KEY_IOPbootinfo)
|
||||
char* udnlString; //+08/2 points to the undl reboot string, NULL if no string
|
||||
u32 firstModuleAddr;//+0C/3 the load address of the first module (sysmem)
|
||||
int pos; //+10/4
|
||||
int size; //+14/5
|
||||
int numConfLines; //+18/6 number of lines in IOPBTCONF
|
||||
u32** moduleAddrs; //+1C/7 pointer to an array of addresses to load modules from
|
||||
} BOOT_PARAMS; //=20
|
||||
|
||||
void FlushIcache(); //4 (14)
|
||||
void FlushDcache(); //5 (14,21,26)
|
||||
int RegisterLibraryEntries(struct export*); //6 (05,06,07,13,14,17,18,28)
|
||||
u32* QueryBootMode(int code); //12(11,21,25,26,28)
|
||||
int loadcore_call20_registerFunc(int (*function)(int *, int), int a1, int *result);
|
||||
//20(28)
|
||||
|
||||
#endif//__LOADCORE_H__
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue