mirror of https://github.com/PCSX2/pcsx2.git
gsdx-ogl-wnd: sync from trunk (r5550 to r5632)
Note: Code need to be fixed with latest GSdx ogl additions git-svn-id: http://pcsx2.googlecode.com/svn/branches/gsdx-ogl-wnd@5633 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
commit
b8e36b44af
|
@ -1,9 +1,9 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
|
/// FIR low-pass (anti-alias) filter with filter coefficient design routine and
|
||||||
/// MMX optimization.
|
/// MMX optimization.
|
||||||
///
|
///
|
||||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||||
/// transposing the sample rate with interpolation.
|
/// transposing the sample rate with interpolation.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-01-11 13:34:24 +0200 (Sun, 11 Jan 2009) $
|
// Last changed : $Date: 2009-01-11 09:34:24 -0200 (dom, 11 jan 2009) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
|
// $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
|
||||||
|
@ -112,21 +112,21 @@ void AAFilter::calculateCoeffs()
|
||||||
work = new double[length];
|
work = new double[length];
|
||||||
coeffs = new SAMPLETYPE[length];
|
coeffs = new SAMPLETYPE[length];
|
||||||
|
|
||||||
fc2 = 2.0 * cutoffFreq;
|
fc2 = 2.0 * cutoffFreq;
|
||||||
wc = PI * fc2;
|
wc = PI * fc2;
|
||||||
tempCoeff = TWOPI / (double)length;
|
tempCoeff = TWOPI / (double)length;
|
||||||
|
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (i = 0; i < length; i ++)
|
for (i = 0; i < length; i ++)
|
||||||
{
|
{
|
||||||
cntTemp = (double)i - (double)(length / 2);
|
cntTemp = (double)i - (double)(length / 2);
|
||||||
|
|
||||||
temp = cntTemp * wc;
|
temp = cntTemp * wc;
|
||||||
if (temp != 0)
|
if (temp != 0)
|
||||||
{
|
{
|
||||||
h = fc2 * sin(temp) / temp; // sinc function
|
h = fc2 * sin(temp) / temp; // sinc function
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
h = 1.0;
|
h = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,7 @@ void AAFilter::calculateCoeffs()
|
||||||
temp = w * h;
|
temp = w * h;
|
||||||
work[i] = temp;
|
work[i] = temp;
|
||||||
|
|
||||||
// calc net sum of coefficients
|
// calc net sum of coefficients
|
||||||
sum += temp;
|
sum += temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ void AAFilter::calculateCoeffs()
|
||||||
// divided by 16384
|
// divided by 16384
|
||||||
scaleCoeff = 16384.0f / sum;
|
scaleCoeff = 16384.0f / sum;
|
||||||
|
|
||||||
for (i = 0; i < length; i ++)
|
for (i = 0; i < length; i ++)
|
||||||
{
|
{
|
||||||
// scale & round to nearest integer
|
// scale & round to nearest integer
|
||||||
temp = work[i] * scaleCoeff;
|
temp = work[i] * scaleCoeff;
|
||||||
|
@ -169,8 +169,8 @@ void AAFilter::calculateCoeffs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Applies the filter to the given sequence of samples.
|
// Applies the filter to the given sequence of samples.
|
||||||
// Note : The amount of outputted samples is by value of 'filter length'
|
// Note : The amount of outputted samples is by value of 'filter length'
|
||||||
// smaller than the amount of input samples.
|
// smaller than the amount of input samples.
|
||||||
uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||||
/// with several performance-increasing tweaks.
|
/// with several performance-increasing tweaks.
|
||||||
///
|
///
|
||||||
/// Anti-alias filter is used to prevent folding of high frequencies when
|
/// Anti-alias filter is used to prevent folding of high frequencies when
|
||||||
/// transposing the sample rate with interpolation.
|
/// transposing the sample rate with interpolation.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
|
// Last changed : $Date: 2008-02-10 14:26:55 -0200 (dom, 10 fev 2008) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
|
// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
|
||||||
|
@ -67,8 +67,8 @@ public:
|
||||||
|
|
||||||
~AAFilter();
|
~AAFilter();
|
||||||
|
|
||||||
/// Sets new anti-alias filter cut-off edge frequency, scaled to sampling
|
/// Sets new anti-alias filter cut-off edge frequency, scaled to sampling
|
||||||
/// frequency (nyquist frequency = 0.5). The filter will cut off the
|
/// frequency (nyquist frequency = 0.5). The filter will cut off the
|
||||||
/// frequencies than that.
|
/// frequencies than that.
|
||||||
void setCutoffFreq(double newCutoffFreq);
|
void setCutoffFreq(double newCutoffFreq);
|
||||||
|
|
||||||
|
@ -77,12 +77,12 @@ public:
|
||||||
|
|
||||||
uint getLength() const;
|
uint getLength() const;
|
||||||
|
|
||||||
/// Applies the filter to the given sequence of samples.
|
/// Applies the filter to the given sequence of samples.
|
||||||
/// Note : The amount of outputted samples is by value of 'filter length'
|
/// Note : The amount of outputted samples is by value of 'filter length'
|
||||||
/// smaller than the amount of input samples.
|
/// smaller than the amount of input samples.
|
||||||
uint evaluate(SAMPLETYPE *dest,
|
uint evaluate(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples,
|
uint numSamples,
|
||||||
uint numChannels) const;
|
uint numChannels) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,370 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// 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.
|
||||||
|
/// - Inputted 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: 2012-08-30 16:45:25 -0300 (qui, 30 ago 2012) $
|
||||||
|
// File revision : $Revision: 4 $
|
||||||
|
//
|
||||||
|
// $Id: BPMDetect.cpp 149 2012-08-30 19:45:25Z oparviai $
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "FIFOSampleBuffer.h"
|
||||||
|
#include "PeakFinder.h"
|
||||||
|
#include "BPMDetect.h"
|
||||||
|
|
||||||
|
using namespace soundtouch;
|
||||||
|
|
||||||
|
#define INPUT_BLOCK_SAMPLES 2048
|
||||||
|
#define DECIMATED_BLOCK_SAMPLES 256
|
||||||
|
|
||||||
|
/// decay constant for calculating RMS volume sliding average approximation
|
||||||
|
/// (time constant is about 10 sec)
|
||||||
|
const float avgdecay = 0.99986f;
|
||||||
|
|
||||||
|
/// Normalization coefficient for calculating RMS sliding average approximation.
|
||||||
|
const float avgnorm = (1 - avgdecay);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Enable following define to create bpm analysis file:
|
||||||
|
|
||||||
|
// #define _CREATE_BPM_DEBUG_FILE
|
||||||
|
|
||||||
|
#ifdef _CREATE_BPM_DEBUG_FILE
|
||||||
|
|
||||||
|
#define DEBUGFILE_NAME "c:\\temp\\soundtouch-bpm-debug.txt"
|
||||||
|
|
||||||
|
static void _SaveDebugData(const float *data, int minpos, int maxpos, double coeff)
|
||||||
|
{
|
||||||
|
FILE *fptr = fopen(DEBUGFILE_NAME, "wt");
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (fptr)
|
||||||
|
{
|
||||||
|
printf("\n\nWriting BPM debug data into file " DEBUGFILE_NAME "\n\n");
|
||||||
|
for (i = minpos; i < maxpos; i ++)
|
||||||
|
{
|
||||||
|
fprintf(fptr, "%d\t%.1lf\t%f\n", i, coeff / (double)i, data[i]);
|
||||||
|
}
|
||||||
|
fclose(fptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define _SaveDebugData(a,b,c,d)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
BPMDetect::BPMDetect(int numChannels, int aSampleRate)
|
||||||
|
{
|
||||||
|
this->sampleRate = aSampleRate;
|
||||||
|
this->channels = numChannels;
|
||||||
|
|
||||||
|
decimateSum = 0;
|
||||||
|
decimateCount = 0;
|
||||||
|
|
||||||
|
envelopeAccu = 0;
|
||||||
|
|
||||||
|
// Initialize RMS volume accumulator to RMS level of 1500 (out of 32768) that's
|
||||||
|
// safe initial RMS signal level value for song data. This value is then adapted
|
||||||
|
// to the actual level during processing.
|
||||||
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
// integer samples
|
||||||
|
RMSVolumeAccu = (1500 * 1500) / avgnorm;
|
||||||
|
#else
|
||||||
|
// float samples, scaled to range [-1..+1[
|
||||||
|
RMSVolumeAccu = (0.045f * 0.045f) / avgnorm;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// choose decimation factor so that result is approx. 1000 Hz
|
||||||
|
decimateBy = sampleRate / 1000;
|
||||||
|
assert(decimateBy > 0);
|
||||||
|
assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
|
||||||
|
|
||||||
|
// Calculate window length & starting item according to desired min & max bpms
|
||||||
|
windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
|
||||||
|
windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
|
||||||
|
|
||||||
|
assert(windowLen > windowStart);
|
||||||
|
|
||||||
|
// allocate new working objects
|
||||||
|
xcorr = new float[windowLen];
|
||||||
|
memset(xcorr, 0, windowLen * sizeof(float));
|
||||||
|
|
||||||
|
// allocate processing buffer
|
||||||
|
buffer = new FIFOSampleBuffer();
|
||||||
|
// we do processing in mono mode
|
||||||
|
buffer->setChannels(1);
|
||||||
|
buffer->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BPMDetect::~BPMDetect()
|
||||||
|
{
|
||||||
|
delete[] xcorr;
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// convert to mono, low-pass filter & decimate to about 500 Hz.
|
||||||
|
/// return number of outputted samples.
|
||||||
|
///
|
||||||
|
/// Decimation is used to remove the unnecessary frequencies and thus to reduce
|
||||||
|
/// the amount of data needed to be processed as calculating autocorrelation
|
||||||
|
/// function is a very-very heavy operation.
|
||||||
|
///
|
||||||
|
/// Anti-alias filtering is done simply by averaging the samples. This is really a
|
||||||
|
/// poor-man's anti-alias filtering, but it's not so critical in this kind of application
|
||||||
|
/// (it'd also be difficult to design a high-quality filter with steep cut-off at very
|
||||||
|
/// narrow band)
|
||||||
|
int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
|
||||||
|
{
|
||||||
|
int count, outcount;
|
||||||
|
LONG_SAMPLETYPE out;
|
||||||
|
|
||||||
|
assert(channels > 0);
|
||||||
|
assert(decimateBy > 0);
|
||||||
|
outcount = 0;
|
||||||
|
for (count = 0; count < numsamples; count ++)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
|
||||||
|
// convert to mono and accumulate
|
||||||
|
for (j = 0; j < channels; j ++)
|
||||||
|
{
|
||||||
|
decimateSum += src[j];
|
||||||
|
}
|
||||||
|
src += j;
|
||||||
|
|
||||||
|
decimateCount ++;
|
||||||
|
if (decimateCount >= decimateBy)
|
||||||
|
{
|
||||||
|
// Store every Nth sample only
|
||||||
|
out = (LONG_SAMPLETYPE)(decimateSum / (decimateBy * channels));
|
||||||
|
decimateSum = 0;
|
||||||
|
decimateCount = 0;
|
||||||
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
// check ranges for sure (shouldn't actually be necessary)
|
||||||
|
if (out > 32767)
|
||||||
|
{
|
||||||
|
out = 32767;
|
||||||
|
}
|
||||||
|
else if (out < -32768)
|
||||||
|
{
|
||||||
|
out = -32768;
|
||||||
|
}
|
||||||
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
dest[outcount] = (SAMPLETYPE)out;
|
||||||
|
outcount ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return outcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Calculates autocorrelation function of the sample history buffer
|
||||||
|
void BPMDetect::updateXCorr(int process_samples)
|
||||||
|
{
|
||||||
|
int offs;
|
||||||
|
SAMPLETYPE *pBuffer;
|
||||||
|
|
||||||
|
assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
|
||||||
|
|
||||||
|
pBuffer = buffer->ptrBegin();
|
||||||
|
for (offs = windowStart; offs < windowLen; offs ++)
|
||||||
|
{
|
||||||
|
LONG_SAMPLETYPE sum;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
for (i = 0; i < process_samples; i ++)
|
||||||
|
{
|
||||||
|
sum += pBuffer[i] * pBuffer[i + offs]; // scaling the sub-result shouldn't be necessary
|
||||||
|
}
|
||||||
|
// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients
|
||||||
|
// if it's desired that the system adapts automatically to
|
||||||
|
// various bpms, e.g. in processing continouos music stream.
|
||||||
|
// The 'xcorr_decay' should be a value that's smaller than but
|
||||||
|
// close to one, and should also depend on 'process_samples' value.
|
||||||
|
|
||||||
|
xcorr[offs] += (float)sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculates envelope of the sample data
|
||||||
|
void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples)
|
||||||
|
{
|
||||||
|
const static double decay = 0.7f; // decay constant for smoothing the envelope
|
||||||
|
const static double norm = (1 - decay);
|
||||||
|
|
||||||
|
int i;
|
||||||
|
LONG_SAMPLETYPE out;
|
||||||
|
double val;
|
||||||
|
|
||||||
|
for (i = 0; i < numsamples; i ++)
|
||||||
|
{
|
||||||
|
// calc average RMS volume
|
||||||
|
RMSVolumeAccu *= avgdecay;
|
||||||
|
val = (float)fabs((float)samples[i]);
|
||||||
|
RMSVolumeAccu += val * val;
|
||||||
|
|
||||||
|
// cut amplitudes that are below cutoff ~2 times RMS volume
|
||||||
|
// (we're interested in peak values, not the silent moments)
|
||||||
|
if (val < 0.5 * sqrt(RMSVolumeAccu * avgnorm))
|
||||||
|
{
|
||||||
|
val = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// smooth amplitude envelope
|
||||||
|
envelopeAccu *= decay;
|
||||||
|
envelopeAccu += val;
|
||||||
|
out = (LONG_SAMPLETYPE)(envelopeAccu * norm);
|
||||||
|
|
||||||
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
// cut peaks (shouldn't be necessary though)
|
||||||
|
if (out > 32767) out = 32767;
|
||||||
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
samples[i] = (SAMPLETYPE)out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void BPMDetect::inputSamples(const SAMPLETYPE *samples, int numSamples)
|
||||||
|
{
|
||||||
|
SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
|
||||||
|
|
||||||
|
// iterate so that max INPUT_BLOCK_SAMPLES processed per iteration
|
||||||
|
while (numSamples > 0)
|
||||||
|
{
|
||||||
|
int block;
|
||||||
|
int decSamples;
|
||||||
|
|
||||||
|
block = (numSamples > INPUT_BLOCK_SAMPLES) ? INPUT_BLOCK_SAMPLES : numSamples;
|
||||||
|
|
||||||
|
// decimate. note that converts to mono at the same time
|
||||||
|
decSamples = decimate(decimated, samples, block);
|
||||||
|
samples += block * channels;
|
||||||
|
numSamples -= block;
|
||||||
|
|
||||||
|
// envelope new samples and add them to buffer
|
||||||
|
calcEnvelope(decimated, decSamples);
|
||||||
|
buffer->putSamples(decimated, decSamples);
|
||||||
|
}
|
||||||
|
|
||||||
|
// when the buffer has enought samples for processing...
|
||||||
|
if ((int)buffer->numSamples() > windowLen)
|
||||||
|
{
|
||||||
|
int processLength;
|
||||||
|
|
||||||
|
// how many samples are processed
|
||||||
|
processLength = (int)buffer->numSamples() - windowLen;
|
||||||
|
|
||||||
|
// ... calculate autocorrelations for oldest samples...
|
||||||
|
updateXCorr(processLength);
|
||||||
|
// ... and remove them from the buffer
|
||||||
|
buffer->receiveSamples(processLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void BPMDetect::removeBias()
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float minval = 1e12f; // arbitrary large number
|
||||||
|
|
||||||
|
for (i = windowStart; i < windowLen; i ++)
|
||||||
|
{
|
||||||
|
if (xcorr[i] < minval)
|
||||||
|
{
|
||||||
|
minval = xcorr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = windowStart; i < windowLen; i ++)
|
||||||
|
{
|
||||||
|
xcorr[i] -= minval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float BPMDetect::getBpm()
|
||||||
|
{
|
||||||
|
double peakPos;
|
||||||
|
double coeff;
|
||||||
|
PeakFinder peakFinder;
|
||||||
|
|
||||||
|
coeff = 60.0 * ((double)sampleRate / (double)decimateBy);
|
||||||
|
|
||||||
|
// save bpm debug analysis data if debug data enabled
|
||||||
|
_SaveDebugData(xcorr, windowStart, windowLen, coeff);
|
||||||
|
|
||||||
|
// remove bias from xcorr data
|
||||||
|
removeBias();
|
||||||
|
|
||||||
|
// find peak position
|
||||||
|
peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen);
|
||||||
|
|
||||||
|
assert(decimateBy != 0);
|
||||||
|
if (peakPos < 1e-9) return 0.0; // detection failed.
|
||||||
|
|
||||||
|
// calculate BPM
|
||||||
|
return (float) (coeff / peakPos);
|
||||||
|
}
|
|
@ -14,10 +14,10 @@
|
||||||
/// taking absolute value that's smoothed by sliding average. Signal levels that
|
/// 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
|
/// are below a couple of times the general RMS amplitude level are cut away to
|
||||||
/// leave only notable peaks there.
|
/// leave only notable peaks there.
|
||||||
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
|
/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term
|
||||||
/// autocorrelation function of the enveloped signal.
|
/// autocorrelation function of the enveloped signal.
|
||||||
/// - After whole sound data file has been analyzed as above, the bpm level is
|
/// - 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
|
/// 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.
|
/// function, calculates it's precise location and converts this reading to bpm's.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -26,10 +26,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
|
// Last changed : $Date: 2012-08-30 16:53:44 -0300 (qui, 30 ago 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: BPMDetect.h 63 2009-02-21 16:00:14Z oparviai $
|
// $Id: BPMDetect.h 150 2012-08-30 19:53:44Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -67,7 +67,7 @@ namespace soundtouch
|
||||||
#define MIN_BPM 29
|
#define MIN_BPM 29
|
||||||
|
|
||||||
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
|
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
|
||||||
#define MAX_BPM 230
|
#define MAX_BPM 200
|
||||||
|
|
||||||
|
|
||||||
/// Class for calculating BPM rate for audio data.
|
/// Class for calculating BPM rate for audio data.
|
||||||
|
@ -76,12 +76,12 @@ class BPMDetect
|
||||||
protected:
|
protected:
|
||||||
/// Auto-correlation accumulator bins.
|
/// Auto-correlation accumulator bins.
|
||||||
float *xcorr;
|
float *xcorr;
|
||||||
|
|
||||||
/// Amplitude envelope sliding average approximation level accumulator
|
/// Amplitude envelope sliding average approximation level accumulator
|
||||||
float envelopeAccu;
|
double envelopeAccu;
|
||||||
|
|
||||||
/// RMS volume sliding average approximation level accumulator
|
/// RMS volume sliding average approximation level accumulator
|
||||||
float RMSVolumeAccu;
|
double RMSVolumeAccu;
|
||||||
|
|
||||||
/// Sample average counter.
|
/// Sample average counter.
|
||||||
int decimateCount;
|
int decimateCount;
|
||||||
|
@ -104,12 +104,12 @@ protected:
|
||||||
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
/// Beginning of auto-correlation window: Autocorrelation isn't being updated for
|
||||||
/// the first these many correlation bins.
|
/// the first these many correlation bins.
|
||||||
int windowStart;
|
int windowStart;
|
||||||
|
|
||||||
/// FIFO-buffer for decimated processing samples.
|
/// FIFO-buffer for decimated processing samples.
|
||||||
soundtouch::FIFOSampleBuffer *buffer;
|
soundtouch::FIFOSampleBuffer *buffer;
|
||||||
|
|
||||||
/// Updates auto-correlation function for given number of decimated samples that
|
/// 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
|
/// are read from the internal 'buffer' pipe (samples aren't removed from the pipe
|
||||||
/// though).
|
/// though).
|
||||||
void updateXCorr(int process_samples /// How many samples are processed.
|
void updateXCorr(int process_samples /// How many samples are processed.
|
||||||
);
|
);
|
||||||
|
@ -128,6 +128,9 @@ protected:
|
||||||
int numsamples ///< Number of samples in buffer
|
int numsamples ///< Number of samples in buffer
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// remove constant bias from xcorr data
|
||||||
|
void removeBias();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
BPMDetect(int numChannels, ///< Number of channels in sample data.
|
||||||
|
@ -139,9 +142,9 @@ public:
|
||||||
|
|
||||||
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
/// Inputs a block of samples for analyzing: Envelopes the samples and then
|
||||||
/// updates the autocorrelation estimation. When whole song data has been input
|
/// updates the autocorrelation estimation. When whole song data has been input
|
||||||
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
/// in smaller blocks using this function, read the resulting bpm with 'getBpm'
|
||||||
/// function.
|
/// function.
|
||||||
///
|
///
|
||||||
/// Notice that data in 'samples' array can be disrupted in processing.
|
/// Notice that data in 'samples' array can be disrupted in processing.
|
||||||
void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
void inputSamples(const soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer
|
||||||
int numSamples ///< Number of samples in buffer
|
int numSamples ///< Number of samples in buffer
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||||
/// first-in-first-out pipe.
|
/// first-in-first-out pipe.
|
||||||
///
|
///
|
||||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
/// 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
|
/// function, and are received from the beginning of the buffer by calling
|
||||||
/// the 'receiveSamples' function. The class automatically removes the
|
/// the 'receiveSamples' function. The class automatically removes the
|
||||||
/// outputted samples from the buffer, as well as grows the buffer size
|
/// outputted samples from the buffer, as well as grows the buffer size
|
||||||
/// whenever necessary.
|
/// whenever necessary.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-27 19:24:42 +0200 (Fri, 27 Feb 2009) $
|
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: FIFOSampleBuffer.cpp 68 2009-02-27 17:24:42Z oparviai $
|
// $Id: FIFOSampleBuffer.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -47,7 +47,6 @@
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "FIFOSampleBuffer.h"
|
#include "FIFOSampleBuffer.h"
|
||||||
|
|
||||||
|
@ -63,7 +62,7 @@ FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
|
||||||
samplesInBuffer = 0;
|
samplesInBuffer = 0;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
channels = (uint)numChannels;
|
channels = (uint)numChannels;
|
||||||
ensureCapacity(32); // allocate initial capacity
|
ensureCapacity(32); // allocate initial capacity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,11 +88,11 @@ void FIFOSampleBuffer::setChannels(int numChannels)
|
||||||
|
|
||||||
|
|
||||||
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
|
// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and
|
||||||
// zeroes this pointer by copying samples from the 'bufferPos' pointer
|
// zeroes this pointer by copying samples from the 'bufferPos' pointer
|
||||||
// location on to the beginning of the buffer.
|
// location on to the beginning of the buffer.
|
||||||
void FIFOSampleBuffer::rewind()
|
void FIFOSampleBuffer::rewind()
|
||||||
{
|
{
|
||||||
if (buffer && bufferPos)
|
if (buffer && bufferPos)
|
||||||
{
|
{
|
||||||
memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
|
memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
|
@ -101,7 +100,7 @@ void FIFOSampleBuffer::rewind()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
// Adds 'numSamples' pcs of samples from the 'samples' memory position to
|
||||||
// the sample buffer.
|
// the sample buffer.
|
||||||
void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||||
{
|
{
|
||||||
|
@ -114,7 +113,7 @@ void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||||
// samples.
|
// samples.
|
||||||
//
|
//
|
||||||
// This function is used to update the number of samples in the sample buffer
|
// This function is used to update the number of samples in the sample buffer
|
||||||
// when accessing the buffer directly with 'ptrEnd' function. Please be
|
// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||||
// careful though!
|
// careful though!
|
||||||
void FIFOSampleBuffer::putSamples(uint nSamples)
|
void FIFOSampleBuffer::putSamples(uint nSamples)
|
||||||
{
|
{
|
||||||
|
@ -126,31 +125,31 @@ void FIFOSampleBuffer::putSamples(uint nSamples)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
// 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
|
// 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!
|
// inserting new samples into the sample buffer directly. Please be careful!
|
||||||
//
|
//
|
||||||
// Parameter 'slackCapacity' tells the function how much free capacity (in
|
// Parameter 'slackCapacity' tells the function how much free capacity (in
|
||||||
// terms of samples) there _at least_ should be, in order to the caller to
|
// 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,
|
// succesfully insert all the required samples to the buffer. When necessary,
|
||||||
// the function grows the buffer size to comply with this requirement.
|
// the function grows the buffer size to comply with this requirement.
|
||||||
//
|
//
|
||||||
// When using this function as means for inserting new samples, also remember
|
// When using this function as means for inserting new samples, also remember
|
||||||
// to increase the sample count afterwards, by calling the
|
// to increase the sample count afterwards, by calling the
|
||||||
// 'putSamples(numSamples)' function.
|
// 'putSamples(numSamples)' function.
|
||||||
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
|
SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity)
|
||||||
{
|
{
|
||||||
ensureCapacity(samplesInBuffer + slackCapacity);
|
ensureCapacity(samplesInBuffer + slackCapacity);
|
||||||
return buffer + samplesInBuffer * channels;
|
return buffer + samplesInBuffer * channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Returns a pointer to the beginning of the currently non-outputted samples.
|
// Returns a pointer to the beginning of the currently non-outputted samples.
|
||||||
// This function is provided for accessing the output samples directly.
|
// This function is provided for accessing the output samples directly.
|
||||||
// Please be careful!
|
// Please be careful!
|
||||||
//
|
//
|
||||||
// When using this function to output samples, also remember to 'remove' the
|
// When using this function to output samples, also remember to 'remove' the
|
||||||
// outputted samples from the buffer by calling the
|
// outputted samples from the buffer by calling the
|
||||||
// 'receiveSamples(numSamples)' function
|
// 'receiveSamples(numSamples)' function
|
||||||
SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
|
SAMPLETYPE *FIFOSampleBuffer::ptrBegin()
|
||||||
{
|
{
|
||||||
|
@ -167,7 +166,7 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||||
{
|
{
|
||||||
SAMPLETYPE *tempUnaligned, *temp;
|
SAMPLETYPE *tempUnaligned, *temp;
|
||||||
|
|
||||||
if (capacityRequirement > getCapacity())
|
if (capacityRequirement > getCapacity())
|
||||||
{
|
{
|
||||||
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
|
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
|
||||||
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
|
sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-4096;
|
||||||
|
@ -175,10 +174,10 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||||
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)];
|
||||||
if (tempUnaligned == NULL)
|
if (tempUnaligned == NULL)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Couldn't allocate memory!\n");
|
ST_THROW_RT_ERROR("Couldn't allocate memory!\n");
|
||||||
}
|
}
|
||||||
// Align the buffer to begin at 16byte cache line boundary for optimal performance
|
// Align the buffer to begin at 16byte cache line boundary for optimal performance
|
||||||
temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16);
|
temp = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(tempUnaligned);
|
||||||
if (samplesInBuffer)
|
if (samplesInBuffer)
|
||||||
{
|
{
|
||||||
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
|
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
|
||||||
|
@ -187,8 +186,8 @@ void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement)
|
||||||
buffer = temp;
|
buffer = temp;
|
||||||
bufferUnaligned = tempUnaligned;
|
bufferUnaligned = tempUnaligned;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// simply rewind the buffer (if necessary)
|
// simply rewind the buffer (if necessary)
|
||||||
rewind();
|
rewind();
|
||||||
|
@ -260,3 +259,16 @@ void FIFOSampleBuffer::clear()
|
||||||
samplesInBuffer = 0;
|
samplesInBuffer = 0;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// allow trimming (downwards) amount of samples in pipeline.
|
||||||
|
/// Returns adjusted amount of samples
|
||||||
|
uint FIFOSampleBuffer::adjustAmountOfSamples(uint numSamples)
|
||||||
|
{
|
||||||
|
if (numSamples < samplesInBuffer)
|
||||||
|
{
|
||||||
|
samplesInBuffer = numSamples;
|
||||||
|
}
|
||||||
|
return samplesInBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// A buffer class for temporarily storaging sound samples, operates as a
|
/// A buffer class for temporarily storaging sound samples, operates as a
|
||||||
/// first-in-first-out pipe.
|
/// first-in-first-out pipe.
|
||||||
///
|
///
|
||||||
/// Samples are added to the end of the sample buffer with the 'putSamples'
|
/// 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
|
/// function, and are received from the beginning of the buffer by calling
|
||||||
/// the 'receiveSamples' function. The class automatically removes the
|
/// the 'receiveSamples' function. The class automatically removes the
|
||||||
/// output samples from the buffer as well as grows the storage size
|
/// output samples from the buffer as well as grows the storage size
|
||||||
/// whenever necessary.
|
/// whenever necessary.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -15,10 +15,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
|
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: FIFOSampleBuffer.h 63 2009-02-21 16:00:14Z oparviai $
|
// $Id: FIFOSampleBuffer.h 143 2012-06-13 19:29:53Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -54,7 +54,7 @@ namespace soundtouch
|
||||||
/// Sample buffer working in FIFO (first-in-first-out) principle. The class takes
|
/// 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.
|
/// 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
|
/// Notice that in case of stereo audio, one sample is considered to consist of
|
||||||
/// both channel data.
|
/// both channel data.
|
||||||
class FIFOSampleBuffer : public FIFOSamplePipe
|
class FIFOSampleBuffer : public FIFOSamplePipe
|
||||||
{
|
{
|
||||||
|
@ -75,12 +75,12 @@ private:
|
||||||
/// Channels, 1=mono, 2=stereo.
|
/// Channels, 1=mono, 2=stereo.
|
||||||
uint channels;
|
uint channels;
|
||||||
|
|
||||||
/// Current position pointer to the buffer. This pointer is increased when samples are
|
/// 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)
|
/// removed from the pipe so that it's necessary to actually rewind buffer (move data)
|
||||||
/// only new data when is put to the pipe.
|
/// only new data when is put to the pipe.
|
||||||
uint bufferPos;
|
uint bufferPos;
|
||||||
|
|
||||||
/// Rewind the buffer by moving data from position pointed by 'bufferPos' to real
|
/// Rewind the buffer by moving data from position pointed by 'bufferPos' to real
|
||||||
/// beginning of the buffer.
|
/// beginning of the buffer.
|
||||||
void rewind();
|
void rewind();
|
||||||
|
|
||||||
|
@ -100,27 +100,27 @@ public:
|
||||||
/// destructor
|
/// destructor
|
||||||
~FIFOSampleBuffer();
|
~FIFOSampleBuffer();
|
||||||
|
|
||||||
/// Returns a pointer to the beginning of the output samples.
|
/// Returns a pointer to the beginning of the output samples.
|
||||||
/// This function is provided for accessing the output samples directly.
|
/// This function is provided for accessing the output samples directly.
|
||||||
/// Please be careful for not to corrupt the book-keeping!
|
/// Please be careful for not to corrupt the book-keeping!
|
||||||
///
|
///
|
||||||
/// When using this function to output samples, also remember to 'remove' the
|
/// When using this function to output samples, also remember to 'remove' the
|
||||||
/// output samples from the buffer by calling the
|
/// output samples from the buffer by calling the
|
||||||
/// 'receiveSamples(numSamples)' function
|
/// 'receiveSamples(numSamples)' function
|
||||||
virtual SAMPLETYPE *ptrBegin();
|
virtual SAMPLETYPE *ptrBegin();
|
||||||
|
|
||||||
/// Returns a pointer to the end of the used part of the sample buffer (i.e.
|
/// 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
|
/// 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
|
/// inserting new samples into the sample buffer directly. Please be careful
|
||||||
/// not corrupt the book-keeping!
|
/// not corrupt the book-keeping!
|
||||||
///
|
///
|
||||||
/// When using this function as means for inserting new samples, also remember
|
/// When using this function as means for inserting new samples, also remember
|
||||||
/// to increase the sample count afterwards, by calling the
|
/// to increase the sample count afterwards, by calling the
|
||||||
/// 'putSamples(numSamples)' function.
|
/// 'putSamples(numSamples)' function.
|
||||||
SAMPLETYPE *ptrEnd(
|
SAMPLETYPE *ptrEnd(
|
||||||
uint slackCapacity ///< How much free capacity (in samples) there _at least_
|
uint slackCapacity ///< How much free capacity (in samples) there _at least_
|
||||||
///< should be so that the caller can succesfully insert the
|
///< should be so that the caller can succesfully insert the
|
||||||
///< desired samples to the buffer. If necessary, the function
|
///< desired samples to the buffer. If necessary, the function
|
||||||
///< grows the buffer size to comply with this requirement.
|
///< grows the buffer size to comply with this requirement.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -130,17 +130,17 @@ public:
|
||||||
uint numSamples ///< Number of samples to insert.
|
uint numSamples ///< Number of samples to insert.
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adjusts the book-keeping to increase number of samples in the buffer without
|
/// Adjusts the book-keeping to increase number of samples in the buffer without
|
||||||
/// copying any actual samples.
|
/// copying any actual samples.
|
||||||
///
|
///
|
||||||
/// This function is used to update the number of samples in the sample buffer
|
/// This function is used to update the number of samples in the sample buffer
|
||||||
/// when accessing the buffer directly with 'ptrEnd' function. Please be
|
/// when accessing the buffer directly with 'ptrEnd' function. Please be
|
||||||
/// careful though!
|
/// careful though!
|
||||||
virtual void putSamples(uint numSamples ///< Number of samples been inserted.
|
virtual void putSamples(uint numSamples ///< Number of samples been inserted.
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
/// 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
|
/// output buffer and removes them from the sample buffer. If there are less than
|
||||||
/// 'numsample' samples in the buffer, returns all that available.
|
/// 'numsample' samples in the buffer, returns all that available.
|
||||||
///
|
///
|
||||||
/// \return Number of samples returned.
|
/// \return Number of samples returned.
|
||||||
|
@ -148,8 +148,8 @@ public:
|
||||||
uint maxSamples ///< How many samples to receive at max.
|
uint maxSamples ///< How many samples to receive at max.
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||||
/// sample buffer without copying them anywhere.
|
/// sample buffer without copying them anywhere.
|
||||||
///
|
///
|
||||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||||
/// with 'ptrBegin' function.
|
/// with 'ptrBegin' function.
|
||||||
|
@ -167,6 +167,10 @@ public:
|
||||||
|
|
||||||
/// Clears all the samples.
|
/// Clears all the samples.
|
||||||
virtual void clear();
|
virtual void clear();
|
||||||
|
|
||||||
|
/// allow trimming (downwards) amount of samples in pipeline.
|
||||||
|
/// Returns adjusted amount of samples
|
||||||
|
uint adjustAmountOfSamples(uint numSamples);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
/// into one end of the pipe with the 'putSamples' function, and the processed
|
/// into one end of the pipe with the 'putSamples' function, and the processed
|
||||||
/// samples are received from the other end with the 'receiveSamples' function.
|
/// samples are received from the other end with the 'receiveSamples' function.
|
||||||
///
|
///
|
||||||
/// 'FIFOProcessor' : A base class for classes the do signal processing with
|
/// 'FIFOProcessor' : A base class for classes the do signal processing with
|
||||||
/// the samples while operating like a first-in-first-out pipe. When samples
|
/// the samples while operating like a first-in-first-out pipe. When samples
|
||||||
/// are input with the 'putSamples' function, the class processes them
|
/// are input with the 'putSamples' function, the class processes them
|
||||||
/// and moves the processed samples to the given 'output' pipe object, which
|
/// and moves the processed samples to the given 'output' pipe object, which
|
||||||
|
@ -17,10 +17,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-04-13 16:18:48 +0300 (Mon, 13 Apr 2009) $
|
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: FIFOSamplePipe.h 69 2009-04-13 13:18:48Z oparviai $
|
// $Id: FIFOSamplePipe.h 143 2012-06-13 19:29:53Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -63,12 +63,12 @@ public:
|
||||||
virtual ~FIFOSamplePipe() {}
|
virtual ~FIFOSamplePipe() {}
|
||||||
|
|
||||||
|
|
||||||
/// Returns a pointer to the beginning of the output samples.
|
/// Returns a pointer to the beginning of the output samples.
|
||||||
/// This function is provided for accessing the output samples directly.
|
/// This function is provided for accessing the output samples directly.
|
||||||
/// Please be careful for not to corrupt the book-keeping!
|
/// Please be careful for not to corrupt the book-keeping!
|
||||||
///
|
///
|
||||||
/// When using this function to output samples, also remember to 'remove' the
|
/// When using this function to output samples, also remember to 'remove' the
|
||||||
/// output samples from the buffer by calling the
|
/// output samples from the buffer by calling the
|
||||||
/// 'receiveSamples(numSamples)' function
|
/// 'receiveSamples(numSamples)' function
|
||||||
virtual SAMPLETYPE *ptrBegin() = 0;
|
virtual SAMPLETYPE *ptrBegin() = 0;
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ public:
|
||||||
other.receiveSamples(oNumSamples);
|
other.receiveSamples(oNumSamples);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
/// 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
|
/// output buffer and removes them from the sample buffer. If there are less than
|
||||||
/// 'numsample' samples in the buffer, returns all that available.
|
/// 'numsample' samples in the buffer, returns all that available.
|
||||||
///
|
///
|
||||||
/// \return Number of samples returned.
|
/// \return Number of samples returned.
|
||||||
|
@ -98,8 +98,8 @@ public:
|
||||||
uint maxSamples ///< How many samples to receive at max.
|
uint maxSamples ///< How many samples to receive at max.
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||||
/// sample buffer without copying them anywhere.
|
/// sample buffer without copying them anywhere.
|
||||||
///
|
///
|
||||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||||
/// with 'ptrBegin' function.
|
/// with 'ptrBegin' function.
|
||||||
|
@ -114,16 +114,21 @@ public:
|
||||||
|
|
||||||
/// Clears all the samples.
|
/// Clears all the samples.
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
|
/// allow trimming (downwards) amount of samples in pipeline.
|
||||||
|
/// Returns adjusted amount of samples
|
||||||
|
virtual uint adjustAmountOfSamples(uint numSamples) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Base-class for sound processing routines working in FIFO principle. With this base
|
/// 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,
|
/// 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
|
/// so that samples that are fed into beginning of the pipe automatically go through
|
||||||
/// all the processing stages.
|
/// all the processing stages.
|
||||||
///
|
///
|
||||||
/// When samples are input to this class, they're first processed and then put to
|
/// 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
|
/// 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.
|
/// either other processing stage or a FIFO sample buffer.
|
||||||
class FIFOProcessor :public FIFOSamplePipe
|
class FIFOProcessor :public FIFOSamplePipe
|
||||||
|
@ -141,7 +146,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Constructor. Doesn't define output pipe; it has to be set be
|
/// Constructor. Doesn't define output pipe; it has to be set be
|
||||||
/// 'setOutPipe' function.
|
/// 'setOutPipe' function.
|
||||||
FIFOProcessor()
|
FIFOProcessor()
|
||||||
{
|
{
|
||||||
|
@ -163,12 +168,12 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns a pointer to the beginning of the output samples.
|
/// Returns a pointer to the beginning of the output samples.
|
||||||
/// This function is provided for accessing the output samples directly.
|
/// This function is provided for accessing the output samples directly.
|
||||||
/// Please be careful for not to corrupt the book-keeping!
|
/// Please be careful for not to corrupt the book-keeping!
|
||||||
///
|
///
|
||||||
/// When using this function to output samples, also remember to 'remove' the
|
/// When using this function to output samples, also remember to 'remove' the
|
||||||
/// output samples from the buffer by calling the
|
/// output samples from the buffer by calling the
|
||||||
/// 'receiveSamples(numSamples)' function
|
/// 'receiveSamples(numSamples)' function
|
||||||
virtual SAMPLETYPE *ptrBegin()
|
virtual SAMPLETYPE *ptrBegin()
|
||||||
{
|
{
|
||||||
|
@ -177,8 +182,8 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Output samples from beginning of the sample buffer. Copies requested samples to
|
/// 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
|
/// output buffer and removes them from the sample buffer. If there are less than
|
||||||
/// 'numsample' samples in the buffer, returns all that available.
|
/// 'numsample' samples in the buffer, returns all that available.
|
||||||
///
|
///
|
||||||
/// \return Number of samples returned.
|
/// \return Number of samples returned.
|
||||||
|
@ -190,8 +195,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
/// Adjusts book-keeping so that given number of samples are removed from beginning of the
|
||||||
/// sample buffer without copying them anywhere.
|
/// sample buffer without copying them anywhere.
|
||||||
///
|
///
|
||||||
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
/// Used to reduce the number of samples in the buffer when accessing the sample buffer directly
|
||||||
/// with 'ptrBegin' function.
|
/// with 'ptrBegin' function.
|
||||||
|
@ -214,6 +219,14 @@ public:
|
||||||
{
|
{
|
||||||
return output->isEmpty();
|
return output->isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// allow trimming (downwards) amount of samples in pipeline.
|
||||||
|
/// Returns adjusted amount of samples
|
||||||
|
virtual uint adjustAmountOfSamples(uint numSamples)
|
||||||
|
{
|
||||||
|
return output->adjustAmountOfSamples(numSamples);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// General FIR digital filter routines with MMX optimization.
|
/// General FIR digital filter routines with MMX optimization.
|
||||||
///
|
///
|
||||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-25 19:13:51 +0200 (Wed, 25 Feb 2009) $
|
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: FIRFilter.cpp 67 2009-02-25 17:13:51Z oparviai $
|
// $Id: FIRFilter.cpp 131 2011-09-02 18:56:11Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -43,7 +43,6 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdexcept>
|
|
||||||
#include "FIRFilter.h"
|
#include "FIRFilter.h"
|
||||||
#include "cpu_detect.h"
|
#include "cpu_detect.h"
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
{
|
{
|
||||||
uint i, j, end;
|
uint i, j, end;
|
||||||
LONG_SAMPLETYPE suml, sumr;
|
LONG_SAMPLETYPE suml, sumr;
|
||||||
#ifdef FLOAT_SAMPLES
|
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
// when using floating point samples, use a scaler instead of a divider
|
// when using floating point samples, use a scaler instead of a divider
|
||||||
// because division is much slower operation than multiplying.
|
// because division is much slower operation than multiplying.
|
||||||
double dScaler = 1.0 / (double)resultDivider;
|
double dScaler = 1.0 / (double)resultDivider;
|
||||||
|
@ -88,14 +87,14 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
|
|
||||||
end = 2 * (numSamples - length);
|
end = 2 * (numSamples - length);
|
||||||
|
|
||||||
for (j = 0; j < end; j += 2)
|
for (j = 0; j < end; j += 2)
|
||||||
{
|
{
|
||||||
const SAMPLETYPE *ptr;
|
const SAMPLETYPE *ptr;
|
||||||
|
|
||||||
suml = sumr = 0;
|
suml = sumr = 0;
|
||||||
ptr = src + j;
|
ptr = src + j;
|
||||||
|
|
||||||
for (i = 0; i < length; i += 4)
|
for (i = 0; i < length; i += 4)
|
||||||
{
|
{
|
||||||
// loop is unrolled by factor of 4 here for efficiency
|
// loop is unrolled by factor of 4 here for efficiency
|
||||||
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
|
suml += ptr[2 * i + 0] * filterCoeffs[i + 0] +
|
||||||
|
@ -108,7 +107,7 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
ptr[2 * i + 7] * filterCoeffs[i + 3];
|
ptr[2 * i + 7] * filterCoeffs[i + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INTEGER_SAMPLES
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
suml >>= resultDivFactor;
|
suml >>= resultDivFactor;
|
||||||
sumr >>= resultDivFactor;
|
sumr >>= resultDivFactor;
|
||||||
// saturate to 16 bit integer limits
|
// saturate to 16 bit integer limits
|
||||||
|
@ -118,7 +117,7 @@ uint FIRFilter::evaluateFilterStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, ui
|
||||||
#else
|
#else
|
||||||
suml *= dScaler;
|
suml *= dScaler;
|
||||||
sumr *= dScaler;
|
sumr *= dScaler;
|
||||||
#endif // INTEGER_SAMPLES
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
dest[j] = (SAMPLETYPE)suml;
|
dest[j] = (SAMPLETYPE)suml;
|
||||||
dest[j + 1] = (SAMPLETYPE)sumr;
|
dest[j + 1] = (SAMPLETYPE)sumr;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +132,7 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
||||||
{
|
{
|
||||||
uint i, j, end;
|
uint i, j, end;
|
||||||
LONG_SAMPLETYPE sum;
|
LONG_SAMPLETYPE sum;
|
||||||
#ifdef FLOAT_SAMPLES
|
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
// when using floating point samples, use a scaler instead of a divider
|
// when using floating point samples, use a scaler instead of a divider
|
||||||
// because division is much slower operation than multiplying.
|
// because division is much slower operation than multiplying.
|
||||||
double dScaler = 1.0 / (double)resultDivider;
|
double dScaler = 1.0 / (double)resultDivider;
|
||||||
|
@ -143,24 +142,24 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
||||||
assert(length != 0);
|
assert(length != 0);
|
||||||
|
|
||||||
end = numSamples - length;
|
end = numSamples - length;
|
||||||
for (j = 0; j < end; j ++)
|
for (j = 0; j < end; j ++)
|
||||||
{
|
{
|
||||||
sum = 0;
|
sum = 0;
|
||||||
for (i = 0; i < length; i += 4)
|
for (i = 0; i < length; i += 4)
|
||||||
{
|
{
|
||||||
// loop is unrolled by factor of 4 here for efficiency
|
// loop is unrolled by factor of 4 here for efficiency
|
||||||
sum += src[i + 0] * filterCoeffs[i + 0] +
|
sum += src[i + 0] * filterCoeffs[i + 0] +
|
||||||
src[i + 1] * filterCoeffs[i + 1] +
|
src[i + 1] * filterCoeffs[i + 1] +
|
||||||
src[i + 2] * filterCoeffs[i + 2] +
|
src[i + 2] * filterCoeffs[i + 2] +
|
||||||
src[i + 3] * filterCoeffs[i + 3];
|
src[i + 3] * filterCoeffs[i + 3];
|
||||||
}
|
}
|
||||||
#ifdef INTEGER_SAMPLES
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
sum >>= resultDivFactor;
|
sum >>= resultDivFactor;
|
||||||
// saturate to 16 bit integer limits
|
// saturate to 16 bit integer limits
|
||||||
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
|
sum = (sum < -32768) ? -32768 : (sum > 32767) ? 32767 : sum;
|
||||||
#else
|
#else
|
||||||
sum *= dScaler;
|
sum *= dScaler;
|
||||||
#endif // INTEGER_SAMPLES
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
dest[j] = (SAMPLETYPE)sum;
|
dest[j] = (SAMPLETYPE)sum;
|
||||||
src ++;
|
src ++;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +173,7 @@ uint FIRFilter::evaluateFilterMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint
|
||||||
void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
|
void FIRFilter::setCoefficients(const SAMPLETYPE *coeffs, uint newLength, uint uResultDivFactor)
|
||||||
{
|
{
|
||||||
assert(newLength > 0);
|
assert(newLength > 0);
|
||||||
if (newLength % 8) throw std::runtime_error("FIR filter length not divisible by 8");
|
if (newLength % 8) ST_THROW_RT_ERROR("FIR filter length not divisible by 8");
|
||||||
|
|
||||||
lengthDiv8 = newLength / 8;
|
lengthDiv8 = newLength / 8;
|
||||||
length = lengthDiv8 * 8;
|
length = lengthDiv8 * 8;
|
||||||
|
@ -196,9 +195,9 @@ uint FIRFilter::getLength() const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Applies the filter to the given sequence of samples.
|
// Applies the filter to the given sequence of samples.
|
||||||
//
|
//
|
||||||
// Note : The amount of outputted samples is by value of 'filter_length'
|
// Note : The amount of outputted samples is by value of 'filter_length'
|
||||||
// smaller than the amount of input samples.
|
// smaller than the amount of input samples.
|
||||||
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const
|
||||||
{
|
{
|
||||||
|
@ -207,7 +206,7 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample
|
||||||
assert(length > 0);
|
assert(length > 0);
|
||||||
assert(lengthDiv8 * 8 == length);
|
assert(lengthDiv8 * 8 == length);
|
||||||
if (numSamples < length) return 0;
|
if (numSamples < length) return 0;
|
||||||
if (numChannels == 2)
|
if (numChannels == 2)
|
||||||
{
|
{
|
||||||
return evaluateFilterStereo(dest, src, numSamples);
|
return evaluateFilterStereo(dest, src, numSamples);
|
||||||
} else {
|
} else {
|
||||||
|
@ -217,13 +216,13 @@ uint FIRFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSample
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
// depending on if we've a MMX-capable CPU available or not.
|
// depending on if we've a MMX-capable CPU available or not.
|
||||||
void * FIRFilter::operator new(size_t s)
|
void * FIRFilter::operator new(size_t s)
|
||||||
{
|
{
|
||||||
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
|
||||||
throw std::runtime_error("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
ST_THROW_RT_ERROR("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
|
||||||
return NULL;
|
return newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -233,34 +232,25 @@ FIRFilter * FIRFilter::newInstance()
|
||||||
|
|
||||||
uExtensions = detectCPUextensions();
|
uExtensions = detectCPUextensions();
|
||||||
|
|
||||||
// Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
|
// Check if MMX/SSE instruction set extensions supported by CPU
|
||||||
|
|
||||||
#ifdef ALLOW_MMX
|
#ifdef SOUNDTOUCH_ALLOW_MMX
|
||||||
// MMX routines available only with integer sample types
|
// MMX routines available only with integer sample types
|
||||||
if (uExtensions & SUPPORT_MMX)
|
if (uExtensions & SUPPORT_MMX)
|
||||||
{
|
{
|
||||||
return ::new FIRFilterMMX;
|
return ::new FIRFilterMMX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // ALLOW_MMX
|
#endif // SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
||||||
#ifdef ALLOW_SSE
|
#ifdef SOUNDTOUCH_ALLOW_SSE
|
||||||
if (uExtensions & SUPPORT_SSE)
|
if (uExtensions & SUPPORT_SSE)
|
||||||
{
|
{
|
||||||
// SSE support
|
// SSE support
|
||||||
return ::new FIRFilterSSE;
|
return ::new FIRFilterSSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // ALLOW_SSE
|
#endif // SOUNDTOUCH_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
|
// ISA optimizations not supported, use plain C version
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// General FIR digital filter routines with MMX optimization.
|
/// General FIR digital filter routines with MMX optimization.
|
||||||
///
|
///
|
||||||
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
/// Note : MMX optimized functions reside in a separate, platform-specific file,
|
||||||
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
/// e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
|
// Last changed : $Date: 2011-02-13 17:13:57 -0200 (dom, 13 fev 2011) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: FIRFilter.h 63 2009-02-21 16:00:14Z oparviai $
|
// $Id: FIRFilter.h 104 2011-02-13 19:13:57Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -48,11 +48,11 @@
|
||||||
namespace soundtouch
|
namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
class FIRFilter
|
class FIRFilter
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
// Number of FIR filter taps
|
// Number of FIR filter taps
|
||||||
uint length;
|
uint length;
|
||||||
// Number of FIR filter taps divided by 8
|
// Number of FIR filter taps divided by 8
|
||||||
uint lengthDiv8;
|
uint lengthDiv8;
|
||||||
|
|
||||||
|
@ -65,44 +65,44 @@ protected:
|
||||||
// Memory for filter coefficients
|
// Memory for filter coefficients
|
||||||
SAMPLETYPE *filterCoeffs;
|
SAMPLETYPE *filterCoeffs;
|
||||||
|
|
||||||
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
|
virtual uint evaluateFilterStereo(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples) const;
|
uint numSamples) const;
|
||||||
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
|
virtual uint evaluateFilterMono(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples) const;
|
uint numSamples) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FIRFilter();
|
FIRFilter();
|
||||||
virtual ~FIRFilter();
|
virtual ~FIRFilter();
|
||||||
|
|
||||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
/// depending on if we've a MMX-capable CPU available or not.
|
/// depending on if we've a MMX-capable CPU available or not.
|
||||||
static void * operator new(size_t s);
|
static void * operator new(size_t s);
|
||||||
|
|
||||||
static FIRFilter *newInstance();
|
static FIRFilter *newInstance();
|
||||||
|
|
||||||
/// Applies the filter to the given sequence of samples.
|
/// Applies the filter to the given sequence of samples.
|
||||||
/// Note : The amount of outputted samples is by value of 'filter_length'
|
/// Note : The amount of outputted samples is by value of 'filter_length'
|
||||||
/// smaller than the amount of input samples.
|
/// smaller than the amount of input samples.
|
||||||
///
|
///
|
||||||
/// \return Number of samples copied to 'dest'.
|
/// \return Number of samples copied to 'dest'.
|
||||||
uint evaluate(SAMPLETYPE *dest,
|
uint evaluate(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples,
|
uint numSamples,
|
||||||
uint numChannels) const;
|
uint numChannels) const;
|
||||||
|
|
||||||
uint getLength() const;
|
uint getLength() const;
|
||||||
|
|
||||||
virtual void setCoefficients(const SAMPLETYPE *coeffs,
|
virtual void setCoefficients(const SAMPLETYPE *coeffs,
|
||||||
uint newLength,
|
uint newLength,
|
||||||
uint uResultDivFactor);
|
uint uResultDivFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Optional subclasses that implement CPU-specific optimizations:
|
// Optional subclasses that implement CPU-specific optimizations:
|
||||||
|
|
||||||
#ifdef ALLOW_MMX
|
#ifdef SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
||||||
/// Class that implements MMX optimized functions exclusive for 16bit integer samples type.
|
/// Class that implements MMX optimized functions exclusive for 16bit integer samples type.
|
||||||
class FIRFilterMMX : public FIRFilter
|
class FIRFilterMMX : public FIRFilter
|
||||||
|
@ -119,29 +119,10 @@ public:
|
||||||
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
|
virtual void setCoefficients(const short *coeffs, uint newLength, uint uResultDivFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ALLOW_MMX
|
#endif // SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALLOW_3DNOW
|
#ifdef SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
||||||
/// 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 that implements SSE optimized functions exclusive for floating point samples type.
|
||||||
class FIRFilterSSE : public FIRFilter
|
class FIRFilterSSE : public FIRFilter
|
||||||
{
|
{
|
||||||
|
@ -157,7 +138,7 @@ public:
|
||||||
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
virtual void setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ALLOW_SSE
|
#endif // SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,71 @@
|
||||||
## Process this file with automake to create Makefile.in
|
## Process this file with automake to create Makefile.in
|
||||||
##
|
##
|
||||||
## $Id: Makefile.am,v 1.3 2006/02/05 18:33:34 Olli Exp $
|
## $Id: Makefile.am 138 2012-04-01 20:00:09Z oparviai $
|
||||||
##
|
|
||||||
## Copyright (C) 2003 - David W. Durham
|
|
||||||
##
|
##
|
||||||
## This file is part of SoundTouch, an audio processing library for pitch/time adjustments
|
## 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
|
## 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
|
## 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
|
## Foundation; either version 2 of the License, or (at your option) any later
|
||||||
## version.
|
## version.
|
||||||
##
|
##
|
||||||
## SoundTouch is distributed in the hope that it will be useful, but WITHOUT ANY
|
## 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
|
## WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
## A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
## 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
|
## 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
|
## this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||||
## Place - Suite 330, Boston, MA 02111-1307, USA
|
## 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
|
include $(top_srcdir)/config/am_include.mk
|
||||||
noinst_LIBRARIES = libSoundTouch.a
|
|
||||||
|
|
||||||
libSoundTouch_a_CXXFLAGS = -msse -mmmx
|
|
||||||
libSoundTouch_a_CFLAGS = -msse -mmmx
|
|
||||||
|
|
||||||
#lib_LTLIBRARIES=libSoundTouch.la
|
# set to something if you want other stuff to be included in the distribution tarball
|
||||||
# the mmx_gcc.cpp and cpu_detect_x86_gcc.cpp may need to be conditionally included here from things discovered in configure.ac
|
EXTRA_DIST=SoundTouch.dsp SoundTouch.dsw SoundTouch.sln SoundTouch.vcproj
|
||||||
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
|
noinst_HEADERS=AAFilter.h cpu_detect.h cpu_detect_x86.cpp FIRFilter.h RateTransposer.h TDStretch.h PeakFinder.h
|
||||||
|
|
||||||
|
lib_LTLIBRARIES=libSoundTouch.la
|
||||||
|
#
|
||||||
|
libSoundTouch_la_SOURCES=AAFilter.cpp FIRFilter.cpp FIFOSampleBuffer.cpp RateTransposer.cpp SoundTouch.cpp TDStretch.cpp cpu_detect_x86.cpp BPMDetect.cpp PeakFinder.cpp
|
||||||
|
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
AM_CXXFLAGS=-O3 -fcheck-new -I../../include
|
||||||
|
|
||||||
|
# Compile the files that need MMX and SSE individually.
|
||||||
|
libSoundTouch_la_LIBADD=libSoundTouchMMX.la libSoundTouchSSE.la
|
||||||
|
noinst_LTLIBRARIES=libSoundTouchMMX.la libSoundTouchSSE.la
|
||||||
|
libSoundTouchMMX_la_SOURCES=mmx_optimized.cpp
|
||||||
|
libSoundTouchSSE_la_SOURCES=sse_optimized.cpp
|
||||||
|
|
||||||
|
# We enable optimizations by default.
|
||||||
|
# If MMX is supported compile with -mmmx.
|
||||||
|
# Do not assume -msse is also supported.
|
||||||
|
if HAVE_MMX
|
||||||
|
libSoundTouchMMX_la_CXXFLAGS = -mmmx $(AM_CXXFLAGS)
|
||||||
|
else
|
||||||
|
libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# We enable optimizations by default.
|
||||||
|
# If SSE is supported compile with -msse.
|
||||||
|
if HAVE_SSE
|
||||||
|
libSoundTouchSSE_la_CXXFLAGS = -msse $(AM_CXXFLAGS)
|
||||||
|
else
|
||||||
|
libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Let the user disable optimizations if he wishes to.
|
||||||
|
if !X86_OPTIMIZATIONS
|
||||||
|
libSoundTouchMMX_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||||
|
libSoundTouchSSE_la_CXXFLAGS = $(AM_CXXFLAGS)
|
||||||
|
endif
|
||||||
|
|
||||||
# ??? 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
|
# other linking flags to add
|
||||||
#libSoundTouch_la_LIBADD=
|
# noinst_LTLIBRARIES = libSoundTouchOpt.la
|
||||||
|
# libSoundTouch_la_LIBADD = libSoundTouchOpt.la
|
||||||
|
# libSoundTouchOpt_la_SOURCES = mmx_optimized.cpp sse_optimized.cpp
|
||||||
|
# libSoundTouchOpt_la_CXXFLAGS = -O3 -msse -fcheck-new -I../../include
|
||||||
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Peak detection routine.
|
||||||
|
///
|
||||||
|
/// The routine detects highest value on an array of values and calculates the
|
||||||
|
/// precise peak location as a mass-center of the 'hump' around the peak value.
|
||||||
|
///
|
||||||
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
/// Author e-mail : oparviai 'at' iki.fi
|
||||||
|
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Last changed : $Date: 2012-12-28 17:52:47 -0200 (sex, 28 dez 2012) $
|
||||||
|
// File revision : $Revision: 4 $
|
||||||
|
//
|
||||||
|
// $Id: PeakFinder.cpp 164 2012-12-28 19:52:47Z oparviai $
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "PeakFinder.h"
|
||||||
|
|
||||||
|
using namespace soundtouch;
|
||||||
|
|
||||||
|
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||||
|
|
||||||
|
|
||||||
|
PeakFinder::PeakFinder()
|
||||||
|
{
|
||||||
|
minPos = maxPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
|
||||||
|
int PeakFinder::findTop(const float *data, int peakpos) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int start, end;
|
||||||
|
float refvalue;
|
||||||
|
|
||||||
|
refvalue = data[peakpos];
|
||||||
|
|
||||||
|
// seek within ±10 points
|
||||||
|
start = peakpos - 10;
|
||||||
|
if (start < minPos) start = minPos;
|
||||||
|
end = peakpos + 10;
|
||||||
|
if (end > maxPos) end = maxPos;
|
||||||
|
|
||||||
|
for (i = start; i <= end; i ++)
|
||||||
|
{
|
||||||
|
if (data[i] > refvalue)
|
||||||
|
{
|
||||||
|
peakpos = i;
|
||||||
|
refvalue = data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// failure if max value is at edges of seek range => it's not peak, it's at slope.
|
||||||
|
if ((peakpos == start) || (peakpos == end)) return 0;
|
||||||
|
|
||||||
|
return peakpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding
|
||||||
|
// to direction defined by 'direction' until next 'hump' after minimum value will
|
||||||
|
// begin
|
||||||
|
int PeakFinder::findGround(const float *data, int peakpos, int direction) const
|
||||||
|
{
|
||||||
|
int lowpos;
|
||||||
|
int pos;
|
||||||
|
int climb_count;
|
||||||
|
float refvalue;
|
||||||
|
float delta;
|
||||||
|
|
||||||
|
climb_count = 0;
|
||||||
|
refvalue = data[peakpos];
|
||||||
|
lowpos = peakpos;
|
||||||
|
|
||||||
|
pos = peakpos;
|
||||||
|
|
||||||
|
while ((pos > minPos+1) && (pos < maxPos-1))
|
||||||
|
{
|
||||||
|
int prevpos;
|
||||||
|
|
||||||
|
prevpos = pos;
|
||||||
|
pos += direction;
|
||||||
|
|
||||||
|
// calculate derivate
|
||||||
|
delta = data[pos] - data[prevpos];
|
||||||
|
if (delta <= 0)
|
||||||
|
{
|
||||||
|
// going downhill, ok
|
||||||
|
if (climb_count)
|
||||||
|
{
|
||||||
|
climb_count --; // decrease climb count
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if new minimum found
|
||||||
|
if (data[pos] < refvalue)
|
||||||
|
{
|
||||||
|
// new minimum found
|
||||||
|
lowpos = pos;
|
||||||
|
refvalue = data[pos];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// going uphill, increase climbing counter
|
||||||
|
climb_count ++;
|
||||||
|
if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lowpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Find offset where the value crosses the given level, when starting from 'peakpos' and
|
||||||
|
// proceeds to direction defined in 'direction'
|
||||||
|
int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, int direction) const
|
||||||
|
{
|
||||||
|
float peaklevel;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
peaklevel = data[peakpos];
|
||||||
|
assert(peaklevel >= level);
|
||||||
|
pos = peakpos;
|
||||||
|
while ((pos >= minPos) && (pos < maxPos))
|
||||||
|
{
|
||||||
|
if (data[pos + direction] < level) return pos; // crossing found
|
||||||
|
pos += direction;
|
||||||
|
}
|
||||||
|
return -1; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculates the center of mass location of 'data' array items between 'firstPos' and 'lastPos'
|
||||||
|
double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) const
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
float sum;
|
||||||
|
float wsum;
|
||||||
|
|
||||||
|
sum = 0;
|
||||||
|
wsum = 0;
|
||||||
|
for (i = firstPos; i <= lastPos; i ++)
|
||||||
|
{
|
||||||
|
sum += (float)i * data[i];
|
||||||
|
wsum += data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wsum < 1e-6) return 0;
|
||||||
|
return sum / wsum;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// get exact center of peak near given position by calculating local mass of center
|
||||||
|
double PeakFinder::getPeakCenter(const float *data, int peakpos) const
|
||||||
|
{
|
||||||
|
float peakLevel; // peak level
|
||||||
|
int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
|
||||||
|
float cutLevel; // cutting value
|
||||||
|
float groundLevel; // ground level of the peak
|
||||||
|
int gp1, gp2; // bottom positions of the peak 'hump'
|
||||||
|
|
||||||
|
// find ground positions.
|
||||||
|
gp1 = findGround(data, peakpos, -1);
|
||||||
|
gp2 = findGround(data, peakpos, 1);
|
||||||
|
|
||||||
|
groundLevel = 0.5f * (data[gp1] + data[gp2]);
|
||||||
|
peakLevel = data[peakpos];
|
||||||
|
|
||||||
|
// calculate 70%-level of the peak
|
||||||
|
cutLevel = 0.70f * peakLevel + 0.30f * groundLevel;
|
||||||
|
// find mid-level crossings
|
||||||
|
crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1);
|
||||||
|
crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1);
|
||||||
|
|
||||||
|
if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak..
|
||||||
|
|
||||||
|
// calculate mass center of the peak surroundings
|
||||||
|
return calcMassCenter(data, crosspos1, crosspos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
double PeakFinder::detectPeak(const float *data, int aminPos, int amaxPos)
|
||||||
|
{
|
||||||
|
|
||||||
|
int i;
|
||||||
|
int peakpos; // position of peak level
|
||||||
|
double highPeak, peak;
|
||||||
|
|
||||||
|
this->minPos = aminPos;
|
||||||
|
this->maxPos = amaxPos;
|
||||||
|
|
||||||
|
// find absolute peak
|
||||||
|
peakpos = minPos;
|
||||||
|
peak = data[minPos];
|
||||||
|
for (i = minPos + 1; i < maxPos; i ++)
|
||||||
|
{
|
||||||
|
if (data[i] > peak)
|
||||||
|
{
|
||||||
|
peak = data[i];
|
||||||
|
peakpos = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate exact location of the highest peak mass center
|
||||||
|
highPeak = getPeakCenter(data, peakpos);
|
||||||
|
peak = highPeak;
|
||||||
|
|
||||||
|
// Now check if the highest peak were in fact harmonic of the true base beat peak
|
||||||
|
// - sometimes the highest peak can be Nth harmonic of the true base peak yet
|
||||||
|
// just a slightly higher than the true base
|
||||||
|
|
||||||
|
for (i = 3; i < 10; i ++)
|
||||||
|
{
|
||||||
|
double peaktmp, harmonic;
|
||||||
|
int i1,i2;
|
||||||
|
|
||||||
|
harmonic = (double)i * 0.5;
|
||||||
|
peakpos = (int)(highPeak / harmonic + 0.5f);
|
||||||
|
if (peakpos < minPos) break;
|
||||||
|
peakpos = findTop(data, peakpos); // seek true local maximum index
|
||||||
|
if (peakpos == 0) continue; // no local max here
|
||||||
|
|
||||||
|
// calculate mass-center of possible harmonic peak
|
||||||
|
peaktmp = getPeakCenter(data, peakpos);
|
||||||
|
|
||||||
|
// accept harmonic peak if
|
||||||
|
// (a) it is found
|
||||||
|
// (b) is within ±4% of the expected harmonic interval
|
||||||
|
// (c) has at least half x-corr value of the max. peak
|
||||||
|
|
||||||
|
double diff = harmonic * peaktmp / highPeak;
|
||||||
|
if ((diff < 0.96) || (diff > 1.04)) continue; // peak too afar from expected
|
||||||
|
|
||||||
|
// now compare to highest detected peak
|
||||||
|
i1 = (int)(highPeak + 0.5);
|
||||||
|
i2 = (int)(peaktmp + 0.5);
|
||||||
|
if (data[i2] >= 0.4*data[i1])
|
||||||
|
{
|
||||||
|
// The harmonic is at least half as high primary peak,
|
||||||
|
// thus use the harmonic peak instead
|
||||||
|
peak = peaktmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return peak;
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// The routine detects highest value on an array of values and calculates the
|
||||||
|
/// precise peak location as a mass-center of the 'hump' around the peak value.
|
||||||
|
///
|
||||||
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
/// Author e-mail : oparviai 'at' iki.fi
|
||||||
|
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Last changed : $Date: 2011-12-30 18:33:46 -0200 (sex, 30 dez 2011) $
|
||||||
|
// File revision : $Revision: 4 $
|
||||||
|
//
|
||||||
|
// $Id: PeakFinder.h 132 2011-12-30 20:33:46Z oparviai $
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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 _PeakFinder_H_
|
||||||
|
#define _PeakFinder_H_
|
||||||
|
|
||||||
|
namespace soundtouch
|
||||||
|
{
|
||||||
|
|
||||||
|
class PeakFinder
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/// Min, max allowed peak positions within the data vector
|
||||||
|
int minPos, maxPos;
|
||||||
|
|
||||||
|
/// Calculates the mass center between given vector items.
|
||||||
|
double calcMassCenter(const float *data, ///< Data vector.
|
||||||
|
int firstPos, ///< Index of first vector item beloging to the peak.
|
||||||
|
int lastPos ///< Index of last vector item beloging to the peak.
|
||||||
|
) const;
|
||||||
|
|
||||||
|
/// Finds the data vector index where the monotoniously decreasing signal crosses the
|
||||||
|
/// given level.
|
||||||
|
int findCrossingLevel(const float *data, ///< Data vector.
|
||||||
|
float level, ///< Goal crossing level.
|
||||||
|
int peakpos, ///< Peak position index within the data vector.
|
||||||
|
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Finds real 'top' of a peak hump from neighnourhood of the given 'peakpos'.
|
||||||
|
int findTop(const float *data, int peakpos) const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right-
|
||||||
|
/// or left-hand side of the given peak position.
|
||||||
|
int findGround(const float *data, /// Data vector.
|
||||||
|
int peakpos, /// Peak position index within the data vector.
|
||||||
|
int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
|
||||||
|
) const;
|
||||||
|
|
||||||
|
/// get exact center of peak near given position by calculating local mass of center
|
||||||
|
double getPeakCenter(const float *data, int peakpos) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Constructor.
|
||||||
|
PeakFinder();
|
||||||
|
|
||||||
|
/// Detect exact peak position of the data vector by finding the largest peak 'hump'
|
||||||
|
/// and calculating the mass-center location of the peak hump.
|
||||||
|
///
|
||||||
|
/// \return The location of the largest base harmonic peak hump.
|
||||||
|
double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has
|
||||||
|
/// to be at least 'maxPos' items long.
|
||||||
|
int minPos, ///< Min allowed peak location within the vector data.
|
||||||
|
int maxPos ///< Max allowed peak location within the vector data.
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _PeakFinder_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
||||||
/// together with anti-alias filtering (first order interpolation with anti-
|
/// together with anti-alias filtering (first order interpolation with anti-
|
||||||
/// alias filtering should be quite adequate for this application)
|
/// alias filtering should be quite adequate for this application)
|
||||||
///
|
///
|
||||||
|
@ -10,10 +10,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-10-31 16:37:24 +0200 (Sat, 31 Oct 2009) $
|
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: RateTransposer.cpp 74 2009-10-31 14:37:24Z oparviai $
|
// $Id: RateTransposer.cpp 131 2011-09-02 18:56:11Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -42,11 +42,9 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdexcept>
|
|
||||||
#include "RateTransposer.h"
|
#include "RateTransposer.h"
|
||||||
#include "AAFilter.h"
|
#include "AAFilter.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace soundtouch;
|
using namespace soundtouch;
|
||||||
|
|
||||||
|
|
||||||
|
@ -61,18 +59,18 @@ protected:
|
||||||
|
|
||||||
virtual void resetRegisters();
|
virtual void resetRegisters();
|
||||||
|
|
||||||
virtual uint transposeStereo(SAMPLETYPE *dest,
|
virtual uint transposeStereo(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
virtual uint transposeMono(SAMPLETYPE *dest,
|
virtual uint transposeMono(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RateTransposerInteger();
|
RateTransposerInteger();
|
||||||
virtual ~RateTransposerInteger();
|
virtual ~RateTransposerInteger();
|
||||||
|
|
||||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||||
/// rate, larger faster rates.
|
/// rate, larger faster rates.
|
||||||
virtual void setRate(float newRate);
|
virtual void setRate(float newRate);
|
||||||
|
|
||||||
|
@ -89,11 +87,11 @@ protected:
|
||||||
|
|
||||||
virtual void resetRegisters();
|
virtual void resetRegisters();
|
||||||
|
|
||||||
virtual uint transposeStereo(SAMPLETYPE *dest,
|
virtual uint transposeStereo(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
virtual uint transposeMono(SAMPLETYPE *dest,
|
virtual uint transposeMono(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -104,18 +102,18 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
// 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.
|
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||||
void * RateTransposer::operator new(size_t s)
|
void * RateTransposer::operator new(size_t s)
|
||||||
{
|
{
|
||||||
throw runtime_error("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
|
ST_THROW_RT_ERROR("Error in RateTransoser::new: don't use \"new TDStretch\" directly, use \"newInstance\" to create a new instance instead!");
|
||||||
return NULL;
|
return newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RateTransposer *RateTransposer::newInstance()
|
RateTransposer *RateTransposer::newInstance()
|
||||||
{
|
{
|
||||||
#ifdef INTEGER_SAMPLES
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
return ::new RateTransposerInteger;
|
return ::new RateTransposerInteger;
|
||||||
#else
|
#else
|
||||||
return ::new RateTransposerFloat;
|
return ::new RateTransposerFloat;
|
||||||
|
@ -165,7 +163,7 @@ AAFilter *RateTransposer::getAAFilter()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
|
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
|
||||||
// iRate, larger faster iRates.
|
// iRate, larger faster iRates.
|
||||||
void RateTransposer::setRate(float newRate)
|
void RateTransposer::setRate(float newRate)
|
||||||
{
|
{
|
||||||
|
@ -174,11 +172,11 @@ void RateTransposer::setRate(float newRate)
|
||||||
fRate = newRate;
|
fRate = newRate;
|
||||||
|
|
||||||
// design a new anti-alias filter
|
// design a new anti-alias filter
|
||||||
if (newRate > 1.0f)
|
if (newRate > 1.0f)
|
||||||
{
|
{
|
||||||
fCutoff = 0.5f / newRate;
|
fCutoff = 0.5f / newRate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fCutoff = 0.5f * newRate;
|
fCutoff = 0.5f * newRate;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +218,7 @@ void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
|
||||||
// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
|
// If the parameter 'uRate' value is smaller than 'SCALE', first transpose
|
||||||
// the samples and then apply the anti-alias filter to remove aliasing.
|
// the samples and then apply the anti-alias filter to remove aliasing.
|
||||||
|
|
||||||
// First check that there's enough room in 'storeBuffer'
|
// First check that there's enough room in 'storeBuffer'
|
||||||
// (+16 is to reserve some slack in the destination buffer)
|
// (+16 is to reserve some slack in the destination buffer)
|
||||||
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
|
sizeTemp = (uint)((float)nSamples / fRate + 16.0f);
|
||||||
|
|
||||||
|
@ -231,7 +229,7 @@ void RateTransposer::upsample(const SAMPLETYPE *src, uint nSamples)
|
||||||
// Apply the anti-alias filter to samples in "store output", output the
|
// Apply the anti-alias filter to samples in "store output", output the
|
||||||
// result to "dest"
|
// result to "dest"
|
||||||
num = storeBuffer.numSamples();
|
num = storeBuffer.numSamples();
|
||||||
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
|
count = pAAFilter->evaluate(outputBuffer.ptrEnd(num),
|
||||||
storeBuffer.ptrBegin(), num, (uint)numChannels);
|
storeBuffer.ptrBegin(), num, (uint)numChannels);
|
||||||
outputBuffer.putSamples(count);
|
outputBuffer.putSamples(count);
|
||||||
|
|
||||||
|
@ -253,13 +251,13 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
|
||||||
// Add the new samples to the end of the storeBuffer
|
// Add the new samples to the end of the storeBuffer
|
||||||
storeBuffer.putSamples(src, nSamples);
|
storeBuffer.putSamples(src, nSamples);
|
||||||
|
|
||||||
// Anti-alias filter the samples to prevent folding and output the filtered
|
// Anti-alias filter the samples to prevent folding and output the filtered
|
||||||
// data to tempBuffer. Note : because of the FIR filter length, the
|
// data to tempBuffer. Note : because of the FIR filter length, the
|
||||||
// filtering routine takes in 'filter_length' more samples than it outputs.
|
// filtering routine takes in 'filter_length' more samples than it outputs.
|
||||||
assert(tempBuffer.isEmpty());
|
assert(tempBuffer.isEmpty());
|
||||||
sizeTemp = storeBuffer.numSamples();
|
sizeTemp = storeBuffer.numSamples();
|
||||||
|
|
||||||
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
|
count = pAAFilter->evaluate(tempBuffer.ptrEnd(sizeTemp),
|
||||||
storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
|
storeBuffer.ptrBegin(), sizeTemp, (uint)numChannels);
|
||||||
|
|
||||||
if (count == 0) return;
|
if (count == 0) return;
|
||||||
|
@ -274,7 +272,7 @@ void RateTransposer::downsample(const SAMPLETYPE *src, uint nSamples)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transposes sample rate by applying anti-alias filter to prevent folding.
|
// Transposes sample rate by applying anti-alias filter to prevent folding.
|
||||||
// Returns amount of samples returned in the "dest" buffer.
|
// 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 maximum amount of samples that can be returned at a time is set by
|
||||||
// the 'set_returnBuffer_size' function.
|
// the 'set_returnBuffer_size' function.
|
||||||
|
@ -288,7 +286,7 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||||
|
|
||||||
// If anti-alias filter is turned off, simply transpose without applying
|
// If anti-alias filter is turned off, simply transpose without applying
|
||||||
// the filter
|
// the filter
|
||||||
if (bUseAAFilter == FALSE)
|
if (bUseAAFilter == FALSE)
|
||||||
{
|
{
|
||||||
sizeReq = (uint)((float)nSamples / fRate + 1.0f);
|
sizeReq = (uint)((float)nSamples / fRate + 1.0f);
|
||||||
count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
|
count = transpose(outputBuffer.ptrEnd(sizeReq), src, nSamples);
|
||||||
|
@ -297,26 +295,26 @@ void RateTransposer::processSamples(const SAMPLETYPE *src, uint nSamples)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transpose with anti-alias filter
|
// Transpose with anti-alias filter
|
||||||
if (fRate < 1.0f)
|
if (fRate < 1.0f)
|
||||||
{
|
{
|
||||||
upsample(src, nSamples);
|
upsample(src, nSamples);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
downsample(src, nSamples);
|
downsample(src, nSamples);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transposes the sample rate of the given samples using linear interpolation.
|
// Transposes the sample rate of the given samples using linear interpolation.
|
||||||
// Returns the number of samples returned in the "dest" buffer
|
// Returns the number of samples returned in the "dest" buffer
|
||||||
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
inline uint RateTransposer::transpose(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
if (numChannels == 2)
|
if (numChannels == 2)
|
||||||
{
|
{
|
||||||
return transposeStereo(dest, src, nSamples);
|
return transposeStereo(dest, src, nSamples);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return transposeMono(dest, src, nSamples);
|
return transposeMono(dest, src, nSamples);
|
||||||
}
|
}
|
||||||
|
@ -363,7 +361,7 @@ int RateTransposer::isEmpty() const
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// RateTransposerInteger - integer arithmetic implementation
|
// RateTransposerInteger - integer arithmetic implementation
|
||||||
//
|
//
|
||||||
|
|
||||||
/// fixed-point interpolation routine precision
|
/// fixed-point interpolation routine precision
|
||||||
#define SCALE 65536
|
#define SCALE 65536
|
||||||
|
@ -371,7 +369,7 @@ int RateTransposer::isEmpty() const
|
||||||
// Constructor
|
// Constructor
|
||||||
RateTransposerInteger::RateTransposerInteger() : RateTransposer()
|
RateTransposerInteger::RateTransposerInteger() : RateTransposer()
|
||||||
{
|
{
|
||||||
// Notice: use local function calling syntax for sake of clarity,
|
// Notice: use local function calling syntax for sake of clarity,
|
||||||
// to indicate the fact that C++ constructor can't call virtual functions.
|
// to indicate the fact that C++ constructor can't call virtual functions.
|
||||||
RateTransposerInteger::resetRegisters();
|
RateTransposerInteger::resetRegisters();
|
||||||
RateTransposerInteger::setRate(1.0f);
|
RateTransposerInteger::setRate(1.0f);
|
||||||
|
@ -386,14 +384,14 @@ RateTransposerInteger::~RateTransposerInteger()
|
||||||
void RateTransposerInteger::resetRegisters()
|
void RateTransposerInteger::resetRegisters()
|
||||||
{
|
{
|
||||||
iSlopeCount = 0;
|
iSlopeCount = 0;
|
||||||
sPrevSampleL =
|
sPrevSampleL =
|
||||||
sPrevSampleR = 0;
|
sPrevSampleR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Transposes the sample rate of the given samples using linear interpolation.
|
// Transposes the sample rate of the given samples using linear interpolation.
|
||||||
// 'Mono' version of the routine. Returns the number of samples returned in
|
// 'Mono' version of the routine. Returns the number of samples returned in
|
||||||
// the "dest" buffer
|
// the "dest" buffer
|
||||||
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
|
@ -402,11 +400,11 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
|
||||||
|
|
||||||
if (nSamples == 0) return 0; // no samples, no work
|
if (nSamples == 0) return 0; // no samples, no work
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// Process the last sample saved from the previous call first...
|
// Process the last sample saved from the previous call first...
|
||||||
while (iSlopeCount <= SCALE)
|
while (iSlopeCount <= SCALE)
|
||||||
{
|
{
|
||||||
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
|
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
|
||||||
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
|
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
|
||||||
|
@ -419,7 +417,7 @@ uint RateTransposerInteger::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *sr
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
while (iSlopeCount > SCALE)
|
while (iSlopeCount > SCALE)
|
||||||
{
|
{
|
||||||
iSlopeCount -= SCALE;
|
iSlopeCount -= SCALE;
|
||||||
used ++;
|
used ++;
|
||||||
|
@ -440,8 +438,8 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transposes the sample rate of the given samples using linear interpolation.
|
// Transposes the sample rate of the given samples using linear interpolation.
|
||||||
// 'Stereo' version of the routine. Returns the number of samples returned in
|
// 'Stereo' version of the routine. Returns the number of samples returned in
|
||||||
// the "dest" buffer
|
// the "dest" buffer
|
||||||
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
|
@ -450,11 +448,11 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
|
||||||
|
|
||||||
if (nSamples == 0) return 0; // no samples, no work
|
if (nSamples == 0) return 0; // no samples, no work
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// Process the last sample saved from the sPrevSampleLious call first...
|
// Process the last sample saved from the sPrevSampleLious call first...
|
||||||
while (iSlopeCount <= SCALE)
|
while (iSlopeCount <= SCALE)
|
||||||
{
|
{
|
||||||
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
|
vol1 = (LONG_SAMPLETYPE)(SCALE - iSlopeCount);
|
||||||
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
|
temp = vol1 * sPrevSampleL + iSlopeCount * src[0];
|
||||||
|
@ -469,7 +467,7 @@ uint RateTransposerInteger::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
while (iSlopeCount > SCALE)
|
while (iSlopeCount > SCALE)
|
||||||
{
|
{
|
||||||
iSlopeCount -= SCALE;
|
iSlopeCount -= SCALE;
|
||||||
used ++;
|
used ++;
|
||||||
|
@ -494,7 +492,7 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
|
// Sets new target iRate. Normal iRate = 1.0, smaller values represent slower
|
||||||
// iRate, larger faster iRates.
|
// iRate, larger faster iRates.
|
||||||
void RateTransposerInteger::setRate(float newRate)
|
void RateTransposerInteger::setRate(float newRate)
|
||||||
{
|
{
|
||||||
|
@ -506,13 +504,13 @@ void RateTransposerInteger::setRate(float newRate)
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// RateTransposerFloat - floating point arithmetic implementation
|
// RateTransposerFloat - floating point arithmetic implementation
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
RateTransposerFloat::RateTransposerFloat() : RateTransposer()
|
RateTransposerFloat::RateTransposerFloat() : RateTransposer()
|
||||||
{
|
{
|
||||||
// Notice: use local function calling syntax for sake of clarity,
|
// Notice: use local function calling syntax for sake of clarity,
|
||||||
// to indicate the fact that C++ constructor can't call virtual functions.
|
// to indicate the fact that C++ constructor can't call virtual functions.
|
||||||
RateTransposerFloat::resetRegisters();
|
RateTransposerFloat::resetRegisters();
|
||||||
RateTransposerFloat::setRate(1.0f);
|
RateTransposerFloat::setRate(1.0f);
|
||||||
|
@ -527,24 +525,24 @@ RateTransposerFloat::~RateTransposerFloat()
|
||||||
void RateTransposerFloat::resetRegisters()
|
void RateTransposerFloat::resetRegisters()
|
||||||
{
|
{
|
||||||
fSlopeCount = 0;
|
fSlopeCount = 0;
|
||||||
sPrevSampleL =
|
sPrevSampleL =
|
||||||
sPrevSampleR = 0;
|
sPrevSampleR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Transposes the sample rate of the given samples using linear interpolation.
|
// Transposes the sample rate of the given samples using linear interpolation.
|
||||||
// 'Mono' version of the routine. Returns the number of samples returned in
|
// 'Mono' version of the routine. Returns the number of samples returned in
|
||||||
// the "dest" buffer
|
// the "dest" buffer
|
||||||
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
unsigned int i, used;
|
unsigned int i, used;
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// Process the last sample saved from the previous call first...
|
// Process the last sample saved from the previous call first...
|
||||||
while (fSlopeCount <= 1.0f)
|
while (fSlopeCount <= 1.0f)
|
||||||
{
|
{
|
||||||
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
|
dest[i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
|
||||||
i++;
|
i++;
|
||||||
|
@ -556,7 +554,7 @@ uint RateTransposerFloat::transposeMono(SAMPLETYPE *dest, const SAMPLETYPE *src,
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
while (fSlopeCount > 1.0f)
|
while (fSlopeCount > 1.0f)
|
||||||
{
|
{
|
||||||
fSlopeCount -= 1.0f;
|
fSlopeCount -= 1.0f;
|
||||||
used ++;
|
used ++;
|
||||||
|
@ -575,8 +573,8 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Transposes the sample rate of the given samples using linear interpolation.
|
// Transposes the sample rate of the given samples using linear interpolation.
|
||||||
// 'Mono' version of the routine. Returns the number of samples returned in
|
// 'Mono' version of the routine. Returns the number of samples returned in
|
||||||
// the "dest" buffer
|
// the "dest" buffer
|
||||||
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *src, uint nSamples)
|
||||||
{
|
{
|
||||||
|
@ -584,11 +582,11 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
|
||||||
|
|
||||||
if (nSamples == 0) return 0; // no samples, no work
|
if (nSamples == 0) return 0; // no samples, no work
|
||||||
|
|
||||||
used = 0;
|
used = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
// Process the last sample saved from the sPrevSampleLious call first...
|
// Process the last sample saved from the sPrevSampleLious call first...
|
||||||
while (fSlopeCount <= 1.0f)
|
while (fSlopeCount <= 1.0f)
|
||||||
{
|
{
|
||||||
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
|
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleL + fSlopeCount * src[0]);
|
||||||
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
|
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * sPrevSampleR + fSlopeCount * src[1]);
|
||||||
|
@ -602,7 +600,7 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
while (fSlopeCount > 1.0f)
|
while (fSlopeCount > 1.0f)
|
||||||
{
|
{
|
||||||
fSlopeCount -= 1.0f;
|
fSlopeCount -= 1.0f;
|
||||||
used ++;
|
used ++;
|
||||||
|
@ -610,9 +608,9 @@ uint RateTransposerFloat::transposeStereo(SAMPLETYPE *dest, const SAMPLETYPE *sr
|
||||||
}
|
}
|
||||||
srcPos = 2 * used;
|
srcPos = 2 * used;
|
||||||
|
|
||||||
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
|
dest[2 * i] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos]
|
||||||
+ fSlopeCount * src[srcPos + 2]);
|
+ fSlopeCount * src[srcPos + 2]);
|
||||||
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
|
dest[2 * i + 1] = (SAMPLETYPE)((1.0f - fSlopeCount) * src[srcPos + 1]
|
||||||
+ fSlopeCount * src[srcPos + 3]);
|
+ fSlopeCount * src[srcPos + 3]);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
/// Sample rate transposer. Changes sample rate by using linear interpolation
|
||||||
/// together with anti-alias filtering (first order interpolation with anti-
|
/// together with anti-alias filtering (first order interpolation with anti-
|
||||||
/// alias filtering should be quite adequate for this application).
|
/// alias filtering should be quite adequate for this application).
|
||||||
///
|
///
|
||||||
/// Use either of the derived classes of 'RateTransposerInteger' or
|
/// Use either of the derived classes of 'RateTransposerInteger' or
|
||||||
/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
|
/// 'RateTransposerFloat' for corresponding integer/floating point tranposing
|
||||||
/// algorithm implementation.
|
/// algorithm implementation.
|
||||||
///
|
///
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-21 18:00:14 +0200 (Sat, 21 Feb 2009) $
|
// Last changed : $Date: 2009-02-21 13:00:14 -0300 (sáb, 21 fev 2009) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: RateTransposer.h 63 2009-02-21 16:00:14Z oparviai $
|
// $Id: RateTransposer.h 63 2009-02-21 16:00:14Z oparviai $
|
||||||
|
@ -57,9 +57,9 @@ namespace soundtouch
|
||||||
|
|
||||||
/// A common linear samplerate transposer class.
|
/// A common linear samplerate transposer class.
|
||||||
///
|
///
|
||||||
/// Note: Use function "RateTransposer::newInstance()" to create a new class
|
/// Note: Use function "RateTransposer::newInstance()" to create a new class
|
||||||
/// instance instead of the "new" operator; that function automatically
|
/// instance instead of the "new" operator; that function automatically
|
||||||
/// chooses a correct implementation depending on if integer or floating
|
/// chooses a correct implementation depending on if integer or floating
|
||||||
/// arithmetics are to be used.
|
/// arithmetics are to be used.
|
||||||
class RateTransposer : public FIFOProcessor
|
class RateTransposer : public FIFOProcessor
|
||||||
{
|
{
|
||||||
|
@ -85,26 +85,26 @@ protected:
|
||||||
|
|
||||||
virtual void resetRegisters() = 0;
|
virtual void resetRegisters() = 0;
|
||||||
|
|
||||||
virtual uint transposeStereo(SAMPLETYPE *dest,
|
virtual uint transposeStereo(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples) = 0;
|
uint numSamples) = 0;
|
||||||
virtual uint transposeMono(SAMPLETYPE *dest,
|
virtual uint transposeMono(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples) = 0;
|
uint numSamples) = 0;
|
||||||
inline uint transpose(SAMPLETYPE *dest,
|
inline uint transpose(SAMPLETYPE *dest,
|
||||||
const SAMPLETYPE *src,
|
const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
|
|
||||||
void downsample(const SAMPLETYPE *src,
|
void downsample(const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
void upsample(const SAMPLETYPE *src,
|
void upsample(const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
|
|
||||||
/// Transposes sample rate by applying anti-alias filter to prevent folding.
|
/// Transposes sample rate by applying anti-alias filter to prevent folding.
|
||||||
/// Returns amount of samples returned in the "dest" buffer.
|
/// 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 maximum amount of samples that can be returned at a time is set by
|
||||||
/// the 'set_returnBuffer_size' function.
|
/// the 'set_returnBuffer_size' function.
|
||||||
void processSamples(const SAMPLETYPE *src,
|
void processSamples(const SAMPLETYPE *src,
|
||||||
uint numSamples);
|
uint numSamples);
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,12 +112,12 @@ public:
|
||||||
RateTransposer();
|
RateTransposer();
|
||||||
virtual ~RateTransposer();
|
virtual ~RateTransposer();
|
||||||
|
|
||||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
||||||
/// depending on if we're to use integer or floating point arithmetics.
|
/// depending on if we're to use integer or floating point arithmetics.
|
||||||
static void *operator new(size_t s);
|
static void *operator new(size_t s);
|
||||||
|
|
||||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
/// 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
|
/// This function automatically chooses a correct implementation, depending on if
|
||||||
/// integer ot floating point arithmetics are to be used.
|
/// integer ot floating point arithmetics are to be used.
|
||||||
static RateTransposer *newInstance();
|
static RateTransposer *newInstance();
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ public:
|
||||||
/// Returns nonzero if anti-alias filter is enabled.
|
/// Returns nonzero if anti-alias filter is enabled.
|
||||||
BOOL isAAFilterEnabled() const;
|
BOOL isAAFilterEnabled() const;
|
||||||
|
|
||||||
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
/// Sets new target rate. Normal rate = 1.0, smaller values represent slower
|
||||||
/// rate, larger faster rates.
|
/// rate, larger faster rates.
|
||||||
virtual void setRate(float newRate);
|
virtual void setRate(float newRate);
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-05-17 14:30:57 +0300 (Sun, 17 May 2009) $
|
// Last changed : $Date: 2012-12-28 12:53:56 -0200 (sex, 28 dez 2012) $
|
||||||
// File revision : $Revision: 3 $
|
// File revision : $Revision: 3 $
|
||||||
//
|
//
|
||||||
// $Id: STTypes.h 70 2009-05-17 11:30:57Z oparviai $
|
// $Id: STTypes.h 162 2012-12-28 14:53:56Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -42,8 +42,21 @@
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
typedef unsigned long ulong;
|
typedef unsigned long ulong;
|
||||||
|
|
||||||
#ifdef __GNUC__
|
// Patch for MinGW: on Win64 long is 32-bit
|
||||||
// In GCC, include soundtouch_config.h made by config scritps
|
#ifdef _WIN64
|
||||||
|
typedef unsigned long long ulongptr;
|
||||||
|
#else
|
||||||
|
typedef ulong ulongptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Helper macro for aligning pointer up to next 16-byte boundary
|
||||||
|
#define SOUNDTOUCH_ALIGN_POINTER_16(x) ( ( (ulongptr)(x) + 15 ) & ~(ulongptr)15 )
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined(__GNUC__) && !defined(ANDROID))
|
||||||
|
// In GCC, include soundtouch_config.h made by config scritps.
|
||||||
|
// Skip this in Android compilation that uses GCC but without configure scripts.
|
||||||
#include "soundtouch_config.h"
|
#include "soundtouch_config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -60,64 +73,81 @@ typedef unsigned long ulong;
|
||||||
|
|
||||||
namespace soundtouch
|
namespace soundtouch
|
||||||
{
|
{
|
||||||
|
/// Activate these undef's to overrule the possible sampletype
|
||||||
|
/// setting inherited from some other header file:
|
||||||
|
//#undef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
//#undef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
|
|
||||||
/// Activate these undef's to overrule the possible sampletype
|
#if (defined(__SOFTFP__))
|
||||||
/// setting inherited from some other header file:
|
// For Android compilation: Force use of Integer samples in case that
|
||||||
//#undef INTEGER_SAMPLES
|
// compilation uses soft-floating point emulation - soft-fp is way too slow
|
||||||
//#undef FLOAT_SAMPLES
|
#undef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
|
#define SOUNDTOUCH_INTEGER_SAMPLES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !(INTEGER_SAMPLES || FLOAT_SAMPLES)
|
#if !(SOUNDTOUCH_INTEGER_SAMPLES || SOUNDTOUCH_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 SOUNDTOUCH_INTEGER_SAMPLES 1 //< 16bit integer samples
|
||||||
|
#define SOUNDTOUCH_FLOAT_SAMPLES 1 //< 32bit float samples
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Choose either 32bit floating point or 16bit integer sampletype
|
#if (_M_IX86 || __i386__ || __x86_64__ || _M_X64)
|
||||||
/// by choosing one of the following defines, unless this selection
|
/// Define this to allow X86-specific assembler/intrinsic optimizations.
|
||||||
/// 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
|
|
||||||
|
|
||||||
#if (WIN32 || __i386__ || __x86_64__)
|
|
||||||
/// Define this to allow X86-specific assembler/intrinsic optimizations.
|
|
||||||
/// Notice that library contains also usual C++ versions of each of these
|
/// Notice that library contains also usual C++ versions of each of these
|
||||||
/// these routines, so if you're having difficulties getting the optimized
|
/// these routines, so if you're having difficulties getting the optimized
|
||||||
/// routines compiled for whatever reason, you may disable these optimizations
|
/// routines compiled for whatever reason, you may disable these optimizations
|
||||||
/// to make the library compile.
|
/// to make the library compile.
|
||||||
|
|
||||||
#define ALLOW_X86_OPTIMIZATIONS 1
|
#define SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS 1
|
||||||
|
|
||||||
|
/// In GNU environment, allow the user to override this setting by
|
||||||
|
/// giving the following switch to the configure script:
|
||||||
|
/// ./configure --disable-x86-optimizations
|
||||||
|
/// ./configure --enable-x86-optimizations=no
|
||||||
|
#ifdef SOUNDTOUCH_DISABLE_X86_OPTIMIZATIONS
|
||||||
|
#undef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/// Always disable optimizations when not using a x86 systems.
|
||||||
|
#undef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If defined, allows the SIMD-optimized routines to take minor shortcuts
|
// If defined, allows the SIMD-optimized routines to take minor shortcuts
|
||||||
// for improved performance. Undefine to require faithfully similar SIMD
|
// for improved performance. Undefine to require faithfully similar SIMD
|
||||||
// calculations as in normal C implementation.
|
// calculations as in normal C implementation.
|
||||||
#define ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
|
#define SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION 1
|
||||||
|
|
||||||
|
|
||||||
#ifdef INTEGER_SAMPLES
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
// 16bit integer sample type
|
// 16bit integer sample type
|
||||||
typedef short SAMPLETYPE;
|
typedef short SAMPLETYPE;
|
||||||
// data type for sample accumulation: Use 32bit integer to prevent overflows
|
// data type for sample accumulation: Use 32bit integer to prevent overflows
|
||||||
typedef long LONG_SAMPLETYPE;
|
typedef long LONG_SAMPLETYPE;
|
||||||
|
|
||||||
#ifdef FLOAT_SAMPLES
|
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
// check that only one sample type is defined
|
// check that only one sample type is defined
|
||||||
#error "conflicting sample types defined"
|
#error "conflicting sample types defined"
|
||||||
#endif // FLOAT_SAMPLES
|
#endif // SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
|
|
||||||
#ifdef ALLOW_X86_OPTIMIZATIONS
|
#ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
|
||||||
// Allow MMX optimizations
|
// Allow MMX optimizations
|
||||||
#define ALLOW_MMX 1
|
#define SOUNDTOUCH_ALLOW_MMX 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -127,23 +157,31 @@ namespace soundtouch
|
||||||
// data type for sample accumulation: Use double to utilize full precision.
|
// data type for sample accumulation: Use double to utilize full precision.
|
||||||
typedef double LONG_SAMPLETYPE;
|
typedef double LONG_SAMPLETYPE;
|
||||||
|
|
||||||
#ifdef ALLOW_X86_OPTIMIZATIONS
|
#ifdef SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS
|
||||||
// Allow 3DNow! and SSE optimizations
|
// Allow SSE optimizations
|
||||||
#if WIN32
|
#define SOUNDTOUCH_ALLOW_SSE 1
|
||||||
#define ALLOW_3DNOW 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ALLOW_SSE 1
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // INTEGER_SAMPLES
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// define ST_NO_EXCEPTION_HANDLING switch to disable throwing std exceptions:
|
||||||
|
// #define ST_NO_EXCEPTION_HANDLING 1
|
||||||
|
#ifdef ST_NO_EXCEPTION_HANDLING
|
||||||
|
// Exceptions disabled. Throw asserts instead if enabled.
|
||||||
|
#include <assert.h>
|
||||||
|
#define ST_THROW_RT_ERROR(x) {assert((const char *)x);}
|
||||||
|
#else
|
||||||
|
// use c++ standard exceptions
|
||||||
|
#include <stdexcept>
|
||||||
|
#define ST_THROW_RT_ERROR(x) {throw std::runtime_error(x);}
|
||||||
|
#endif
|
||||||
|
|
||||||
// When this #define is active, eliminates a clicking sound when the "rate" or "pitch"
|
// When this #define is active, eliminates a clicking sound when the "rate" or "pitch"
|
||||||
// parameter setting crosses from value <1 to >=1 or vice versa during processing.
|
// parameter setting crosses from value <1 to >=1 or vice versa during processing.
|
||||||
// Default is off as such crossover is untypical case and involves a slight sound
|
// Default is off as such crossover is untypical case and involves a slight sound
|
||||||
// quality compromise.
|
// quality compromise.
|
||||||
//#define PREVENT_CLICK_AT_RATE_CROSSOVER 1
|
//#define SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||||
///
|
///
|
||||||
/// Notes:
|
/// Notes:
|
||||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||||
///
|
///
|
||||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
/// - 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
|
/// 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
|
/// function 'putSamples', while the ready processed samples can be read
|
||||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||||
///
|
///
|
||||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||||
/// samples in order to process the sound. For this reason the classes buffer
|
/// samples in order to process the sound. For this reason the classes buffer
|
||||||
/// incoming samples until there are enough of samples available for
|
/// incoming samples until there are enough of samples available for
|
||||||
/// processing, then they carry out the processing step and consequently
|
/// processing, then they carry out the processing step and consequently
|
||||||
/// make the processed samples available for outputting.
|
/// make the processed samples available for outputting.
|
||||||
///
|
///
|
||||||
/// - For the above reason, the processing routines introduce a certain
|
/// - For the above reason, the processing routines introduce a certain
|
||||||
/// 'latency' between the input and output, so that the samples input to
|
/// 'latency' between the input and output, so that the samples input to
|
||||||
/// SoundTouch may not be immediately available in the output, and neither
|
/// SoundTouch may not be immediately available in the output, and neither
|
||||||
/// the amount of outputtable samples may not immediately be in direct
|
/// the amount of outputtable samples may not immediately be in direct
|
||||||
/// relationship with the amount of previously input samples.
|
/// relationship with the amount of previously input samples.
|
||||||
///
|
///
|
||||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
/// required.
|
/// required.
|
||||||
///
|
///
|
||||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
/// 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
|
/// 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
|
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||||
/// combining the two other controls.
|
/// combining the two other controls.
|
||||||
///
|
///
|
||||||
|
@ -41,10 +41,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-05-19 07:57:30 +0300 (Tue, 19 May 2009) $
|
// Last changed : $Date: 2012-06-13 16:29:53 -0300 (qua, 13 jun 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: SoundTouch.cpp 73 2009-05-19 04:57:30Z oparviai $
|
// $Id: SoundTouch.cpp 143 2012-06-13 19:29:53Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -73,7 +73,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdexcept>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "SoundTouch.h"
|
#include "SoundTouch.h"
|
||||||
|
@ -82,7 +81,7 @@
|
||||||
#include "cpu_detect.h"
|
#include "cpu_detect.h"
|
||||||
|
|
||||||
using namespace soundtouch;
|
using namespace soundtouch;
|
||||||
|
|
||||||
/// test if two floating point numbers are equal
|
/// test if two floating point numbers are equal
|
||||||
#define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10)
|
#define TEST_FLOAT_EQUAL(a, b) (fabs(a - b) < 1e-10)
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ using namespace soundtouch;
|
||||||
extern "C" void soundtouch_ac_test()
|
extern "C" void soundtouch_ac_test()
|
||||||
{
|
{
|
||||||
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
|
printf("SoundTouch Version: %s\n",SOUNDTOUCH_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SoundTouch::SoundTouch()
|
SoundTouch::SoundTouch()
|
||||||
|
@ -105,8 +104,8 @@ SoundTouch::SoundTouch()
|
||||||
|
|
||||||
rate = tempo = 0;
|
rate = tempo = 0;
|
||||||
|
|
||||||
virtualPitch =
|
virtualPitch =
|
||||||
virtualRate =
|
virtualRate =
|
||||||
virtualTempo = 1.0;
|
virtualTempo = 1.0;
|
||||||
|
|
||||||
calcEffectiveRateAndTempo();
|
calcEffectiveRateAndTempo();
|
||||||
|
@ -144,9 +143,9 @@ uint SoundTouch::getVersionId()
|
||||||
// Sets the number of channels, 1 = mono, 2 = stereo
|
// Sets the number of channels, 1 = mono, 2 = stereo
|
||||||
void SoundTouch::setChannels(uint numChannels)
|
void SoundTouch::setChannels(uint numChannels)
|
||||||
{
|
{
|
||||||
if (numChannels != 1 && numChannels != 2)
|
if (numChannels != 1 && numChannels != 2)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Illegal number of channels");
|
ST_THROW_RT_ERROR("Illegal number of channels");
|
||||||
}
|
}
|
||||||
channels = numChannels;
|
channels = numChannels;
|
||||||
pRateTransposer->setChannels((int)numChannels);
|
pRateTransposer->setChannels((int)numChannels);
|
||||||
|
@ -243,10 +242,10 @@ void SoundTouch::calcEffectiveRateAndTempo()
|
||||||
if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
|
if (!TEST_FLOAT_EQUAL(rate,oldRate)) pRateTransposer->setRate(rate);
|
||||||
if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
|
if (!TEST_FLOAT_EQUAL(tempo, oldTempo)) pTDStretch->setTempo(tempo);
|
||||||
|
|
||||||
#ifndef PREVENT_CLICK_AT_RATE_CROSSOVER
|
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||||
if (rate <= 1.0f)
|
if (rate <= 1.0f)
|
||||||
{
|
{
|
||||||
if (output != pTDStretch)
|
if (output != pTDStretch)
|
||||||
{
|
{
|
||||||
FIFOSamplePipe *tempoOut;
|
FIFOSamplePipe *tempoOut;
|
||||||
|
|
||||||
|
@ -263,7 +262,7 @@ void SoundTouch::calcEffectiveRateAndTempo()
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (output != pRateTransposer)
|
if (output != pRateTransposer)
|
||||||
{
|
{
|
||||||
FIFOSamplePipe *transOut;
|
FIFOSamplePipe *transOut;
|
||||||
|
|
||||||
|
@ -276,7 +275,7 @@ void SoundTouch::calcEffectiveRateAndTempo()
|
||||||
|
|
||||||
output = pRateTransposer;
|
output = pRateTransposer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -293,42 +292,42 @@ void SoundTouch::setSampleRate(uint srate)
|
||||||
// the input of the object.
|
// the input of the object.
|
||||||
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||||
{
|
{
|
||||||
if (bSrateSet == FALSE)
|
if (bSrateSet == FALSE)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("SoundTouch : Sample rate not defined");
|
ST_THROW_RT_ERROR("SoundTouch : Sample rate not defined");
|
||||||
}
|
}
|
||||||
else if (channels == 0)
|
else if (channels == 0)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("SoundTouch : Number of channels not defined");
|
ST_THROW_RT_ERROR("SoundTouch : Number of channels not defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transpose the rate of the new samples if necessary
|
// 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...
|
/* Bypass the nominal setting - can introduce a click in sound when tempo/pitch control crosses the nominal value...
|
||||||
if (rate == 1.0f)
|
if (rate == 1.0f)
|
||||||
{
|
{
|
||||||
// The rate value is same as the original, simply evaluate the tempo changer.
|
// The rate value is same as the original, simply evaluate the tempo changer.
|
||||||
assert(output == pTDStretch);
|
assert(output == pTDStretch);
|
||||||
if (pRateTransposer->isEmpty() == 0)
|
if (pRateTransposer->isEmpty() == 0)
|
||||||
{
|
{
|
||||||
// yet flush the last samples in the pitch transposer buffer
|
// yet flush the last samples in the pitch transposer buffer
|
||||||
// (may happen if 'rate' changes from a non-zero value to zero)
|
// (may happen if 'rate' changes from a non-zero value to zero)
|
||||||
pTDStretch->moveSamples(*pRateTransposer);
|
pTDStretch->moveSamples(*pRateTransposer);
|
||||||
}
|
}
|
||||||
pTDStretch->putSamples(samples, nSamples);
|
pTDStretch->putSamples(samples, nSamples);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
#ifndef PREVENT_CLICK_AT_RATE_CROSSOVER
|
#ifndef SOUNDTOUCH_PREVENT_CLICK_AT_RATE_CROSSOVER
|
||||||
else if (rate <= 1.0f)
|
else if (rate <= 1.0f)
|
||||||
{
|
{
|
||||||
// transpose the rate down, output the transposed sound to tempo changer buffer
|
// transpose the rate down, output the transposed sound to tempo changer buffer
|
||||||
assert(output == pTDStretch);
|
assert(output == pTDStretch);
|
||||||
pRateTransposer->putSamples(samples, nSamples);
|
pRateTransposer->putSamples(samples, nSamples);
|
||||||
pTDStretch->moveSamples(*pRateTransposer);
|
pTDStretch->moveSamples(*pRateTransposer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// evaluate the tempo changer, then transpose the rate up,
|
// evaluate the tempo changer, then transpose the rate up,
|
||||||
assert(output == pRateTransposer);
|
assert(output == pRateTransposer);
|
||||||
pTDStretch->putSamples(samples, nSamples);
|
pTDStretch->putSamples(samples, nSamples);
|
||||||
pRateTransposer->moveSamples(*pTDStretch);
|
pRateTransposer->moveSamples(*pTDStretch);
|
||||||
|
@ -346,20 +345,36 @@ void SoundTouch::putSamples(const SAMPLETYPE *samples, uint nSamples)
|
||||||
void SoundTouch::flush()
|
void SoundTouch::flush()
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint nOut;
|
int nUnprocessed;
|
||||||
SAMPLETYPE buff[128];
|
int nOut;
|
||||||
|
SAMPLETYPE buff[64*2]; // note: allocate 2*64 to cater 64 sample frames of stereo sound
|
||||||
|
|
||||||
nOut = numSamples();
|
// check how many samples still await processing, and scale
|
||||||
|
// that by tempo & rate to get expected output sample count
|
||||||
|
nUnprocessed = numUnprocessedSamples();
|
||||||
|
nUnprocessed = (int)((double)nUnprocessed / (tempo * rate) + 0.5);
|
||||||
|
|
||||||
memset(buff, 0, 128 * sizeof(SAMPLETYPE));
|
nOut = numSamples(); // ready samples currently in buffer ...
|
||||||
|
nOut += nUnprocessed; // ... and how many we expect there to be in the end
|
||||||
|
|
||||||
|
memset(buff, 0, 64 * channels * sizeof(SAMPLETYPE));
|
||||||
// "Push" the last active samples out from the processing pipeline by
|
// "Push" the last active samples out from the processing pipeline by
|
||||||
// feeding blank samples into the processing pipeline until new,
|
// feeding blank samples into the processing pipeline until new,
|
||||||
// processed samples appear in the output (not however, more than
|
// processed samples appear in the output (not however, more than
|
||||||
// 8ksamples in any case)
|
// 8ksamples in any case)
|
||||||
for (i = 0; i < 128; i ++)
|
for (i = 0; i < 128; i ++)
|
||||||
{
|
{
|
||||||
putSamples(buff, 64);
|
putSamples(buff, 64);
|
||||||
if (numSamples() != nOut) break; // new samples have appeared in the output!
|
if ((int)numSamples() >= nOut)
|
||||||
|
{
|
||||||
|
// Enough new samples have appeared into the output!
|
||||||
|
// As samples come from processing with bigger chunks, now truncate it
|
||||||
|
// back to maximum "nOut" samples to improve duration accuracy
|
||||||
|
adjustAmountOfSamples(nOut);
|
||||||
|
|
||||||
|
// finish
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear working buffers
|
// Clear working buffers
|
||||||
|
@ -379,7 +394,7 @@ BOOL SoundTouch::setSetting(int settingId, int value)
|
||||||
// read current tdstretch routine parameters
|
// read current tdstretch routine parameters
|
||||||
pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
|
pTDStretch->getParameters(&sampleRate, &sequenceMs, &seekWindowMs, &overlapMs);
|
||||||
|
|
||||||
switch (settingId)
|
switch (settingId)
|
||||||
{
|
{
|
||||||
case SETTING_USE_AA_FILTER :
|
case SETTING_USE_AA_FILTER :
|
||||||
// enables / disabless anti-alias filter
|
// enables / disabless anti-alias filter
|
||||||
|
@ -425,7 +440,7 @@ int SoundTouch::getSetting(int settingId) const
|
||||||
{
|
{
|
||||||
int temp;
|
int temp;
|
||||||
|
|
||||||
switch (settingId)
|
switch (settingId)
|
||||||
{
|
{
|
||||||
case SETTING_USE_AA_FILTER :
|
case SETTING_USE_AA_FILTER :
|
||||||
return (uint)pRateTransposer->isAAFilterEnabled();
|
return (uint)pRateTransposer->isAAFilterEnabled();
|
||||||
|
@ -448,7 +463,13 @@ int SoundTouch::getSetting(int settingId) const
|
||||||
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
|
pTDStretch->getParameters(NULL, NULL, NULL, &temp);
|
||||||
return temp;
|
return temp;
|
||||||
|
|
||||||
default :
|
case SETTING_NOMINAL_INPUT_SEQUENCE :
|
||||||
|
return pTDStretch->getInputSampleReq();
|
||||||
|
|
||||||
|
case SETTING_NOMINAL_OUTPUT_SEQUENCE :
|
||||||
|
return pTDStretch->getOutputBatchSize();
|
||||||
|
|
||||||
|
default :
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
/// SoundTouch - main class for tempo/pitch/rate adjusting routines.
|
||||||
///
|
///
|
||||||
/// Notes:
|
/// Notes:
|
||||||
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
/// - Initialize the SoundTouch object instance by setting up the sound stream
|
||||||
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
/// parameters with functions 'setSampleRate' and 'setChannels', then set
|
||||||
/// desired tempo/pitch/rate settings with the corresponding functions.
|
/// desired tempo/pitch/rate settings with the corresponding functions.
|
||||||
///
|
///
|
||||||
/// - The SoundTouch class behaves like a first-in-first-out pipeline: The
|
/// - 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
|
/// 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
|
/// function 'putSamples', while the ready processed samples can be read
|
||||||
/// from the other end of the pipeline with function 'receiveSamples'.
|
/// from the other end of the pipeline with function 'receiveSamples'.
|
||||||
///
|
///
|
||||||
/// - The SoundTouch processing classes require certain sized 'batches' of
|
/// - The SoundTouch processing classes require certain sized 'batches' of
|
||||||
/// samples in order to process the sound. For this reason the classes buffer
|
/// samples in order to process the sound. For this reason the classes buffer
|
||||||
/// incoming samples until there are enough of samples available for
|
/// incoming samples until there are enough of samples available for
|
||||||
/// processing, then they carry out the processing step and consequently
|
/// processing, then they carry out the processing step and consequently
|
||||||
/// make the processed samples available for outputting.
|
/// make the processed samples available for outputting.
|
||||||
///
|
///
|
||||||
/// - For the above reason, the processing routines introduce a certain
|
/// - For the above reason, the processing routines introduce a certain
|
||||||
/// 'latency' between the input and output, so that the samples input to
|
/// 'latency' between the input and output, so that the samples input to
|
||||||
/// SoundTouch may not be immediately available in the output, and neither
|
/// SoundTouch may not be immediately available in the output, and neither
|
||||||
/// the amount of outputtable samples may not immediately be in direct
|
/// the amount of outputtable samples may not immediately be in direct
|
||||||
/// relationship with the amount of previously input samples.
|
/// relationship with the amount of previously input samples.
|
||||||
///
|
///
|
||||||
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
/// - The tempo/pitch/rate control parameters can be altered during processing.
|
||||||
|
@ -30,8 +30,8 @@
|
||||||
/// required.
|
/// required.
|
||||||
///
|
///
|
||||||
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
/// - This class utilizes classes 'TDStretch' for tempo change (without modifying
|
||||||
/// pitch) and 'RateTransposer' for changing the playback rate (that is, both
|
/// 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
|
/// 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
|
/// 'pitch' (change pitch but maintain tempo) is produced by a combination of
|
||||||
/// combining the two other controls.
|
/// combining the two other controls.
|
||||||
///
|
///
|
||||||
|
@ -41,10 +41,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-12-28 22:10:14 +0200 (Mon, 28 Dec 2009) $
|
// Last changed : $Date: 2012-12-28 17:32:59 -0200 (sex, 28 dez 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: SoundTouch.h 78 2009-12-28 20:10:14Z oparviai $
|
// $Id: SoundTouch.h 163 2012-12-28 19:32:59Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -79,10 +79,10 @@ namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Soundtouch library version string
|
/// Soundtouch library version string
|
||||||
#define SOUNDTOUCH_VERSION "1.5.0"
|
#define SOUNDTOUCH_VERSION "1.7.1"
|
||||||
|
|
||||||
/// SoundTouch library version id
|
/// SoundTouch library version id
|
||||||
#define SOUNDTOUCH_VERSION_ID (10500)
|
#define SOUNDTOUCH_VERSION_ID (10701)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
// Available setting IDs for the 'setSetting' & 'get_setting' functions:
|
||||||
|
@ -98,24 +98,49 @@ namespace soundtouch
|
||||||
/// quality compromising)
|
/// quality compromising)
|
||||||
#define SETTING_USE_QUICKSEEK 2
|
#define SETTING_USE_QUICKSEEK 2
|
||||||
|
|
||||||
/// Time-stretch algorithm single processing sequence length in milliseconds. This determines
|
/// 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.
|
/// to how long sequences the original sound is chopped in the time-stretch algorithm.
|
||||||
/// See "STTypes.h" or README for more information.
|
/// See "STTypes.h" or README for more information.
|
||||||
#define SETTING_SEQUENCE_MS 3
|
#define SETTING_SEQUENCE_MS 3
|
||||||
|
|
||||||
/// Time-stretch algorithm seeking window length in milliseconds for algorithm that finds the
|
/// 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
|
/// 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.
|
/// may look for an optimal joining location when mixing the sound sequences back together.
|
||||||
/// See "STTypes.h" or README for more information.
|
/// See "STTypes.h" or README for more information.
|
||||||
#define SETTING_SEEKWINDOW_MS 4
|
#define SETTING_SEEKWINDOW_MS 4
|
||||||
|
|
||||||
/// Time-stretch algorithm overlap length in milliseconds. When the chopped sound sequences
|
/// 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
|
/// 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.
|
/// how long period the two consecutive sequences are let to overlap each other.
|
||||||
/// See "STTypes.h" or README for more information.
|
/// See "STTypes.h" or README for more information.
|
||||||
#define SETTING_OVERLAP_MS 5
|
#define SETTING_OVERLAP_MS 5
|
||||||
|
|
||||||
|
|
||||||
|
/// Call "getSetting" with this ID to query nominal average processing sequence
|
||||||
|
/// size in samples. This value tells approcimate value how many input samples
|
||||||
|
/// SoundTouch needs to gather before it does DSP processing run for the sample batch.
|
||||||
|
///
|
||||||
|
/// Notices:
|
||||||
|
/// - This is read-only parameter, i.e. setSetting ignores this parameter
|
||||||
|
/// - Returned value is approximate average value, exact processing batch
|
||||||
|
/// size may wary from time to time
|
||||||
|
/// - This parameter value is not constant but may change depending on
|
||||||
|
/// tempo/pitch/rate/samplerate settings.
|
||||||
|
#define SETTING_NOMINAL_INPUT_SEQUENCE 6
|
||||||
|
|
||||||
|
|
||||||
|
/// Call "getSetting" with this ID to query nominal average processing output
|
||||||
|
/// size in samples. This value tells approcimate value how many output samples
|
||||||
|
/// SoundTouch outputs once it does DSP processing run for a batch of input samples.
|
||||||
|
///
|
||||||
|
/// Notices:
|
||||||
|
/// - This is read-only parameter, i.e. setSetting ignores this parameter
|
||||||
|
/// - Returned value is approximate average value, exact processing batch
|
||||||
|
/// size may wary from time to time
|
||||||
|
/// - This parameter value is not constant but may change depending on
|
||||||
|
/// tempo/pitch/rate/samplerate settings.
|
||||||
|
#define SETTING_NOMINAL_OUTPUT_SEQUENCE 7
|
||||||
|
|
||||||
class SoundTouch : public FIFOProcessor
|
class SoundTouch : public FIFOProcessor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -137,7 +162,7 @@ private:
|
||||||
/// Flag: Has sample rate been set?
|
/// Flag: Has sample rate been set?
|
||||||
BOOL bSrateSet;
|
BOOL bSrateSet;
|
||||||
|
|
||||||
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
|
/// Calculates effective rate & tempo valuescfrom 'virtualRate', 'virtualTempo' and
|
||||||
/// 'virtualPitch' parameters.
|
/// 'virtualPitch' parameters.
|
||||||
void calcEffectiveRateAndTempo();
|
void calcEffectiveRateAndTempo();
|
||||||
|
|
||||||
|
@ -181,7 +206,7 @@ public:
|
||||||
/// represent lower pitches, larger values higher pitch.
|
/// represent lower pitches, larger values higher pitch.
|
||||||
void setPitch(float newPitch);
|
void setPitch(float newPitch);
|
||||||
|
|
||||||
/// Sets pitch change in octaves compared to the original pitch
|
/// Sets pitch change in octaves compared to the original pitch
|
||||||
/// (-1.00 .. +1.00)
|
/// (-1.00 .. +1.00)
|
||||||
void setPitchOctaves(float newPitch);
|
void setPitchOctaves(float newPitch);
|
||||||
|
|
||||||
|
@ -221,7 +246,7 @@ public:
|
||||||
|
|
||||||
/// Changes a setting controlling the processing system behaviour. See the
|
/// Changes a setting controlling the processing system behaviour. See the
|
||||||
/// 'SETTING_...' defines for available setting ID's.
|
/// 'SETTING_...' defines for available setting ID's.
|
||||||
///
|
///
|
||||||
/// \return 'TRUE' if the setting was succesfully changed
|
/// \return 'TRUE' if the setting was succesfully changed
|
||||||
BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines.
|
BOOL setSetting(int settingId, ///< Setting ID number. see SETTING_... defines.
|
||||||
int value ///< New setting value.
|
int value ///< New setting value.
|
||||||
|
@ -242,7 +267,7 @@ public:
|
||||||
/// classes 'FIFOProcessor' and 'FIFOSamplePipe')
|
/// classes 'FIFOProcessor' and 'FIFOSamplePipe')
|
||||||
///
|
///
|
||||||
/// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
|
/// - receiveSamples() : Use this function to receive 'ready' processed samples from SoundTouch.
|
||||||
/// - numSamples() : Get number of 'ready' samples that can be received with
|
/// - numSamples() : Get number of 'ready' samples that can be received with
|
||||||
/// function 'receiveSamples()'
|
/// function 'receiveSamples()'
|
||||||
/// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
|
/// - isEmpty() : Returns nonzero if there aren't any 'ready' samples.
|
||||||
/// - clear() : Clears all samples from ready/processing buffers.
|
/// - clear() : Clears all samples from ready/processing buffers.
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||||
/// while maintaining the original pitch by using a time domain WSOLA-like
|
/// while maintaining the original pitch by using a time domain WSOLA-like
|
||||||
/// method with several performance-increasing tweaks.
|
/// method with several performance-increasing tweaks.
|
||||||
///
|
///
|
||||||
/// Note : MMX optimized functions reside in a separate, platform-specific
|
/// Note : MMX optimized functions reside in a separate, platform-specific
|
||||||
/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
/// file, e.g. 'mmx_win.cpp' or 'mmx_gcc.cpp'
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-12-28 21:27:04 +0200 (Mon, 28 Dec 2009) $
|
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
|
||||||
// File revision : $Revision: 1.12 $
|
// File revision : $Revision: 1.12 $
|
||||||
//
|
//
|
||||||
// $Id: TDStretch.cpp 77 2009-12-28 19:27:04Z oparviai $
|
// $Id: TDStretch.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -46,7 +46,6 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
#include "STTypes.h"
|
#include "STTypes.h"
|
||||||
#include "cpu_detect.h"
|
#include "cpu_detect.h"
|
||||||
|
@ -91,7 +90,7 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
|
||||||
channels = 2;
|
channels = 2;
|
||||||
|
|
||||||
pMidBuffer = NULL;
|
pMidBuffer = NULL;
|
||||||
pRefMidBufferUnaligned = NULL;
|
pMidBufferUnaligned = NULL;
|
||||||
overlapLength = 0;
|
overlapLength = 0;
|
||||||
|
|
||||||
bAutoSeqSetting = TRUE;
|
bAutoSeqSetting = TRUE;
|
||||||
|
@ -101,7 +100,7 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
|
||||||
skipFract = 0;
|
skipFract = 0;
|
||||||
|
|
||||||
tempo = 1.0f;
|
tempo = 1.0f;
|
||||||
setParameters(48000, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
|
setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
|
||||||
setTempo(1.0f);
|
setTempo(1.0f);
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
|
@ -111,8 +110,7 @@ TDStretch::TDStretch() : FIFOProcessor(&outputBuffer)
|
||||||
|
|
||||||
TDStretch::~TDStretch()
|
TDStretch::~TDStretch()
|
||||||
{
|
{
|
||||||
delete[] pMidBuffer;
|
delete[] pMidBufferUnaligned;
|
||||||
delete[] pRefMidBufferUnaligned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -122,11 +120,11 @@ TDStretch::~TDStretch()
|
||||||
//
|
//
|
||||||
// 'sampleRate' = sample rate of the sound
|
// 'sampleRate' = sample rate of the sound
|
||||||
// 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
|
// 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
|
||||||
// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
||||||
// position (default = 28 ms)
|
// position (default = 28 ms)
|
||||||
// 'overlapMS' = overlapping length (default = 12 ms)
|
// 'overlapMS' = overlapping length (default = 12 ms)
|
||||||
|
|
||||||
void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
|
void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
|
||||||
int aSeekWindowMS, int aOverlapMS)
|
int aSeekWindowMS, int aOverlapMS)
|
||||||
{
|
{
|
||||||
// accept only positive parameter values - if zero or negative, use old values instead
|
// accept only positive parameter values - if zero or negative, use old values instead
|
||||||
|
@ -137,19 +135,19 @@ void TDStretch::setParameters(int aSampleRate, int aSequenceMS,
|
||||||
{
|
{
|
||||||
this->sequenceMs = aSequenceMS;
|
this->sequenceMs = aSequenceMS;
|
||||||
bAutoSeqSetting = FALSE;
|
bAutoSeqSetting = FALSE;
|
||||||
}
|
}
|
||||||
else if (aSequenceMS == 0)
|
else if (aSequenceMS == 0)
|
||||||
{
|
{
|
||||||
// if zero, use automatic setting
|
// if zero, use automatic setting
|
||||||
bAutoSeqSetting = TRUE;
|
bAutoSeqSetting = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aSeekWindowMS > 0)
|
if (aSeekWindowMS > 0)
|
||||||
{
|
{
|
||||||
this->seekWindowMs = aSeekWindowMS;
|
this->seekWindowMs = aSeekWindowMS;
|
||||||
bAutoSeekSetting = FALSE;
|
bAutoSeekSetting = FALSE;
|
||||||
}
|
}
|
||||||
else if (aSeekWindowMS == 0)
|
else if (aSeekWindowMS == 0)
|
||||||
{
|
{
|
||||||
// if zero, use automatic setting
|
// if zero, use automatic setting
|
||||||
bAutoSeekSetting = TRUE;
|
bAutoSeekSetting = TRUE;
|
||||||
|
@ -196,12 +194,17 @@ void TDStretch::getParameters(int *pSampleRate, int *pSequenceMs, int *pSeekWind
|
||||||
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
|
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
|
||||||
void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
|
void TDStretch::overlapMono(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput) const
|
||||||
{
|
{
|
||||||
int i, itemp;
|
int i;
|
||||||
|
SAMPLETYPE m1, m2;
|
||||||
|
|
||||||
for (i = 0; i < overlapLength ; i ++)
|
m1 = (SAMPLETYPE)0;
|
||||||
|
m2 = (SAMPLETYPE)overlapLength;
|
||||||
|
|
||||||
|
for (i = 0; i < overlapLength ; i ++)
|
||||||
{
|
{
|
||||||
itemp = overlapLength - i;
|
pOutput[i] = (pInput[i] * m1 + pMidBuffer[i] * m2 ) / overlapLength;
|
||||||
pOutput[i] = (pInput[i] * i + pMidBuffer[i] * itemp ) / overlapLength; // >> overlapDividerBits;
|
m1 += 1;
|
||||||
|
m2 -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,40 +250,22 @@ BOOL TDStretch::isQuickSeekEnabled() const
|
||||||
// Seeks for the optimal overlap-mixing position.
|
// Seeks for the optimal overlap-mixing position.
|
||||||
int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
|
int TDStretch::seekBestOverlapPosition(const SAMPLETYPE *refPos)
|
||||||
{
|
{
|
||||||
if (channels == 2)
|
if (bQuickSeek)
|
||||||
{
|
{
|
||||||
// stereo sound
|
return seekBestOverlapPositionQuick(refPos);
|
||||||
if (bQuickSeek)
|
}
|
||||||
{
|
else
|
||||||
return seekBestOverlapPositionStereoQuick(refPos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return seekBestOverlapPositionStereo(refPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// mono sound
|
return seekBestOverlapPositionFull(refPos);
|
||||||
if (bQuickSeek)
|
|
||||||
{
|
|
||||||
return seekBestOverlapPositionMonoQuick(refPos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return seekBestOverlapPositionMono(refPos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
|
// Overlaps samples in 'midBuffer' with the samples in 'pInputBuffer' at position
|
||||||
// of 'ovlPos'.
|
// of 'ovlPos'.
|
||||||
inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
|
inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, uint ovlPos) const
|
||||||
{
|
{
|
||||||
if (channels == 2)
|
if (channels == 2)
|
||||||
{
|
{
|
||||||
// stereo sound
|
// stereo sound
|
||||||
overlapStereo(pOutput, pInput + 2 * ovlPos);
|
overlapStereo(pOutput, pInput + 2 * ovlPos);
|
||||||
|
@ -292,38 +277,34 @@ inline void TDStretch::overlap(SAMPLETYPE *pOutput, const SAMPLETYPE *pInput, ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
|
// Seeks for the optimal overlap-mixing position. The 'stereo' version of the
|
||||||
// routine
|
// routine
|
||||||
//
|
//
|
||||||
// The best position is determined as the position where the two overlapped
|
// The best position is determined as the position where the two overlapped
|
||||||
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
||||||
// value over the overlapping period
|
// value over the overlapping period
|
||||||
int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos)
|
int TDStretch::seekBestOverlapPositionFull(const SAMPLETYPE *refPos)
|
||||||
{
|
{
|
||||||
int bestOffs;
|
int bestOffs;
|
||||||
double bestCorr, corr;
|
double bestCorr, corr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Slopes the amplitudes of the 'midBuffer' samples
|
|
||||||
precalcCorrReferenceStereo();
|
|
||||||
|
|
||||||
bestCorr = FLT_MIN;
|
bestCorr = FLT_MIN;
|
||||||
bestOffs = 0;
|
bestOffs = 0;
|
||||||
|
|
||||||
// Scans for the best correlation value by testing each possible position
|
// Scans for the best correlation value by testing each possible position
|
||||||
// over the permitted range.
|
// over the permitted range.
|
||||||
for (i = 0; i < seekLength; i ++)
|
for (i = 0; i < seekLength; i ++)
|
||||||
{
|
{
|
||||||
// Calculates correlation value for the mixing position corresponding
|
// Calculates correlation value for the mixing position corresponding
|
||||||
// to 'i'
|
// to 'i'
|
||||||
corr = (double)calcCrossCorrStereo(refPos + 2 * i, pRefMidBuffer);
|
corr = calcCrossCorr(refPos + channels * i, pMidBuffer);
|
||||||
// heuristic rule to slightly favour values close to mid of the range
|
// heuristic rule to slightly favour values close to mid of the range
|
||||||
double tmp = (double)(2 * i - seekLength) / (double)seekLength;
|
double tmp = (double)(2 * i - seekLength) / (double)seekLength;
|
||||||
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
||||||
|
|
||||||
// Checks for the highest correlation value
|
// Checks for the highest correlation value
|
||||||
if (corr > bestCorr)
|
if (corr > bestCorr)
|
||||||
{
|
{
|
||||||
bestCorr = corr;
|
bestCorr = corr;
|
||||||
bestOffs = i;
|
bestOffs = i;
|
||||||
|
@ -342,16 +323,13 @@ int TDStretch::seekBestOverlapPositionStereo(const SAMPLETYPE *refPos)
|
||||||
// The best position is determined as the position where the two overlapped
|
// The best position is determined as the position where the two overlapped
|
||||||
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
||||||
// value over the overlapping period
|
// value over the overlapping period
|
||||||
int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos)
|
int TDStretch::seekBestOverlapPositionQuick(const SAMPLETYPE *refPos)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
int bestOffs;
|
int bestOffs;
|
||||||
double bestCorr, corr;
|
double bestCorr, corr;
|
||||||
int scanCount, corrOffset, tempOffset;
|
int scanCount, corrOffset, tempOffset;
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples
|
|
||||||
precalcCorrReferenceStereo();
|
|
||||||
|
|
||||||
bestCorr = FLT_MIN;
|
bestCorr = FLT_MIN;
|
||||||
bestOffs = _scanOffsets[0][0];
|
bestOffs = _scanOffsets[0][0];
|
||||||
corrOffset = 0;
|
corrOffset = 0;
|
||||||
|
@ -360,26 +338,26 @@ int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos)
|
||||||
// Scans for the best correlation value using four-pass hierarchical search.
|
// Scans for the best correlation value using four-pass hierarchical search.
|
||||||
//
|
//
|
||||||
// The look-up table 'scans' has hierarchical position adjusting steps.
|
// The look-up table 'scans' has hierarchical position adjusting steps.
|
||||||
// In first pass the routine searhes for the highest correlation with
|
// In first pass the routine searhes for the highest correlation with
|
||||||
// relatively coarse steps, then rescans the neighbourhood of the highest
|
// relatively coarse steps, then rescans the neighbourhood of the highest
|
||||||
// correlation with better resolution and so on.
|
// correlation with better resolution and so on.
|
||||||
for (scanCount = 0;scanCount < 4; scanCount ++)
|
for (scanCount = 0;scanCount < 4; scanCount ++)
|
||||||
{
|
{
|
||||||
j = 0;
|
j = 0;
|
||||||
while (_scanOffsets[scanCount][j])
|
while (_scanOffsets[scanCount][j])
|
||||||
{
|
{
|
||||||
tempOffset = corrOffset + _scanOffsets[scanCount][j];
|
tempOffset = corrOffset + _scanOffsets[scanCount][j];
|
||||||
if (tempOffset >= seekLength) break;
|
if (tempOffset >= seekLength) break;
|
||||||
|
|
||||||
// Calculates correlation value for the mixing position corresponding
|
// Calculates correlation value for the mixing position corresponding
|
||||||
// to 'tempOffset'
|
// to 'tempOffset'
|
||||||
corr = (double)calcCrossCorrStereo(refPos + 2 * tempOffset, pRefMidBuffer);
|
corr = (double)calcCrossCorr(refPos + channels * tempOffset, pMidBuffer);
|
||||||
// heuristic rule to slightly favour values close to mid of the range
|
// heuristic rule to slightly favour values close to mid of the range
|
||||||
double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
|
double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
|
||||||
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
||||||
|
|
||||||
// Checks for the highest correlation value
|
// Checks for the highest correlation value
|
||||||
if (corr > bestCorr)
|
if (corr > bestCorr)
|
||||||
{
|
{
|
||||||
bestCorr = corr;
|
bestCorr = corr;
|
||||||
bestOffs = tempOffset;
|
bestOffs = tempOffset;
|
||||||
|
@ -396,112 +374,7 @@ int TDStretch::seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Seeks for the optimal overlap-mixing position. The 'mono' version of the
|
/// clear cross correlation routine state if necessary
|
||||||
// routine
|
|
||||||
//
|
|
||||||
// The best position is determined as the position where the two overlapped
|
|
||||||
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
|
||||||
// value over the overlapping period
|
|
||||||
int TDStretch::seekBestOverlapPositionMono(const SAMPLETYPE *refPos)
|
|
||||||
{
|
|
||||||
int bestOffs;
|
|
||||||
double bestCorr, corr;
|
|
||||||
int tempOffset;
|
|
||||||
const SAMPLETYPE *compare;
|
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples
|
|
||||||
precalcCorrReferenceMono();
|
|
||||||
|
|
||||||
bestCorr = FLT_MIN;
|
|
||||||
bestOffs = 0;
|
|
||||||
|
|
||||||
// Scans for the best correlation value by testing each possible position
|
|
||||||
// over the permitted range.
|
|
||||||
for (tempOffset = 0; tempOffset < seekLength; tempOffset ++)
|
|
||||||
{
|
|
||||||
compare = refPos + tempOffset;
|
|
||||||
|
|
||||||
// Calculates correlation value for the mixing position corresponding
|
|
||||||
// to 'tempOffset'
|
|
||||||
corr = (double)calcCrossCorrMono(pRefMidBuffer, compare);
|
|
||||||
// heuristic rule to slightly favour values close to mid of the range
|
|
||||||
double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
|
|
||||||
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
|
||||||
|
|
||||||
// Checks for the highest correlation value
|
|
||||||
if (corr > bestCorr)
|
|
||||||
{
|
|
||||||
bestCorr = corr;
|
|
||||||
bestOffs = tempOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// clear cross correlation routine state if necessary (is so e.g. in MMX routines).
|
|
||||||
clearCrossCorrState();
|
|
||||||
|
|
||||||
return bestOffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Seeks for the optimal overlap-mixing position. The 'mono' version of the
|
|
||||||
// routine
|
|
||||||
//
|
|
||||||
// The best position is determined as the position where the two overlapped
|
|
||||||
// sample sequences are 'most alike', in terms of the highest cross-correlation
|
|
||||||
// value over the overlapping period
|
|
||||||
int TDStretch::seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
int bestOffs;
|
|
||||||
double bestCorr, corr;
|
|
||||||
int scanCount, corrOffset, tempOffset;
|
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples
|
|
||||||
precalcCorrReferenceMono();
|
|
||||||
|
|
||||||
bestCorr = FLT_MIN;
|
|
||||||
bestOffs = _scanOffsets[0][0];
|
|
||||||
corrOffset = 0;
|
|
||||||
tempOffset = 0;
|
|
||||||
|
|
||||||
// Scans for the best correlation value using four-pass hierarchical search.
|
|
||||||
//
|
|
||||||
// The look-up table 'scans' has hierarchical position adjusting steps.
|
|
||||||
// In first pass the routine searhes for the highest correlation with
|
|
||||||
// relatively coarse steps, then rescans the neighbourhood of the highest
|
|
||||||
// correlation with better resolution and so on.
|
|
||||||
for (scanCount = 0;scanCount < 4; scanCount ++)
|
|
||||||
{
|
|
||||||
j = 0;
|
|
||||||
while (_scanOffsets[scanCount][j])
|
|
||||||
{
|
|
||||||
tempOffset = corrOffset + _scanOffsets[scanCount][j];
|
|
||||||
if (tempOffset >= seekLength) break;
|
|
||||||
|
|
||||||
// Calculates correlation value for the mixing position corresponding
|
|
||||||
// to 'tempOffset'
|
|
||||||
corr = (double)calcCrossCorrMono(refPos + tempOffset, pRefMidBuffer);
|
|
||||||
// heuristic rule to slightly favour values close to mid of the range
|
|
||||||
double tmp = (double)(2 * tempOffset - seekLength) / seekLength;
|
|
||||||
corr = ((corr + 0.1) * (1.0 - 0.25 * tmp * tmp));
|
|
||||||
|
|
||||||
// Checks for the highest correlation value
|
|
||||||
if (corr > bestCorr)
|
|
||||||
{
|
|
||||||
bestCorr = corr;
|
|
||||||
bestOffs = tempOffset;
|
|
||||||
}
|
|
||||||
j ++;
|
|
||||||
}
|
|
||||||
corrOffset = bestOffs;
|
|
||||||
}
|
|
||||||
// clear cross correlation routine state if necessary (is so e.g. in MMX routines).
|
|
||||||
clearCrossCorrState();
|
|
||||||
|
|
||||||
return bestOffs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// clear cross correlation routine state if necessary
|
|
||||||
void TDStretch::clearCrossCorrState()
|
void TDStretch::clearCrossCorrState()
|
||||||
{
|
{
|
||||||
// default implementation is empty.
|
// default implementation is empty.
|
||||||
|
@ -531,7 +404,7 @@ void TDStretch::calcSeqParameters()
|
||||||
#define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
|
#define CHECK_LIMITS(x, mi, ma) (((x) < (mi)) ? (mi) : (((x) > (ma)) ? (ma) : (x)))
|
||||||
|
|
||||||
double seq, seek;
|
double seq, seek;
|
||||||
|
|
||||||
if (bAutoSeqSetting)
|
if (bAutoSeqSetting)
|
||||||
{
|
{
|
||||||
seq = AUTOSEQ_C + AUTOSEQ_K * tempo;
|
seq = AUTOSEQ_C + AUTOSEQ_K * tempo;
|
||||||
|
@ -548,7 +421,7 @@ void TDStretch::calcSeqParameters()
|
||||||
|
|
||||||
// Update seek window lengths
|
// Update seek window lengths
|
||||||
seekWindowLength = (sampleRate * sequenceMs) / 1000;
|
seekWindowLength = (sampleRate * sequenceMs) / 1000;
|
||||||
if (seekWindowLength < 2 * overlapLength)
|
if (seekWindowLength < 2 * overlapLength)
|
||||||
{
|
{
|
||||||
seekWindowLength = 2 * overlapLength;
|
seekWindowLength = 2 * overlapLength;
|
||||||
}
|
}
|
||||||
|
@ -557,7 +430,7 @@ void TDStretch::calcSeqParameters()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
||||||
// tempo, larger faster tempo.
|
// tempo, larger faster tempo.
|
||||||
void TDStretch::setTempo(float newTempo)
|
void TDStretch::setTempo(float newTempo)
|
||||||
{
|
{
|
||||||
|
@ -568,11 +441,11 @@ void TDStretch::setTempo(float newTempo)
|
||||||
// Calculate new sequence duration
|
// Calculate new sequence duration
|
||||||
calcSeqParameters();
|
calcSeqParameters();
|
||||||
|
|
||||||
// Calculate ideal skip length (according to tempo value)
|
// Calculate ideal skip length (according to tempo value)
|
||||||
nominalSkip = tempo * (seekWindowLength - overlapLength);
|
nominalSkip = tempo * (seekWindowLength - overlapLength);
|
||||||
intskip = (int)(nominalSkip + 0.5f);
|
intskip = (int)(nominalSkip + 0.5f);
|
||||||
|
|
||||||
// Calculate how many samples are needed in the 'inputBuffer' to
|
// Calculate how many samples are needed in the 'inputBuffer' to
|
||||||
// process another batch of samples
|
// process another batch of samples
|
||||||
//sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
|
//sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength / 2;
|
||||||
sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
|
sampleReq = max(intskip + overlapLength, seekWindowLength) + seekLength;
|
||||||
|
@ -600,18 +473,18 @@ void TDStretch::processNominalTempo()
|
||||||
{
|
{
|
||||||
assert(tempo == 1.0f);
|
assert(tempo == 1.0f);
|
||||||
|
|
||||||
if (bMidBufferDirty)
|
if (bMidBufferDirty)
|
||||||
{
|
{
|
||||||
// If there are samples in pMidBuffer waiting for overlapping,
|
// If there are samples in pMidBuffer waiting for overlapping,
|
||||||
// do a single sliding overlapping with them in order to prevent a
|
// do a single sliding overlapping with them in order to prevent a
|
||||||
// clicking distortion in the output sound
|
// clicking distortion in the output sound
|
||||||
if (inputBuffer.numSamples() < overlapLength)
|
if (inputBuffer.numSamples() < overlapLength)
|
||||||
{
|
{
|
||||||
// wait until we've got overlapLength input samples
|
// wait until we've got overlapLength input samples
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Mix the samples in the beginning of 'inputBuffer' with the
|
// Mix the samples in the beginning of 'inputBuffer' with the
|
||||||
// samples in 'midBuffer' using sliding overlapping
|
// samples in 'midBuffer' using sliding overlapping
|
||||||
overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0);
|
overlap(outputBuffer.ptrEnd(overlapLength), inputBuffer.ptrBegin(), 0);
|
||||||
outputBuffer.putSamples(overlapLength);
|
outputBuffer.putSamples(overlapLength);
|
||||||
inputBuffer.receiveSamples(overlapLength);
|
inputBuffer.receiveSamples(overlapLength);
|
||||||
|
@ -636,7 +509,7 @@ void TDStretch::processSamples()
|
||||||
|
|
||||||
/* Removed this small optimization - can introduce a click to sound when tempo setting
|
/* Removed this small optimization - can introduce a click to sound when tempo setting
|
||||||
crosses the nominal value
|
crosses the nominal value
|
||||||
if (tempo == 1.0f)
|
if (tempo == 1.0f)
|
||||||
{
|
{
|
||||||
// tempo not changed from the original, so bypass the processing
|
// tempo not changed from the original, so bypass the processing
|
||||||
processNominalTempo();
|
processNominalTempo();
|
||||||
|
@ -646,14 +519,13 @@ void TDStretch::processSamples()
|
||||||
|
|
||||||
// Process samples as long as there are enough samples in 'inputBuffer'
|
// Process samples as long as there are enough samples in 'inputBuffer'
|
||||||
// to form a processing frame.
|
// to form a processing frame.
|
||||||
// while ((int)inputBuffer.numSamples() >= sampleReq - (outDebt / 4))
|
while ((int)inputBuffer.numSamples() >= sampleReq)
|
||||||
while ((int)inputBuffer.numSamples() >= sampleReq)
|
|
||||||
{
|
{
|
||||||
// If tempo differs from the normal ('SCALE'), scan for the best overlapping
|
// If tempo differs from the normal ('SCALE'), scan for the best overlapping
|
||||||
// position
|
// position
|
||||||
offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
|
offset = seekBestOverlapPosition(inputBuffer.ptrBegin());
|
||||||
|
|
||||||
// Mix the samples in the 'inputBuffer' at position of 'offset' with the
|
// Mix the samples in the 'inputBuffer' at position of 'offset' with the
|
||||||
// samples in 'midBuffer' using sliding overlapping
|
// samples in 'midBuffer' using sliding overlapping
|
||||||
// ... first partially overlap with the end of the previous sequence
|
// ... first partially overlap with the end of the previous sequence
|
||||||
// (that's in 'midBuffer')
|
// (that's in 'midBuffer')
|
||||||
|
@ -661,16 +533,8 @@ void TDStretch::processSamples()
|
||||||
outputBuffer.putSamples((uint)overlapLength);
|
outputBuffer.putSamples((uint)overlapLength);
|
||||||
|
|
||||||
// ... then copy sequence samples from 'inputBuffer' to output:
|
// ... then copy sequence samples from 'inputBuffer' to output:
|
||||||
temp = (seekLength / 2 - offset);
|
|
||||||
|
|
||||||
// compensate cumulated output length diff vs. ideal output
|
|
||||||
// temp -= outDebt / 4;
|
|
||||||
|
|
||||||
// update ideal vs. true output difference
|
|
||||||
// outDebt += temp;
|
|
||||||
|
|
||||||
// length of sequence
|
// length of sequence
|
||||||
// temp += (seekWindowLength - 2 * overlapLength);
|
|
||||||
temp = (seekWindowLength - 2 * overlapLength);
|
temp = (seekWindowLength - 2 * overlapLength);
|
||||||
|
|
||||||
// crosscheck that we don't have buffer overflow...
|
// crosscheck that we don't have buffer overflow...
|
||||||
|
@ -681,11 +545,11 @@ void TDStretch::processSamples()
|
||||||
|
|
||||||
outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
|
outputBuffer.putSamples(inputBuffer.ptrBegin() + channels * (offset + overlapLength), (uint)temp);
|
||||||
|
|
||||||
// Copies the end of the current sequence from 'inputBuffer' to
|
// Copies the end of the current sequence from 'inputBuffer' to
|
||||||
// 'midBuffer' for being mixed with the beginning of the next
|
// 'midBuffer' for being mixed with the beginning of the next
|
||||||
// processing sequence and so on
|
// processing sequence and so on
|
||||||
assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
|
assert((offset + temp + overlapLength * 2) <= (int)inputBuffer.numSamples());
|
||||||
memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength),
|
memcpy(pMidBuffer, inputBuffer.ptrBegin() + channels * (offset + temp + overlapLength),
|
||||||
channels * sizeof(SAMPLETYPE) * overlapLength);
|
channels * sizeof(SAMPLETYPE) * overlapLength);
|
||||||
|
|
||||||
// Remove the processed samples from the input buffer. Update
|
// Remove the processed samples from the input buffer. Update
|
||||||
|
@ -722,26 +586,24 @@ void TDStretch::acceptNewOverlapLength(int newOverlapLength)
|
||||||
|
|
||||||
if (overlapLength > prevOvl)
|
if (overlapLength > prevOvl)
|
||||||
{
|
{
|
||||||
delete[] pMidBuffer;
|
delete[] pMidBufferUnaligned;
|
||||||
delete[] pRefMidBufferUnaligned;
|
|
||||||
|
pMidBufferUnaligned = new SAMPLETYPE[overlapLength * 2 + 16 / sizeof(SAMPLETYPE)];
|
||||||
|
// ensure that 'pMidBuffer' is aligned to 16 byte boundary for efficiency
|
||||||
|
pMidBuffer = (SAMPLETYPE *)SOUNDTOUCH_ALIGN_POINTER_16(pMidBufferUnaligned);
|
||||||
|
|
||||||
pMidBuffer = new SAMPLETYPE[overlapLength * 2];
|
|
||||||
clearMidBuffer();
|
clearMidBuffer();
|
||||||
|
|
||||||
pRefMidBufferUnaligned = new SAMPLETYPE[2 * overlapLength + 16 / sizeof(SAMPLETYPE)];
|
|
||||||
// ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency
|
|
||||||
pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & (ulong)-16);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
// 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.
|
// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||||
void * TDStretch::operator new(size_t s)
|
void * TDStretch::operator new(size_t s)
|
||||||
{
|
{
|
||||||
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
|
// Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
|
||||||
throw std::runtime_error("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
|
ST_THROW_RT_ERROR("Error in TDStretch::new: Don't use 'new TDStretch' directly, use 'newInstance' member instead!");
|
||||||
return NULL;
|
return newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -751,36 +613,26 @@ TDStretch * TDStretch::newInstance()
|
||||||
|
|
||||||
uExtensions = detectCPUextensions();
|
uExtensions = detectCPUextensions();
|
||||||
|
|
||||||
// Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
|
// Check if MMX/SSE instruction set extensions supported by CPU
|
||||||
|
|
||||||
#ifdef ALLOW_MMX
|
#ifdef SOUNDTOUCH_ALLOW_MMX
|
||||||
// MMX routines available only with integer sample types
|
// MMX routines available only with integer sample types
|
||||||
if (uExtensions & SUPPORT_MMX)
|
if (uExtensions & SUPPORT_MMX)
|
||||||
{
|
{
|
||||||
return ::new TDStretchMMX;
|
return ::new TDStretchMMX;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // ALLOW_MMX
|
#endif // SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALLOW_SSE
|
#ifdef SOUNDTOUCH_ALLOW_SSE
|
||||||
if (uExtensions & SUPPORT_SSE)
|
if (uExtensions & SUPPORT_SSE)
|
||||||
{
|
{
|
||||||
// SSE support
|
// SSE support
|
||||||
return ::new TDStretchSSE;
|
return ::new TDStretchSSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // ALLOW_SSE
|
#endif // SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALLOW_3DNOW
|
|
||||||
if (uExtensions & SUPPORT_3DNOW)
|
|
||||||
{
|
|
||||||
// 3DNow! support
|
|
||||||
return ::new TDStretch3DNow;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif // ALLOW_3DNOW
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// ISA optimizations not supported, use plain C version
|
// ISA optimizations not supported, use plain C version
|
||||||
|
@ -795,46 +647,9 @@ TDStretch * TDStretch::newInstance()
|
||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef INTEGER_SAMPLES
|
#ifdef SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
|
// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
|
||||||
// is faster to calculate
|
|
||||||
void TDStretch::precalcCorrReferenceStereo()
|
|
||||||
{
|
|
||||||
int i, cnt2;
|
|
||||||
int temp, temp2;
|
|
||||||
|
|
||||||
for (i=0 ; i < (int)overlapLength ;i ++)
|
|
||||||
{
|
|
||||||
temp = i * (overlapLength - i);
|
|
||||||
cnt2 = i * 2;
|
|
||||||
|
|
||||||
temp2 = (pMidBuffer[cnt2] * temp) / slopingDivider;
|
|
||||||
pRefMidBuffer[cnt2] = (short)(temp2);
|
|
||||||
temp2 = (pMidBuffer[cnt2 + 1] * temp) / slopingDivider;
|
|
||||||
pRefMidBuffer[cnt2 + 1] = (short)(temp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
|
|
||||||
// is faster to calculate
|
|
||||||
void TDStretch::precalcCorrReferenceMono()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
long temp;
|
|
||||||
long temp2;
|
|
||||||
|
|
||||||
for (i=0 ; i < (int)overlapLength ;i ++)
|
|
||||||
{
|
|
||||||
temp = i * (overlapLength - i);
|
|
||||||
temp2 = (pMidBuffer[i] * temp) / slopingDivider;
|
|
||||||
pRefMidBuffer[i] = (short)temp2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
|
|
||||||
// version of the routine.
|
// version of the routine.
|
||||||
void TDStretch::overlapStereo(short *poutput, const short *input) const
|
void TDStretch::overlapStereo(short *poutput, const short *input) const
|
||||||
{
|
{
|
||||||
|
@ -842,7 +657,7 @@ void TDStretch::overlapStereo(short *poutput, const short *input) const
|
||||||
short temp;
|
short temp;
|
||||||
int cnt2;
|
int cnt2;
|
||||||
|
|
||||||
for (i = 0; i < overlapLength ; i ++)
|
for (i = 0; i < overlapLength ; i ++)
|
||||||
{
|
{
|
||||||
temp = (short)(overlapLength - i);
|
temp = (short)(overlapLength - i);
|
||||||
cnt2 = 2 * i;
|
cnt2 = 2 * i;
|
||||||
|
@ -868,8 +683,8 @@ void TDStretch::calculateOverlapLength(int aoverlapMs)
|
||||||
assert(aoverlapMs >= 0);
|
assert(aoverlapMs >= 0);
|
||||||
|
|
||||||
// calculate overlap length so that it's power of 2 - thus it's easy to do
|
// calculate overlap length so that it's power of 2 - thus it's easy to do
|
||||||
// integer division by right-shifting. Term "-1" at end is to account for
|
// integer division by right-shifting. Term "-1" at end is to account for
|
||||||
// the extra most significatnt bit left unused in result by signed multiplication
|
// the extra most significatnt bit left unused in result by signed multiplication
|
||||||
overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
|
overlapDividerBits = _getClosest2Power((sampleRate * aoverlapMs) / 1000.0) - 1;
|
||||||
if (overlapDividerBits > 9) overlapDividerBits = 9;
|
if (overlapDividerBits > 9) overlapDividerBits = 9;
|
||||||
if (overlapDividerBits < 3) overlapDividerBits = 3;
|
if (overlapDividerBits < 3) overlapDividerBits = 3;
|
||||||
|
@ -877,113 +692,70 @@ void TDStretch::calculateOverlapLength(int aoverlapMs)
|
||||||
|
|
||||||
acceptNewOverlapLength(newOvl);
|
acceptNewOverlapLength(newOvl);
|
||||||
|
|
||||||
// calculate sloping divider so that crosscorrelation operation won't
|
// calculate sloping divider so that crosscorrelation operation won't
|
||||||
// overflow 32-bit register. Max. sum of the crosscorrelation sum without
|
// overflow 32-bit register. Max. sum of the crosscorrelation sum without
|
||||||
// divider would be 2^30*(N^3-N)/3, where N = overlap length
|
// divider would be 2^30*(N^3-N)/3, where N = overlap length
|
||||||
slopingDivider = (newOvl * newOvl - 1) / 3;
|
slopingDivider = (newOvl * newOvl - 1) / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
long TDStretch::calcCrossCorrMono(const short *mixingPos, const short *compare) const
|
double TDStretch::calcCrossCorr(const short *mixingPos, const short *compare) const
|
||||||
{
|
{
|
||||||
long corr;
|
long corr;
|
||||||
long norm;
|
long norm;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
corr = norm = 0;
|
corr = norm = 0;
|
||||||
for (i = 1; i < overlapLength; i ++)
|
// Same routine for stereo and mono. For stereo, unroll loop for better
|
||||||
|
// efficiency and gives slightly better resolution against rounding.
|
||||||
|
// For mono it same routine, just unrolls loop by factor of 4
|
||||||
|
for (i = 0; i < channels * overlapLength; i += 4)
|
||||||
{
|
{
|
||||||
corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
|
corr += (mixingPos[i] * compare[i] +
|
||||||
norm += (mixingPos[i] * mixingPos[i]) >> overlapDividerBits;
|
mixingPos[i + 1] * compare[i + 1] +
|
||||||
|
mixingPos[i + 2] * compare[i + 2] +
|
||||||
|
mixingPos[i + 3] * compare[i + 3]) >> overlapDividerBits;
|
||||||
|
norm += (mixingPos[i] * mixingPos[i] +
|
||||||
|
mixingPos[i + 1] * mixingPos[i + 1] +
|
||||||
|
mixingPos[i + 2] * mixingPos[i + 2] +
|
||||||
|
mixingPos[i + 3] * mixingPos[i + 3]) >> overlapDividerBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize result by dividing by sqrt(norm) - this step is easiest
|
// Normalize result by dividing by sqrt(norm) - this step is easiest
|
||||||
// done using floating point operation
|
// done using floating point operation
|
||||||
if (norm == 0) norm = 1; // to avoid div by zero
|
if (norm == 0) norm = 1; // to avoid div by zero
|
||||||
return (long)((double)corr * SHRT_MAX / sqrt((double)norm));
|
return (double)corr / sqrt((double)norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // SOUNDTOUCH_INTEGER_SAMPLES
|
||||||
long TDStretch::calcCrossCorrStereo(const short *mixingPos, const short *compare) const
|
|
||||||
{
|
|
||||||
long corr;
|
|
||||||
long norm;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
corr = norm = 0;
|
|
||||||
for (i = 2; i < 2 * overlapLength; i += 2)
|
|
||||||
{
|
|
||||||
corr += (mixingPos[i] * compare[i] +
|
|
||||||
mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;
|
|
||||||
norm += (mixingPos[i] * mixingPos[i] + mixingPos[i + 1] * mixingPos[i + 1]) >> overlapDividerBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normalize result by dividing by sqrt(norm) - this step is easiest
|
|
||||||
// done using floating point operation
|
|
||||||
if (norm == 0) norm = 1; // to avoid div by zero
|
|
||||||
return (long)((double)corr * SHRT_MAX / sqrt((double)norm));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // INTEGER_SAMPLES
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Floating point arithmetics specific algorithm implementations.
|
// Floating point arithmetics specific algorithm implementations.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifdef FLOAT_SAMPLES
|
#ifdef SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
|
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
|
|
||||||
// is faster to calculate
|
|
||||||
void TDStretch::precalcCorrReferenceStereo()
|
|
||||||
{
|
|
||||||
int i, cnt2;
|
|
||||||
float temp;
|
|
||||||
|
|
||||||
for (i=0 ; i < (int)overlapLength ;i ++)
|
|
||||||
{
|
|
||||||
temp = (float)i * (float)(overlapLength - i);
|
|
||||||
cnt2 = i * 2;
|
|
||||||
pRefMidBuffer[cnt2] = (float)(pMidBuffer[cnt2] * temp);
|
|
||||||
pRefMidBuffer[cnt2 + 1] = (float)(pMidBuffer[cnt2 + 1] * temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Slopes the amplitude of the 'midBuffer' samples so that cross correlation
|
|
||||||
// is faster to calculate
|
|
||||||
void TDStretch::precalcCorrReferenceMono()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
float temp;
|
|
||||||
|
|
||||||
for (i=0 ; i < (int)overlapLength ;i ++)
|
|
||||||
{
|
|
||||||
temp = (float)i * (float)(overlapLength - i);
|
|
||||||
pRefMidBuffer[i] = (float)(pMidBuffer[i] * temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
|
// Overlaps samples in 'midBuffer' with the samples in 'pInput'
|
||||||
void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
|
void TDStretch::overlapStereo(float *pOutput, const float *pInput) const
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int cnt2;
|
|
||||||
float fTemp;
|
|
||||||
float fScale;
|
float fScale;
|
||||||
float fi;
|
float f1;
|
||||||
|
float f2;
|
||||||
|
|
||||||
fScale = 1.0f / (float)overlapLength;
|
fScale = 1.0f / (float)overlapLength;
|
||||||
|
|
||||||
for (i = 0; i < (int)overlapLength ; i ++)
|
f1 = 0;
|
||||||
|
f2 = 1.0f;
|
||||||
|
|
||||||
|
for (i = 0; i < 2 * (int)overlapLength ; i += 2)
|
||||||
{
|
{
|
||||||
fTemp = (float)(overlapLength - i) * fScale;
|
pOutput[i + 0] = pInput[i + 0] * f1 + pMidBuffer[i + 0] * f2;
|
||||||
fi = (float)i * fScale;
|
pOutput[i + 1] = pInput[i + 1] * f1 + pMidBuffer[i + 1] * f2;
|
||||||
cnt2 = 2 * i;
|
|
||||||
pOutput[cnt2 + 0] = pInput[cnt2 + 0] * fi + pMidBuffer[cnt2 + 0] * fTemp;
|
f1 += fScale;
|
||||||
pOutput[cnt2 + 1] = pInput[cnt2 + 1] * fi + pMidBuffer[cnt2 + 1] * fTemp;
|
f2 -= fScale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1004,42 +776,33 @@ void TDStretch::calculateOverlapLength(int overlapInMsec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double TDStretch::calcCrossCorr(const float *mixingPos, const float *compare) const
|
||||||
double TDStretch::calcCrossCorrMono(const float *mixingPos, const float *compare) const
|
|
||||||
{
|
{
|
||||||
double corr;
|
double corr;
|
||||||
double norm;
|
double norm;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
corr = norm = 0;
|
corr = norm = 0;
|
||||||
for (i = 1; i < overlapLength; i ++)
|
// Same routine for stereo and mono. For Stereo, unroll by factor of 2.
|
||||||
{
|
// For mono it's same routine yet unrollsd by factor of 4.
|
||||||
corr += mixingPos[i] * compare[i];
|
for (i = 0; i < channels * overlapLength; i += 4)
|
||||||
norm += mixingPos[i] * mixingPos[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (norm < 1e-9) norm = 1.0; // to avoid div by zero
|
|
||||||
return corr / sqrt(norm);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
double TDStretch::calcCrossCorrStereo(const float *mixingPos, const float *compare) const
|
|
||||||
{
|
|
||||||
double corr;
|
|
||||||
double norm;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
corr = norm = 0;
|
|
||||||
for (i = 2; i < 2 * overlapLength; i += 2)
|
|
||||||
{
|
{
|
||||||
corr += mixingPos[i] * compare[i] +
|
corr += mixingPos[i] * compare[i] +
|
||||||
mixingPos[i + 1] * compare[i + 1];
|
mixingPos[i + 1] * compare[i + 1];
|
||||||
norm += mixingPos[i] * mixingPos[i] +
|
|
||||||
|
norm += mixingPos[i] * mixingPos[i] +
|
||||||
mixingPos[i + 1] * mixingPos[i + 1];
|
mixingPos[i + 1] * mixingPos[i + 1];
|
||||||
|
|
||||||
|
// unroll the loop for better CPU efficiency:
|
||||||
|
corr += mixingPos[i + 2] * compare[i + 2] +
|
||||||
|
mixingPos[i + 3] * compare[i + 3];
|
||||||
|
|
||||||
|
norm += mixingPos[i + 2] * mixingPos[i + 2] +
|
||||||
|
mixingPos[i + 3] * mixingPos[i + 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (norm < 1e-9) norm = 1.0; // to avoid div by zero
|
if (norm < 1e-9) norm = 1.0; // to avoid div by zero
|
||||||
return corr / sqrt(norm);
|
return corr / sqrt(norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FLOAT_SAMPLES
|
#endif // SOUNDTOUCH_FLOAT_SAMPLES
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo
|
||||||
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
/// while maintaining the original pitch by using a time domain WSOLA-like method
|
||||||
/// with several performance-increasing tweaks.
|
/// with several performance-increasing tweaks.
|
||||||
///
|
///
|
||||||
/// Note : MMX/SSE optimized functions reside in separate, platform-specific files
|
/// Note : MMX/SSE optimized functions reside in separate, platform-specific files
|
||||||
/// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
|
/// 'mmx_optimized.cpp' and 'sse_optimized.cpp'
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -13,10 +13,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-05-17 14:35:13 +0300 (Sun, 17 May 2009) $
|
// Last changed : $Date: 2012-04-01 16:49:30 -0300 (dom, 01 abr 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: TDStretch.h 71 2009-05-17 11:35:13Z oparviai $
|
// $Id: TDStretch.h 137 2012-04-01 19:49:30Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -53,14 +53,14 @@ namespace soundtouch
|
||||||
{
|
{
|
||||||
|
|
||||||
/// Default values for sound processing parameters:
|
/// Default values for sound processing parameters:
|
||||||
/// Notice that the default parameters are tuned for contemporary popular music
|
/// Notice that the default parameters are tuned for contemporary popular music
|
||||||
/// processing. For speech processing applications these parameters suit better:
|
/// processing. For speech processing applications these parameters suit better:
|
||||||
/// #define DEFAULT_SEQUENCE_MS 40
|
/// #define DEFAULT_SEQUENCE_MS 40
|
||||||
/// #define DEFAULT_SEEKWINDOW_MS 15
|
/// #define DEFAULT_SEEKWINDOW_MS 15
|
||||||
/// #define DEFAULT_OVERLAP_MS 8
|
/// #define DEFAULT_OVERLAP_MS 8
|
||||||
///
|
///
|
||||||
|
|
||||||
/// Default length of a single processing sequence, in milliseconds. This determines to how
|
/// 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.
|
/// 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
|
/// The larger this value is, the lesser sequences are used in processing. In principle
|
||||||
|
@ -75,15 +75,15 @@ namespace soundtouch
|
||||||
/// according to tempo setting (recommended)
|
/// according to tempo setting (recommended)
|
||||||
#define USE_AUTO_SEQUENCE_LEN 0
|
#define USE_AUTO_SEQUENCE_LEN 0
|
||||||
|
|
||||||
/// Seeking window default length in milliseconds for algorithm that finds the best possible
|
/// Seeking window default length in milliseconds for algorithm that finds the best possible
|
||||||
/// overlapping location. This determines from how wide window the algorithm may look for an
|
/// overlapping location. This determines from how wide window the algorithm may look for an
|
||||||
/// optimal joining location when mixing the sound sequences back together.
|
/// optimal joining location when mixing the sound sequences back together.
|
||||||
///
|
///
|
||||||
/// The bigger this window setting is, the higher the possibility to find a better mixing
|
/// The bigger this window setting is, the higher the possibility to find a better mixing
|
||||||
/// position will become, but at the same time large values may cause a "drifting" artifact
|
/// position will become, but at the same time large values may cause a "drifting" artifact
|
||||||
/// because consequent sequences will be taken at more uneven intervals.
|
/// because consequent sequences will be taken at more uneven intervals.
|
||||||
///
|
///
|
||||||
/// If there's a disturbing artifact that sounds as if a constant frequency was drifting
|
/// If there's a disturbing artifact that sounds as if a constant frequency was drifting
|
||||||
/// around, try reducing this setting.
|
/// around, try reducing this setting.
|
||||||
///
|
///
|
||||||
/// Increasing this value increases computational burden & vice versa.
|
/// Increasing this value increases computational burden & vice versa.
|
||||||
|
@ -94,11 +94,11 @@ namespace soundtouch
|
||||||
/// according to tempo setting (recommended)
|
/// according to tempo setting (recommended)
|
||||||
#define USE_AUTO_SEEKWINDOW_LEN 0
|
#define USE_AUTO_SEEKWINDOW_LEN 0
|
||||||
|
|
||||||
/// Overlap length in milliseconds. When the chopped sound sequences are mixed back together,
|
/// 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
|
/// to form a continuous sound stream, this parameter defines over how long period the two
|
||||||
/// consecutive sequences are let to overlap each other.
|
/// consecutive sequences are let to overlap each other.
|
||||||
///
|
///
|
||||||
/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
|
/// This shouldn't be that critical parameter. If you reduce the DEFAULT_SEQUENCE_MS setting
|
||||||
/// by a large amount, you might wish to try a smaller value on this.
|
/// by a large amount, you might wish to try a smaller value on this.
|
||||||
///
|
///
|
||||||
/// Increasing this value increases computational burden & vice versa.
|
/// Increasing this value increases computational burden & vice versa.
|
||||||
|
@ -115,8 +115,7 @@ protected:
|
||||||
float tempo;
|
float tempo;
|
||||||
|
|
||||||
SAMPLETYPE *pMidBuffer;
|
SAMPLETYPE *pMidBuffer;
|
||||||
SAMPLETYPE *pRefMidBuffer;
|
SAMPLETYPE *pMidBufferUnaligned;
|
||||||
SAMPLETYPE *pRefMidBufferUnaligned;
|
|
||||||
int overlapLength;
|
int overlapLength;
|
||||||
int seekLength;
|
int seekLength;
|
||||||
int seekWindowLength;
|
int seekWindowLength;
|
||||||
|
@ -127,8 +126,6 @@ protected:
|
||||||
FIFOSampleBuffer outputBuffer;
|
FIFOSampleBuffer outputBuffer;
|
||||||
FIFOSampleBuffer inputBuffer;
|
FIFOSampleBuffer inputBuffer;
|
||||||
BOOL bQuickSeek;
|
BOOL bQuickSeek;
|
||||||
// int outDebt;
|
|
||||||
// BOOL bMidBufferDirty;
|
|
||||||
|
|
||||||
int sampleRate;
|
int sampleRate;
|
||||||
int sequenceMs;
|
int sequenceMs;
|
||||||
|
@ -142,13 +139,10 @@ protected:
|
||||||
virtual void clearCrossCorrState();
|
virtual void clearCrossCorrState();
|
||||||
void calculateOverlapLength(int overlapMs);
|
void calculateOverlapLength(int overlapMs);
|
||||||
|
|
||||||
virtual LONG_SAMPLETYPE calcCrossCorrStereo(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
virtual double calcCrossCorr(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
||||||
virtual LONG_SAMPLETYPE calcCrossCorrMono(const SAMPLETYPE *mixingPos, const SAMPLETYPE *compare) const;
|
|
||||||
|
|
||||||
virtual int seekBestOverlapPositionStereo(const SAMPLETYPE *refPos);
|
virtual int seekBestOverlapPositionFull(const SAMPLETYPE *refPos);
|
||||||
virtual int seekBestOverlapPositionStereoQuick(const SAMPLETYPE *refPos);
|
virtual int seekBestOverlapPositionQuick(const SAMPLETYPE *refPos);
|
||||||
virtual int seekBestOverlapPositionMono(const SAMPLETYPE *refPos);
|
|
||||||
virtual int seekBestOverlapPositionMonoQuick(const SAMPLETYPE *refPos);
|
|
||||||
int seekBestOverlapPosition(const SAMPLETYPE *refPos);
|
int seekBestOverlapPosition(const SAMPLETYPE *refPos);
|
||||||
|
|
||||||
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
virtual void overlapStereo(SAMPLETYPE *output, const SAMPLETYPE *input) const;
|
||||||
|
@ -157,9 +151,6 @@ protected:
|
||||||
void clearMidBuffer();
|
void clearMidBuffer();
|
||||||
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
|
void overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const;
|
||||||
|
|
||||||
void precalcCorrReferenceMono();
|
|
||||||
void precalcCorrReferenceStereo();
|
|
||||||
|
|
||||||
void calcSeqParameters();
|
void calcSeqParameters();
|
||||||
|
|
||||||
/// Changes the tempo of the given sound samples.
|
/// Changes the tempo of the given sound samples.
|
||||||
|
@ -167,27 +158,27 @@ protected:
|
||||||
/// The maximum amount of samples that can be returned at a time is set by
|
/// The maximum amount of samples that can be returned at a time is set by
|
||||||
/// the 'set_returnBuffer_size' function.
|
/// the 'set_returnBuffer_size' function.
|
||||||
void processSamples();
|
void processSamples();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TDStretch();
|
TDStretch();
|
||||||
virtual ~TDStretch();
|
virtual ~TDStretch();
|
||||||
|
|
||||||
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
|
/// 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.
|
/// depending on if we've a MMX/SSE/etc-capable CPU available or not.
|
||||||
static void *operator new(size_t s);
|
static void *operator new(size_t s);
|
||||||
|
|
||||||
/// Use this function instead of "new" operator to create a new instance of this class.
|
/// 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
|
/// This function automatically chooses a correct feature set depending on if the CPU
|
||||||
/// supports MMX/SSE/etc extensions.
|
/// supports MMX/SSE/etc extensions.
|
||||||
static TDStretch *newInstance();
|
static TDStretch *newInstance();
|
||||||
|
|
||||||
/// Returns the output buffer object
|
/// Returns the output buffer object
|
||||||
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
FIFOSamplePipe *getOutput() { return &outputBuffer; };
|
||||||
|
|
||||||
/// Returns the input buffer object
|
/// Returns the input buffer object
|
||||||
FIFOSamplePipe *getInput() { return &inputBuffer; };
|
FIFOSamplePipe *getInput() { return &inputBuffer; };
|
||||||
|
|
||||||
/// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
/// Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
|
||||||
/// tempo, larger faster tempo.
|
/// tempo, larger faster tempo.
|
||||||
void setTempo(float newTempo);
|
void setTempo(float newTempo);
|
||||||
|
|
||||||
|
@ -200,7 +191,7 @@ public:
|
||||||
/// Sets the number of channels, 1 = mono, 2 = stereo
|
/// Sets the number of channels, 1 = mono, 2 = stereo
|
||||||
void setChannels(int numChannels);
|
void setChannels(int numChannels);
|
||||||
|
|
||||||
/// Enables/disables the quick position seeking algorithm. Zero to disable,
|
/// Enables/disables the quick position seeking algorithm. Zero to disable,
|
||||||
/// nonzero to enable
|
/// nonzero to enable
|
||||||
void enableQuickSeek(BOOL enable);
|
void enableQuickSeek(BOOL enable);
|
||||||
|
|
||||||
|
@ -212,7 +203,7 @@ public:
|
||||||
//
|
//
|
||||||
/// 'sampleRate' = sample rate of the sound
|
/// 'sampleRate' = sample rate of the sound
|
||||||
/// 'sequenceMS' = one processing sequence length in milliseconds
|
/// 'sequenceMS' = one processing sequence length in milliseconds
|
||||||
/// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
/// 'seekwindowMS' = seeking window length for scanning the best overlapping
|
||||||
/// position
|
/// position
|
||||||
/// 'overlapMS' = overlapping length
|
/// 'overlapMS' = overlapping length
|
||||||
void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz)
|
void setParameters(int sampleRate, ///< Samplerate of sound being processed (Hz)
|
||||||
|
@ -233,43 +224,45 @@ public:
|
||||||
uint numSamples ///< Number of samples in 'samples' so that one sample
|
uint numSamples ///< Number of samples in 'samples' so that one sample
|
||||||
///< contains both channels if stereo
|
///< contains both channels if stereo
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// return nominal input sample requirement for triggering a processing batch
|
||||||
|
int getInputSampleReq() const
|
||||||
|
{
|
||||||
|
return (int)(nominalSkip + 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// return nominal output sample amount when running a processing batch
|
||||||
|
int getOutputBatchSize() const
|
||||||
|
{
|
||||||
|
return seekWindowLength - overlapLength;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Implementation-specific class declarations:
|
// Implementation-specific class declarations:
|
||||||
|
|
||||||
#ifdef ALLOW_MMX
|
#ifdef SOUNDTOUCH_ALLOW_MMX
|
||||||
/// Class that implements MMX optimized routines for 16bit integer samples type.
|
/// Class that implements MMX optimized routines for 16bit integer samples type.
|
||||||
class TDStretchMMX : public TDStretch
|
class TDStretchMMX : public TDStretch
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
long calcCrossCorrStereo(const short *mixingPos, const short *compare) const;
|
double calcCrossCorr(const short *mixingPos, const short *compare) const;
|
||||||
virtual void overlapStereo(short *output, const short *input) const;
|
virtual void overlapStereo(short *output, const short *input) const;
|
||||||
virtual void clearCrossCorrState();
|
virtual void clearCrossCorrState();
|
||||||
};
|
};
|
||||||
#endif /// ALLOW_MMX
|
#endif /// SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
||||||
|
|
||||||
#ifdef ALLOW_3DNOW
|
#ifdef SOUNDTOUCH_ALLOW_SSE
|
||||||
/// 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 that implements SSE optimized routines for floating point samples type.
|
||||||
class TDStretchSSE : public TDStretch
|
class TDStretchSSE : public TDStretch
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
double calcCrossCorrStereo(const float *mixingPos, const float *compare) const;
|
double calcCrossCorr(const float *mixingPos, const float *compare) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /// ALLOW_SSE
|
#endif /// SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif /// TDStretch_H
|
#endif /// TDStretch_H
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
///
|
///
|
||||||
/// A header file for detecting the Intel MMX instructions set extension.
|
/// 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
|
/// 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
|
/// routine implementations for x86 Windows, x86 gnu version and non-x86
|
||||||
/// platforms, respectively.
|
/// platforms, respectively.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
|
// Last changed : $Date: 2008-02-10 14:26:55 -0200 (dom, 10 fev 2008) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
|
// $Id: cpu_detect.h 11 2008-02-10 16:26:55Z oparviai $
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///
|
||||||
|
/// Generic version of the x86 CPU extension detection routine.
|
||||||
|
///
|
||||||
|
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
|
||||||
|
/// for the Microsoft compiler version.
|
||||||
|
///
|
||||||
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
/// Author e-mail : oparviai 'at' iki.fi
|
||||||
|
/// SoundTouch WWW: http://www.surina.net/soundtouch
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Last changed : $Date: 2012-11-08 16:44:37 -0200 (qui, 08 nov 2012) $
|
||||||
|
// File revision : $Revision: 4 $
|
||||||
|
//
|
||||||
|
// $Id: cpu_detect_x86.cpp 159 2012-11-08 18:44:37Z oparviai $
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
#if defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
|
||||||
|
|
||||||
|
#if defined(__GNUC__) && defined(__i386__)
|
||||||
|
// gcc
|
||||||
|
#include "cpuid.h"
|
||||||
|
#elif defined(_M_IX86)
|
||||||
|
// windows non-gcc
|
||||||
|
#include <intrin.h>
|
||||||
|
#define bit_MMX (1 << 23)
|
||||||
|
#define bit_SSE (1 << 25)
|
||||||
|
#define bit_SSE2 (1 << 26)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
/// If building for a 64bit system (no Itanium) and the user wants optimizations.
|
||||||
|
/// Return the OR of SUPPORT_{MMX,SSE,SSE2}. 11001 or 0x19.
|
||||||
|
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
|
||||||
|
#if ((defined(__GNUC__) && defined(__x86_64__)) \
|
||||||
|
|| defined(_M_X64)) \
|
||||||
|
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
|
||||||
|
return 0x19 & ~_dwDisabledISA;
|
||||||
|
|
||||||
|
/// If building for a 32bit system and the user wants optimizations.
|
||||||
|
/// Keep the _dwDisabledISA test (2 more operations, could be eliminated).
|
||||||
|
#elif ((defined(__GNUC__) && defined(__i386__)) \
|
||||||
|
|| defined(_M_IX86)) \
|
||||||
|
&& defined(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS)
|
||||||
|
|
||||||
|
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||||
|
|
||||||
|
uint res = 0;
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
// GCC version of cpuid. Requires GCC 4.3.0 or later for __cpuid intrinsic support.
|
||||||
|
uint eax, ebx, ecx, edx; // unsigned int is the standard type. uint is defined by the compiler and not guaranteed to be portable.
|
||||||
|
|
||||||
|
// Check if no cpuid support.
|
||||||
|
if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) return 0; // always disable extensions.
|
||||||
|
|
||||||
|
if (edx & bit_MMX) res = res | SUPPORT_MMX;
|
||||||
|
if (edx & bit_SSE) res = res | SUPPORT_SSE;
|
||||||
|
if (edx & bit_SSE2) res = res | SUPPORT_SSE2;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Window / VS version of cpuid. Notice that Visual Studio 2005 or later required
|
||||||
|
// for __cpuid intrinsic support.
|
||||||
|
int reg[4] = {-1};
|
||||||
|
|
||||||
|
// Check if no cpuid support.
|
||||||
|
__cpuid(reg,0);
|
||||||
|
if ((unsigned int)reg[0] == 0) return 0; // always disable extensions.
|
||||||
|
|
||||||
|
__cpuid(reg,1);
|
||||||
|
if ((unsigned int)reg[3] & bit_MMX) res = res | SUPPORT_MMX;
|
||||||
|
if ((unsigned int)reg[3] & bit_SSE) res = res | SUPPORT_SSE;
|
||||||
|
if ((unsigned int)reg[3] & bit_SSE2) res = res | SUPPORT_SSE2;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return res & ~_dwDisabledISA;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/// One of these is true:
|
||||||
|
/// 1) We don't want optimizations.
|
||||||
|
/// 2) Using an unsupported compiler.
|
||||||
|
/// 3) Running on a non-x86 platform.
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
///
|
///
|
||||||
/// Generic version of the x86 CPU extension detection routine.
|
/// Generic version of the x86 CPU extension detection routine.
|
||||||
///
|
///
|
||||||
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
|
/// This file is for GNU & other non-Windows compilers, see 'cpu_detect_x86_win.cpp'
|
||||||
/// for the Microsoft compiler version.
|
/// for the Microsoft compiler version.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -11,10 +11,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-25 19:13:51 +0200 (Wed, 25 Feb 2009) $
|
// Last changed : $Date: 2011-09-02 15:56:11 -0300 (sex, 02 set 2011) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: cpu_detect_x86_gcc.cpp 67 2009-02-25 17:13:51Z oparviai $
|
// $Id: cpu_detect_x86_gcc.cpp 131 2011-09-02 18:56:11Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -39,15 +39,9 @@
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <string>
|
|
||||||
#include "cpu_detect.h"
|
#include "cpu_detect.h"
|
||||||
#include "STTypes.h"
|
#include "STTypes.h"
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// processor instructions extension detection routines
|
// processor instructions extension detection routines
|
||||||
|
@ -68,7 +62,7 @@ void disableExtensions(uint dwDisableMask)
|
||||||
/// Checks which instruction set extensions are supported by the CPU.
|
/// Checks which instruction set extensions are supported by the CPU.
|
||||||
uint detectCPUextensions(void)
|
uint detectCPUextensions(void)
|
||||||
{
|
{
|
||||||
#if (!(ALLOW_X86_OPTIMIZATIONS) || !(__GNUC__))
|
#if (!(SOUNDTOUCH_ALLOW_X86_OPTIMIZATIONS) || !(__GNUC__))
|
||||||
|
|
||||||
return 0; // always disable extensions on non-x86 platforms.
|
return 0; // always disable extensions on non-x86 platforms.
|
||||||
|
|
||||||
|
@ -78,8 +72,11 @@ uint detectCPUextensions(void)
|
||||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||||
|
|
||||||
asm volatile(
|
asm volatile(
|
||||||
|
#ifndef __x86_64__
|
||||||
|
// Check if 'cpuid' instructions is available by toggling eflags bit 21.
|
||||||
|
// Skip this for x86-64 as they always have cpuid while stack manipulation
|
||||||
|
// differs from 16/32bit ISA.
|
||||||
"\n\txor %%esi, %%esi" // clear %%esi = result register
|
"\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\tpushf" // save eflags to stack
|
||||||
"\n\tmovl (%%esp), %%eax" // load eax from stack (with eflags)
|
"\n\tmovl (%%esp), %%eax" // load eax from stack (with eflags)
|
||||||
|
@ -93,6 +90,8 @@ uint detectCPUextensions(void)
|
||||||
"\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
|
"\n\txor %%edx, %%edx" // clear edx for defaulting no mmx
|
||||||
"\n\tcmp %%ecx, %%eax" // compare to original eflags values
|
"\n\tcmp %%ecx, %%eax" // compare to original eflags values
|
||||||
"\n\tjz end" // jumps to 'end' if cpuid not present
|
"\n\tjz end" // jumps to 'end' if cpuid not present
|
||||||
|
#endif // __x86_64__
|
||||||
|
|
||||||
// cpuid instruction available, test for presence of mmx instructions
|
// cpuid instruction available, test for presence of mmx instructions
|
||||||
|
|
||||||
"\n\tmovl $1, %%eax"
|
"\n\tmovl $1, %%eax"
|
||||||
|
@ -129,7 +128,7 @@ uint detectCPUextensions(void)
|
||||||
: "=r" (res)
|
: "=r" (res)
|
||||||
: /* no inputs */
|
: /* no inputs */
|
||||||
: "%edx", "%eax", "%ecx", "%esi" );
|
: "%edx", "%eax", "%ecx", "%esi" );
|
||||||
|
|
||||||
return res & ~_dwDisabledISA;
|
return res & ~_dwDisabledISA;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
///
|
///
|
||||||
/// Win32 version of the x86 CPU detect routine.
|
/// Win32 version of the x86 CPU detect routine.
|
||||||
///
|
///
|
||||||
/// This file is to be compiled in Windows platform with Microsoft Visual C++
|
/// 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
|
/// Compiler. Please see 'cpu_detect_x86_gcc.cpp' for the gcc compiler version
|
||||||
/// for all GNU platforms.
|
/// for all GNU platforms.
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-02-13 18:22:48 +0200 (Fri, 13 Feb 2009) $
|
// Last changed : $Date: 2011-07-17 07:58:40 -0300 (dom, 17 jul 2011) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: cpu_detect_x86_win.cpp 62 2009-02-13 16:22:48Z oparviai $
|
// $Id: cpu_detect_x86_win.cpp 127 2011-07-17 10:58:40Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -42,9 +42,7 @@
|
||||||
|
|
||||||
#include "cpu_detect.h"
|
#include "cpu_detect.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
#include "STTypes.h"
|
||||||
#error wrong platform - this source code file is exclusively for Win32 platform
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -71,7 +69,9 @@ uint detectCPUextensions(void)
|
||||||
|
|
||||||
if (_dwDisabledISA == 0xffffffff) return 0;
|
if (_dwDisabledISA == 0xffffffff) return 0;
|
||||||
|
|
||||||
_asm
|
#ifndef _M_X64
|
||||||
|
// 32bit compilation, detect CPU capabilities with inline assembler.
|
||||||
|
__asm
|
||||||
{
|
{
|
||||||
; check if 'cpuid' instructions is available by toggling eflags bit 21
|
; check if 'cpuid' instructions is available by toggling eflags bit 21
|
||||||
;
|
;
|
||||||
|
@ -92,7 +92,7 @@ uint detectCPUextensions(void)
|
||||||
cmp eax, ecx ; compare to original eflags values
|
cmp eax, ecx ; compare to original eflags values
|
||||||
jz end ; jumps to 'end' if cpuid not present
|
jz end ; jumps to 'end' if cpuid not present
|
||||||
|
|
||||||
; cpuid instruction available, test for presence of mmx instructions
|
; cpuid instruction available, test for presence of mmx instructions
|
||||||
mov eax, 1
|
mov eax, 1
|
||||||
cpuid
|
cpuid
|
||||||
test edx, 0x00800000
|
test edx, 0x00800000
|
||||||
|
@ -125,5 +125,13 @@ uint detectCPUextensions(void)
|
||||||
mov res, esi
|
mov res, esi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Visual C++ 64bit compilation doesn't support inline assembler. However,
|
||||||
|
// all x64 compatible CPUs support MMX & SSE extensions.
|
||||||
|
res = SUPPORT_MMX | SUPPORT_SSE | SUPPORT_SSE2;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return res & ~_dwDisabledISA;
|
return res & ~_dwDisabledISA;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// MMX optimized routines. All MMX optimized functions have been gathered into
|
/// MMX optimized routines. All MMX optimized functions have been gathered into
|
||||||
/// this single source code file, regardless to their class or original source
|
/// 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
|
/// code file, in order to ease porting the library to other compiler and
|
||||||
/// processor platforms.
|
/// processor platforms.
|
||||||
///
|
///
|
||||||
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
|
/// The MMX-optimizations are programmed using MMX compiler intrinsics that
|
||||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||||
/// should compile with both toolsets.
|
/// should compile with both toolsets.
|
||||||
///
|
///
|
||||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
/// 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
|
/// 6.0 processor pack" update to support compiler intrinsic syntax. The update
|
||||||
/// is available for download at Microsoft Developers Network, see here:
|
/// is available for download at Microsoft Developers Network, see here:
|
||||||
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
|
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
|
||||||
|
@ -20,10 +20,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-10-31 16:53:23 +0200 (Sat, 31 Oct 2009) $
|
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: mmx_optimized.cpp 75 2009-10-31 14:53:23Z oparviai $
|
// $Id: mmx_optimized.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -50,13 +50,9 @@
|
||||||
|
|
||||||
#include "STTypes.h"
|
#include "STTypes.h"
|
||||||
|
|
||||||
#ifdef ALLOW_MMX
|
#ifdef SOUNDTOUCH_ALLOW_MMX
|
||||||
// MMX routines available only with integer sample type
|
// 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;
|
using namespace soundtouch;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -72,23 +68,23 @@ using namespace soundtouch;
|
||||||
|
|
||||||
|
|
||||||
// Calculates cross correlation of two buffers
|
// Calculates cross correlation of two buffers
|
||||||
long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const
|
double TDStretchMMX::calcCrossCorr(const short *pV1, const short *pV2) const
|
||||||
{
|
{
|
||||||
const __m64 *pVec1, *pVec2;
|
const __m64 *pVec1, *pVec2;
|
||||||
__m64 shifter;
|
__m64 shifter;
|
||||||
__m64 accu, normaccu;
|
__m64 accu, normaccu;
|
||||||
long corr, norm;
|
long corr, norm;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
pVec1 = (__m64*)pV1;
|
pVec1 = (__m64*)pV1;
|
||||||
pVec2 = (__m64*)pV2;
|
pVec2 = (__m64*)pV2;
|
||||||
|
|
||||||
shifter = _m_from_int(overlapDividerBits);
|
shifter = _m_from_int(overlapDividerBits);
|
||||||
normaccu = accu = _mm_setzero_si64();
|
normaccu = accu = _mm_setzero_si64();
|
||||||
|
|
||||||
// Process 4 parallel sets of 2 * stereo samples each during each
|
// Process 4 parallel sets of 2 * stereo samples or 4 * mono samples
|
||||||
// round to improve CPU-level parallellization.
|
// during each round for improved CPU-level parallellization.
|
||||||
for (i = 0; i < overlapLength / 8; i ++)
|
for (i = 0; i < channels * overlapLength / 16; i ++)
|
||||||
{
|
{
|
||||||
__m64 temp, temp2;
|
__m64 temp, temp2;
|
||||||
|
|
||||||
|
@ -127,10 +123,11 @@ long TDStretchMMX::calcCrossCorrStereo(const short *pV1, const short *pV2) const
|
||||||
// Clear MMS state
|
// Clear MMS state
|
||||||
_m_empty();
|
_m_empty();
|
||||||
|
|
||||||
// Normalize result by dividing by sqrt(norm) - this step is easiest
|
// Normalize result by dividing by sqrt(norm) - this step is easiest
|
||||||
// done using floating point operation
|
// done using floating point operation
|
||||||
if (norm == 0) norm = 1; // to avoid div by zero
|
if (norm == 0) norm = 1; // to avoid div by zero
|
||||||
return (long)((double)corr * USHRT_MAX / sqrt((double)norm));
|
|
||||||
|
return (double)corr / sqrt((double)norm);
|
||||||
// Note: Warning about the missing EMMS instruction is harmless
|
// Note: Warning about the missing EMMS instruction is harmless
|
||||||
// as it'll be called elsewhere.
|
// as it'll be called elsewhere.
|
||||||
}
|
}
|
||||||
|
@ -161,7 +158,7 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const
|
||||||
// mix1 = mixer values for 1st stereo sample
|
// mix1 = mixer values for 1st stereo sample
|
||||||
// mix1 = mixer values for 2nd stereo sample
|
// mix1 = mixer values for 2nd stereo sample
|
||||||
// adder = adder for updating mixer values after each round
|
// adder = adder for updating mixer values after each round
|
||||||
|
|
||||||
mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
|
mix1 = _mm_set_pi16(0, overlapLength, 0, overlapLength);
|
||||||
adder = _mm_set_pi16(1, -1, 1, -1);
|
adder = _mm_set_pi16(1, -1, 1, -1);
|
||||||
mix2 = _mm_add_pi16(mix1, adder);
|
mix2 = _mm_add_pi16(mix1, adder);
|
||||||
|
@ -174,7 +171,7 @@ void TDStretchMMX::overlapStereo(short *output, const short *input) const
|
||||||
for (i = 0; i < overlapLength / 4; i ++)
|
for (i = 0; i < overlapLength / 4; i ++)
|
||||||
{
|
{
|
||||||
__m64 temp1, temp2;
|
__m64 temp1, temp2;
|
||||||
|
|
||||||
// load & shuffle data so that input & mixbuffer data samples are paired
|
// load & shuffle data so that input & mixbuffer data samples are paired
|
||||||
temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
|
temp1 = _mm_unpacklo_pi16(pVMidBuf[0], pVinput[0]); // = i0l m0l i0r m0r
|
||||||
temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
|
temp2 = _mm_unpackhi_pi16(pVMidBuf[0], pVinput[0]); // = i1l m1l i1r m1r
|
||||||
|
@ -242,10 +239,10 @@ void FIRFilterMMX::setCoefficients(const short *coeffs, uint newLength, uint uRe
|
||||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||||
delete[] filterCoeffsUnalign;
|
delete[] filterCoeffsUnalign;
|
||||||
filterCoeffsUnalign = new short[2 * newLength + 8];
|
filterCoeffsUnalign = new short[2 * newLength + 8];
|
||||||
filterCoeffsAlign = (short *)(((ulong)filterCoeffsUnalign + 15) & -16);
|
filterCoeffsAlign = (short *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign);
|
||||||
|
|
||||||
// rearrange the filter coefficients for mmx routines
|
// rearrange the filter coefficients for mmx routines
|
||||||
for (i = 0;i < length; i += 4)
|
for (i = 0;i < length; i += 4)
|
||||||
{
|
{
|
||||||
filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
|
filterCoeffsAlign[2 * i + 0] = coeffs[i + 0];
|
||||||
filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
|
filterCoeffsAlign[2 * i + 1] = coeffs[i + 2];
|
||||||
|
@ -317,4 +314,4 @@ uint FIRFilterMMX::evaluateFilterStereo(short *dest, const short *src, uint numS
|
||||||
return (numSamples & 0xfffffffe) - length;
|
return (numSamples & 0xfffffffe) - length;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ALLOW_MMX
|
#endif // SOUNDTOUCH_ALLOW_MMX
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
///
|
///
|
||||||
/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE
|
/// SSE optimized routines for Pentium-III, Athlon-XP and later CPUs. All SSE
|
||||||
/// optimized functions have been gathered into this single source
|
/// optimized functions have been gathered into this single source
|
||||||
/// code file, regardless to their class or original source code file, in order
|
/// code file, regardless to their class or original source code file, in order
|
||||||
/// to ease porting the library to other compiler and processor platforms.
|
/// to ease porting the library to other compiler and processor platforms.
|
||||||
///
|
///
|
||||||
/// The SSE-optimizations are programmed using SSE compiler intrinsics that
|
/// The SSE-optimizations are programmed using SSE compiler intrinsics that
|
||||||
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
/// are supported both by Microsoft Visual C++ and GCC compilers, so this file
|
||||||
/// should compile with both toolsets.
|
/// should compile with both toolsets.
|
||||||
///
|
///
|
||||||
/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++
|
/// 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
|
/// 6.0 processor pack" update to support SSE instruction set. The update is
|
||||||
/// available for download at Microsoft Developers Network, see here:
|
/// available for download at Microsoft Developers Network, see here:
|
||||||
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
|
/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
|
||||||
///
|
///
|
||||||
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
|
||||||
/// perform a search with keywords "processor pack".
|
/// perform a search with keywords "processor pack".
|
||||||
///
|
///
|
||||||
/// Author : Copyright (c) Olli Parviainen
|
/// Author : Copyright (c) Olli Parviainen
|
||||||
|
@ -23,10 +23,10 @@
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// Last changed : $Date: 2009-12-28 22:32:57 +0200 (Mon, 28 Dec 2009) $
|
// Last changed : $Date: 2012-11-08 16:53:01 -0200 (qui, 08 nov 2012) $
|
||||||
// File revision : $Revision: 4 $
|
// File revision : $Revision: 4 $
|
||||||
//
|
//
|
||||||
// $Id: sse_optimized.cpp 80 2009-12-28 20:32:57Z oparviai $
|
// $Id: sse_optimized.cpp 160 2012-11-08 18:53:01Z oparviai $
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
|
|
||||||
using namespace soundtouch;
|
using namespace soundtouch;
|
||||||
|
|
||||||
#ifdef ALLOW_SSE
|
#ifdef SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
||||||
// SSE routines available only with float sample type
|
// SSE routines available only with float sample type
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -71,35 +71,35 @@ using namespace soundtouch;
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
// Calculates cross correlation of two buffers
|
// Calculates cross correlation of two buffers
|
||||||
double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) const
|
double TDStretchSSE::calcCrossCorr(const float *pV1, const float *pV2) const
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const float *pVec1;
|
const float *pVec1;
|
||||||
const __m128 *pVec2;
|
const __m128 *pVec2;
|
||||||
__m128 vSum, vNorm;
|
__m128 vSum, vNorm;
|
||||||
|
|
||||||
// Note. It means a major slow-down if the routine needs to tolerate
|
// 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 __m128 memory accesses. It's way faster if we can skip
|
||||||
// unaligned slots and use _mm_load_ps instruction instead of _mm_loadu_ps.
|
// 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
|
// This can mean up to ~ 10-fold difference (incl. part of which is
|
||||||
// due to skipping every second round for stereo sound though).
|
// due to skipping every second round for stereo sound though).
|
||||||
//
|
//
|
||||||
// Compile-time define ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
|
// Compile-time define SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION is provided
|
||||||
// for choosing if this little cheating is allowed.
|
// for choosing if this little cheating is allowed.
|
||||||
|
|
||||||
#ifdef ALLOW_NONEXACT_SIMD_OPTIMIZATION
|
#ifdef SOUNDTOUCH_ALLOW_NONEXACT_SIMD_OPTIMIZATION
|
||||||
// Little cheating allowed, return valid correlation only for
|
// Little cheating allowed, return valid correlation only for
|
||||||
// aligned locations, meaning every second round for stereo sound.
|
// aligned locations, meaning every second round for stereo sound.
|
||||||
|
|
||||||
#define _MM_LOAD _mm_load_ps
|
#define _MM_LOAD _mm_load_ps
|
||||||
|
|
||||||
if (((ulong)pV1) & 15) return -1e50; // skip unaligned locations
|
if (((ulongptr)pV1) & 15) return -1e50; // skip unaligned locations
|
||||||
|
|
||||||
#else
|
#else
|
||||||
// No cheating allowed, use unaligned load & take the resulting
|
// No cheating allowed, use unaligned load & take the resulting
|
||||||
// performance hit.
|
// performance hit.
|
||||||
#define _MM_LOAD _mm_loadu_ps
|
#define _MM_LOAD _mm_loadu_ps
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ensure overlapLength is divisible by 8
|
// ensure overlapLength is divisible by 8
|
||||||
assert((overlapLength % 8) == 0);
|
assert((overlapLength % 8) == 0);
|
||||||
|
@ -110,8 +110,9 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con
|
||||||
pVec2 = (const __m128*)pV2;
|
pVec2 = (const __m128*)pV2;
|
||||||
vSum = vNorm = _mm_setzero_ps();
|
vSum = vNorm = _mm_setzero_ps();
|
||||||
|
|
||||||
// Unroll the loop by factor of 4 * 4 operations
|
// Unroll the loop by factor of 4 * 4 operations. Use same routine for
|
||||||
for (i = 0; i < overlapLength / 8; i ++)
|
// stereo & mono, for mono it just means twice the amount of unrolling.
|
||||||
|
for (i = 0; i < channels * overlapLength / 16; i ++)
|
||||||
{
|
{
|
||||||
__m128 vTemp;
|
__m128 vTemp;
|
||||||
// vSum += pV1[0..3] * pV2[0..3]
|
// vSum += pV1[0..3] * pV2[0..3]
|
||||||
|
@ -152,7 +153,7 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con
|
||||||
|
|
||||||
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
// Calculates the cross-correlation value between 'pV1' and 'pV2' vectors
|
||||||
corr = norm = 0.0;
|
corr = norm = 0.0;
|
||||||
for (i = 0; i < overlapLength / 8; i ++)
|
for (i = 0; i < channels * overlapLength / 16; i ++)
|
||||||
{
|
{
|
||||||
corr += pV1[0] * pV2[0] +
|
corr += pV1[0] * pV2[0] +
|
||||||
pV1[1] * pV2[1] +
|
pV1[1] * pV2[1] +
|
||||||
|
@ -171,81 +172,13 @@ double TDStretchSSE::calcCrossCorrStereo(const float *pV1, const float *pV2) con
|
||||||
pV1[14] * pV2[14] +
|
pV1[14] * pV2[14] +
|
||||||
pV1[15] * pV2[15];
|
pV1[15] * pV2[15];
|
||||||
|
|
||||||
for (j = 0; j < 15; j ++) norm += pV1[j] * pV1[j];
|
for (j = 0; j < 15; j ++) norm += pV1[j] * pV1[j];
|
||||||
|
|
||||||
pV1 += 16;
|
pV1 += 16;
|
||||||
pV2 += 16;
|
pV2 += 16;
|
||||||
}
|
}
|
||||||
return corr / sqrt(norm);
|
return corr / sqrt(norm);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* This is a bit outdated, 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;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,15 +214,15 @@ void FIRFilterSSE::setCoefficients(const float *coeffs, uint newLength, uint uRe
|
||||||
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor);
|
||||||
|
|
||||||
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
// Scale the filter coefficients so that it won't be necessary to scale the filtering result
|
||||||
// also rearrange coefficients suitably for 3DNow!
|
// also rearrange coefficients suitably for SSE
|
||||||
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
// Ensure that filter coeffs array is aligned to 16-byte boundary
|
||||||
delete[] filterCoeffsUnalign;
|
delete[] filterCoeffsUnalign;
|
||||||
filterCoeffsUnalign = new float[2 * newLength + 4];
|
filterCoeffsUnalign = new float[2 * newLength + 4];
|
||||||
filterCoeffsAlign = (float *)(((unsigned long)filterCoeffsUnalign + 15) & (ulong)-16);
|
filterCoeffsAlign = (float *)SOUNDTOUCH_ALIGN_POINTER_16(filterCoeffsUnalign);
|
||||||
|
|
||||||
fDivider = (float)resultDivider;
|
fDivider = (float)resultDivider;
|
||||||
|
|
||||||
// rearrange the filter coefficients for mmx routines
|
// rearrange the filter coefficients for mmx routines
|
||||||
for (i = 0; i < newLength; i ++)
|
for (i = 0; i < newLength; i ++)
|
||||||
{
|
{
|
||||||
filterCoeffsAlign[2 * i + 0] =
|
filterCoeffsAlign[2 * i + 0] =
|
||||||
|
@ -313,7 +246,7 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
assert(dest != NULL);
|
assert(dest != NULL);
|
||||||
assert((length % 8) == 0);
|
assert((length % 8) == 0);
|
||||||
assert(filterCoeffsAlign != NULL);
|
assert(filterCoeffsAlign != NULL);
|
||||||
assert(((ulong)filterCoeffsAlign) % 16 == 0);
|
assert(((ulongptr)filterCoeffsAlign) % 16 == 0);
|
||||||
|
|
||||||
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
// filter is evaluated for two stereo samples with each iteration, thus use of 'j += 2'
|
||||||
for (j = 0; j < count; j += 2)
|
for (j = 0; j < count; j += 2)
|
||||||
|
@ -324,13 +257,13 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
uint i;
|
uint i;
|
||||||
|
|
||||||
pSrc = (const float*)source; // source audio data
|
pSrc = (const float*)source; // source audio data
|
||||||
pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
pFil = (const __m128*)filterCoeffsAlign; // filter coefficients. NOTE: Assumes coefficients
|
||||||
// are aligned to 16-byte boundary
|
// are aligned to 16-byte boundary
|
||||||
sum1 = sum2 = _mm_setzero_ps();
|
sum1 = sum2 = _mm_setzero_ps();
|
||||||
|
|
||||||
for (i = 0; i < length / 8; i ++)
|
for (i = 0; i < length / 8; i ++)
|
||||||
{
|
{
|
||||||
// Unroll loop for efficiency & calculate filter for 2*2 stereo samples
|
// Unroll loop for efficiency & calculate filter for 2*2 stereo samples
|
||||||
// at each pass
|
// at each pass
|
||||||
|
|
||||||
// sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset
|
// sum1 is accu for 2*2 filtered stereo sound data at the primary sound data offset
|
||||||
|
@ -365,14 +298,14 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ideas for further improvement:
|
// Ideas for further improvement:
|
||||||
// 1. If it could be guaranteed that 'source' were always aligned to 16-byte
|
// 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.
|
// 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
|
// 2. If it could be guaranteed that 'dest' were always aligned to 16-byte
|
||||||
// boundary, a faster '_mm_store_ps' instruction could be used.
|
// boundary, a faster '_mm_store_ps' instruction could be used.
|
||||||
|
|
||||||
return (uint)count;
|
return (uint)count;
|
||||||
|
|
||||||
/* original routine in C-language. please notice the C-version has differently
|
/* original routine in C-language. please notice the C-version has differently
|
||||||
organized coefficients though.
|
organized coefficients though.
|
||||||
double suml1, suml2;
|
double suml1, suml2;
|
||||||
double sumr1, sumr2;
|
double sumr1, sumr2;
|
||||||
|
@ -387,26 +320,26 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
suml2 = sumr2 = 0.0;
|
suml2 = sumr2 = 0.0;
|
||||||
ptr = src;
|
ptr = src;
|
||||||
pFil = filterCoeffs;
|
pFil = filterCoeffs;
|
||||||
for (i = 0; i < lengthLocal; i ++)
|
for (i = 0; i < lengthLocal; i ++)
|
||||||
{
|
{
|
||||||
// unroll loop for efficiency.
|
// unroll loop for efficiency.
|
||||||
|
|
||||||
suml1 += ptr[0] * pFil[0] +
|
suml1 += ptr[0] * pFil[0] +
|
||||||
ptr[2] * pFil[2] +
|
ptr[2] * pFil[2] +
|
||||||
ptr[4] * pFil[4] +
|
ptr[4] * pFil[4] +
|
||||||
ptr[6] * pFil[6];
|
ptr[6] * pFil[6];
|
||||||
|
|
||||||
sumr1 += ptr[1] * pFil[1] +
|
sumr1 += ptr[1] * pFil[1] +
|
||||||
ptr[3] * pFil[3] +
|
ptr[3] * pFil[3] +
|
||||||
ptr[5] * pFil[5] +
|
ptr[5] * pFil[5] +
|
||||||
ptr[7] * pFil[7];
|
ptr[7] * pFil[7];
|
||||||
|
|
||||||
suml2 += ptr[8] * pFil[0] +
|
suml2 += ptr[8] * pFil[0] +
|
||||||
ptr[10] * pFil[2] +
|
ptr[10] * pFil[2] +
|
||||||
ptr[12] * pFil[4] +
|
ptr[12] * pFil[4] +
|
||||||
ptr[14] * pFil[6];
|
ptr[14] * pFil[6];
|
||||||
|
|
||||||
sumr2 += ptr[9] * pFil[1] +
|
sumr2 += ptr[9] * pFil[1] +
|
||||||
ptr[11] * pFil[3] +
|
ptr[11] * pFil[3] +
|
||||||
ptr[13] * pFil[5] +
|
ptr[13] * pFil[5] +
|
||||||
ptr[15] * pFil[7];
|
ptr[15] * pFil[7];
|
||||||
|
@ -423,88 +356,6 @@ uint FIRFilterSSE::evaluateFilterStereo(float *dest, const float *source, uint n
|
||||||
dest += 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
|
#endif // SOUNDTOUCH_ALLOW_SSE
|
||||||
|
|
|
@ -641,7 +641,7 @@
|
||||||
<None Include="PCSX2.txt" />
|
<None Include="PCSX2.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="pthreads.vcxproj">
|
<ProjectReference Include="pthreads_vs11.vcxproj">
|
||||||
<Project>{26511268-2902-4997-8421-ecd7055f9e28}</Project>
|
<Project>{26511268-2902-4997-8421-ecd7055f9e28}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -0,0 +1,359 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||||
|
* Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||||
|
* nor the names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @ingroup packetapi
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @defgroup packet32h Packet.dll definitions and data structures
|
||||||
|
* Packet32.h contains the data structures and the definitions used by packet.dll.
|
||||||
|
* The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included
|
||||||
|
* by the applications that use the functions of this library
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PACKET32
|
||||||
|
#define __PACKET32
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_AIRPCAP_API
|
||||||
|
#include <airpcap.h>
|
||||||
|
#else
|
||||||
|
#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
|
||||||
|
#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
|
||||||
|
typedef struct _AirpcapHandle *PAirpcapHandle;
|
||||||
|
#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */
|
||||||
|
#endif /* HAVE_AIRPCAP_API */
|
||||||
|
|
||||||
|
#ifdef HAVE_DAG_API
|
||||||
|
#include <dagc.h>
|
||||||
|
#endif /* HAVE_DAG_API */
|
||||||
|
|
||||||
|
// Working modes
|
||||||
|
#define PACKET_MODE_CAPT 0x0 ///< Capture mode
|
||||||
|
#define PACKET_MODE_STAT 0x1 ///< Statistical mode
|
||||||
|
#define PACKET_MODE_MON 0x2 ///< Monitoring mode
|
||||||
|
#define PACKET_MODE_DUMP 0x10 ///< Dump mode
|
||||||
|
#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode
|
||||||
|
|
||||||
|
|
||||||
|
/// Alignment macro. Defines the alignment size.
|
||||||
|
#define Packet_ALIGNMENT sizeof(int)
|
||||||
|
/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
|
||||||
|
#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))
|
||||||
|
|
||||||
|
#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent
|
||||||
|
|
||||||
|
// Loopback behaviour definitions
|
||||||
|
#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver
|
||||||
|
#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Network type structure.
|
||||||
|
|
||||||
|
This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed.
|
||||||
|
*/
|
||||||
|
typedef struct NetType
|
||||||
|
{
|
||||||
|
UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information)
|
||||||
|
ULONGLONG LinkSpeed; ///< The speed of the network in bits per second
|
||||||
|
}NetType;
|
||||||
|
|
||||||
|
|
||||||
|
//some definitions stolen from libpcap
|
||||||
|
|
||||||
|
#ifndef BPF_MAJOR_VERSION
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief A BPF pseudo-assembly program.
|
||||||
|
|
||||||
|
The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet.
|
||||||
|
*/
|
||||||
|
struct bpf_program
|
||||||
|
{
|
||||||
|
UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow.
|
||||||
|
struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief A single BPF pseudo-instruction.
|
||||||
|
|
||||||
|
bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver.
|
||||||
|
*/
|
||||||
|
struct bpf_insn
|
||||||
|
{
|
||||||
|
USHORT code; ///< Instruction type and addressing mode.
|
||||||
|
UCHAR jt; ///< Jump if true
|
||||||
|
UCHAR jf; ///< Jump if false
|
||||||
|
int k; ///< Generic field used for various purposes.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Structure that contains a couple of statistics values on the current capture.
|
||||||
|
|
||||||
|
It is used by packet.dll to return statistics about a capture session.
|
||||||
|
*/
|
||||||
|
struct bpf_stat
|
||||||
|
{
|
||||||
|
UINT bs_recv; ///< Number of packets that the driver received from the network adapter
|
||||||
|
///< from the beginning of the current capture. This value includes the packets
|
||||||
|
///< lost by the driver.
|
||||||
|
UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
|
||||||
|
///< Basically, a packet is lost when the the buffer of the driver is full.
|
||||||
|
///< In this situation the packet cannot be stored and the driver rejects it.
|
||||||
|
UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
|
||||||
|
UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
|
||||||
|
///< thus reach the application.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Packet header.
|
||||||
|
|
||||||
|
This structure defines the header associated with every packet delivered to the application.
|
||||||
|
*/
|
||||||
|
struct bpf_hdr
|
||||||
|
{
|
||||||
|
struct timeval bh_tstamp; ///< The timestamp associated with the captured packet.
|
||||||
|
///< It is stored in a TimeVal structure.
|
||||||
|
UINT bh_caplen; ///< Length of captured portion. The captured portion <b>can be different</b>
|
||||||
|
///< from the original packet, because it is possible (with a proper filter)
|
||||||
|
///< to instruct the driver to capture only a portion of the packets.
|
||||||
|
UINT bh_datalen; ///< Original length of packet
|
||||||
|
USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases,
|
||||||
|
///< a padding could be added between the end of this structure and the packet
|
||||||
|
///< data for performance reasons. This filed can be used to retrieve the actual data
|
||||||
|
///< of the packet.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Dump packet header.
|
||||||
|
|
||||||
|
This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets().
|
||||||
|
It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a
|
||||||
|
packet in a dump file. This makes straightforward sending WinPcap dump files to the network.
|
||||||
|
*/
|
||||||
|
struct dump_bpf_hdr{
|
||||||
|
struct timeval ts; ///< Time stamp of the packet
|
||||||
|
UINT caplen; ///< Length of captured portion. The captured portion can smaller than the
|
||||||
|
///< the original packet, because it is possible (with a proper filter) to
|
||||||
|
///< instruct the driver to capture only a portion of the packets.
|
||||||
|
UINT len; ///< Length of the original packet (off wire).
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct bpf_stat;
|
||||||
|
|
||||||
|
#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices
|
||||||
|
#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links
|
||||||
|
#define NMAX_PACKET 65535
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Addresses of a network adapter.
|
||||||
|
|
||||||
|
This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with
|
||||||
|
an adapter.
|
||||||
|
*/
|
||||||
|
typedef struct npf_if_addr {
|
||||||
|
struct sockaddr_storage IPAddress; ///< IP address.
|
||||||
|
struct sockaddr_storage SubnetMask; ///< Netmask for that address.
|
||||||
|
struct sockaddr_storage Broadcast; ///< Broadcast address.
|
||||||
|
}npf_if_addr;
|
||||||
|
|
||||||
|
|
||||||
|
#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API.
|
||||||
|
#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API.
|
||||||
|
#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
|
||||||
|
#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
|
||||||
|
typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
|
||||||
|
|
||||||
|
#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter
|
||||||
|
#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET
|
||||||
|
#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card
|
||||||
|
#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file
|
||||||
|
#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones.
|
||||||
|
#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card
|
||||||
|
#define INFO_FLAG_NPFIM_DEVICE 32
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Describes an opened network adapter.
|
||||||
|
|
||||||
|
This structure is the most important for the functioning of packet.dll, but the great part of its fields
|
||||||
|
should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters
|
||||||
|
*/
|
||||||
|
typedef struct _ADAPTER {
|
||||||
|
HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver.
|
||||||
|
CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened.
|
||||||
|
int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated
|
||||||
|
///< on the wire.
|
||||||
|
HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter.
|
||||||
|
///< It can be passed to standard Win32 functions (like WaitForSingleObject
|
||||||
|
///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
|
||||||
|
///< data. It is particularly useful in GUI applications that need to wait
|
||||||
|
///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy()
|
||||||
|
///< function can be used to define the minimum amount of data in the kernel buffer
|
||||||
|
///< that will cause the event to be signalled.
|
||||||
|
|
||||||
|
UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and
|
||||||
|
///< ReadEvent will be signaled, also if no packets were captured
|
||||||
|
CHAR Name[ADAPTER_NAME_LENGTH];
|
||||||
|
PWAN_ADAPTER pWanAdapter;
|
||||||
|
UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
|
||||||
|
|
||||||
|
#ifdef HAVE_AIRPCAP_API
|
||||||
|
PAirpcapHandle AirpcapAd;
|
||||||
|
#endif // HAVE_AIRPCAP_API
|
||||||
|
|
||||||
|
#ifdef HAVE_NPFIM_API
|
||||||
|
void* NpfImHandle;
|
||||||
|
#endif // HAVE_NPFIM_API
|
||||||
|
|
||||||
|
#ifdef HAVE_DAG_API
|
||||||
|
dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter
|
||||||
|
PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card
|
||||||
|
struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure
|
||||||
|
unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry
|
||||||
|
DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps).
|
||||||
|
#endif // HAVE_DAG_API
|
||||||
|
} ADAPTER, *LPADAPTER;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Structure that contains a group of packets coming from the driver.
|
||||||
|
|
||||||
|
This structure defines the header associated with every packet delivered to the application.
|
||||||
|
*/
|
||||||
|
typedef struct _PACKET {
|
||||||
|
HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications.
|
||||||
|
OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications.
|
||||||
|
PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for
|
||||||
|
///< details about the organization of the data in this buffer
|
||||||
|
UINT Length; ///< Length of the buffer
|
||||||
|
DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data
|
||||||
|
///< received by the last call to PacketReceivePacket()
|
||||||
|
BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications.
|
||||||
|
} PACKET, *LPPACKET;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Structure containing an OID request.
|
||||||
|
|
||||||
|
It is used by the PacketRequest() function to send an OID to the interface card driver.
|
||||||
|
It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address,
|
||||||
|
the list of the multicast groups defined on it, and so on.
|
||||||
|
*/
|
||||||
|
struct _PACKET_OID_DATA {
|
||||||
|
ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
|
||||||
|
///< for a complete list of valid codes.
|
||||||
|
ULONG Length; ///< Length of the data field
|
||||||
|
UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
|
||||||
|
///< from the adapter.
|
||||||
|
};
|
||||||
|
typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName,
|
||||||
|
CHAR *Value,
|
||||||
|
UINT *pValueLen,
|
||||||
|
CHAR *DefaultVal);
|
||||||
|
|
||||||
|
BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName,
|
||||||
|
WCHAR *Value,
|
||||||
|
UINT *pValueLen,
|
||||||
|
WCHAR *DefaultVal);
|
||||||
|
*/
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// EXPORTED FUNCTIONS
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PCHAR PacketGetVersion();
|
||||||
|
PCHAR PacketGetDriverVersion();
|
||||||
|
BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes);
|
||||||
|
BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites);
|
||||||
|
BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode);
|
||||||
|
BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout);
|
||||||
|
BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp);
|
||||||
|
BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior);
|
||||||
|
INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen);
|
||||||
|
BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s);
|
||||||
|
BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s);
|
||||||
|
BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim);
|
||||||
|
BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type);
|
||||||
|
LPADAPTER PacketOpenAdapter(PCHAR AdapterName);
|
||||||
|
BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync);
|
||||||
|
INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync);
|
||||||
|
LPPACKET PacketAllocatePacket(void);
|
||||||
|
VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length);
|
||||||
|
VOID PacketFreePacket(LPPACKET lpPacket);
|
||||||
|
BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync);
|
||||||
|
BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter);
|
||||||
|
BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize);
|
||||||
|
BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries);
|
||||||
|
BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData);
|
||||||
|
HANDLE PacketGetReadEvent(LPADAPTER AdapterObject);
|
||||||
|
BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len);
|
||||||
|
BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks);
|
||||||
|
BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync);
|
||||||
|
BOOL PacketStopDriver();
|
||||||
|
VOID PacketCloseAdapter(LPADAPTER lpAdapter);
|
||||||
|
BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength);
|
||||||
|
BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags);
|
||||||
|
PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Used by PacketStartOemEx
|
||||||
|
//
|
||||||
|
#define PACKET_START_OEM_NO_NETMON 0x00000001
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //__PACKET32
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||||
|
* Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Politecnico di Torino, CACE Technologies
|
||||||
|
* nor the names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __WIN32_EXTENSIONS_H__
|
||||||
|
#define __WIN32_EXTENSIONS_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Definitions */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit().
|
||||||
|
*/
|
||||||
|
struct pcap_send_queue
|
||||||
|
{
|
||||||
|
u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field.
|
||||||
|
u_int len; ///< Current size of the queue, in bytes.
|
||||||
|
char *buffer; ///< Buffer containing the packets to be sent.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct pcap_send_queue pcap_send_queue;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This typedef is a support for the pcap_get_airpcap_handle() function
|
||||||
|
*/
|
||||||
|
#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
|
||||||
|
#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
|
||||||
|
typedef struct _AirpcapHandle *PAirpcapHandle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BPF_MEM_EX_IMM 0xc0
|
||||||
|
#define BPF_MEM_EX_IND 0xe0
|
||||||
|
|
||||||
|
/*used for ST*/
|
||||||
|
#define BPF_MEM_EX 0xc0
|
||||||
|
#define BPF_TME 0x08
|
||||||
|
|
||||||
|
#define BPF_LOOKUP 0x90
|
||||||
|
#define BPF_EXECUTE 0xa0
|
||||||
|
#define BPF_INIT 0xb0
|
||||||
|
#define BPF_VALIDATE 0xc0
|
||||||
|
#define BPF_SET_ACTIVE 0xd0
|
||||||
|
#define BPF_RESET 0xe0
|
||||||
|
#define BPF_SET_MEMORY 0x80
|
||||||
|
#define BPF_GET_REGISTER_VALUE 0x70
|
||||||
|
#define BPF_SET_REGISTER_VALUE 0x60
|
||||||
|
#define BPF_SET_WORKING 0x50
|
||||||
|
#define BPF_SET_ACTIVE_READ 0x40
|
||||||
|
#define BPF_SET_AUTODELETION 0x30
|
||||||
|
#define BPF_SEPARATION 0xff
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);
|
||||||
|
|
||||||
|
void pcap_sendqueue_destroy(pcap_send_queue* queue);
|
||||||
|
|
||||||
|
int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);
|
||||||
|
|
||||||
|
u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);
|
||||||
|
|
||||||
|
HANDLE pcap_getevent(pcap_t *p);
|
||||||
|
|
||||||
|
struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);
|
||||||
|
|
||||||
|
int pcap_setuserbuffer(pcap_t *p, int size);
|
||||||
|
|
||||||
|
int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks);
|
||||||
|
|
||||||
|
int pcap_live_dump_ended(pcap_t *p, int sync);
|
||||||
|
|
||||||
|
int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data);
|
||||||
|
|
||||||
|
int pcap_start_oem(char* err_str, int flags);
|
||||||
|
|
||||||
|
PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //__WIN32_EXTENSIONS_H__
|
|
@ -0,0 +1,137 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1999 WIDE Project.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the project nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _BITTYPES_H
|
||||||
|
#define _BITTYPES_H
|
||||||
|
|
||||||
|
#ifndef HAVE_U_INT8_T
|
||||||
|
|
||||||
|
#if SIZEOF_CHAR == 1
|
||||||
|
typedef unsigned char u_int8_t;
|
||||||
|
typedef signed char int8_t;
|
||||||
|
#elif SIZEOF_INT == 1
|
||||||
|
typedef unsigned int u_int8_t;
|
||||||
|
typedef signed int int8_t;
|
||||||
|
#else /* XXX */
|
||||||
|
#error "there's no appropriate type for u_int8_t"
|
||||||
|
#endif
|
||||||
|
#define HAVE_U_INT8_T 1
|
||||||
|
#define HAVE_INT8_T 1
|
||||||
|
|
||||||
|
#endif /* HAVE_U_INT8_T */
|
||||||
|
|
||||||
|
#ifndef HAVE_U_INT16_T
|
||||||
|
|
||||||
|
#if SIZEOF_SHORT == 2
|
||||||
|
typedef unsigned short u_int16_t;
|
||||||
|
typedef signed short int16_t;
|
||||||
|
#elif SIZEOF_INT == 2
|
||||||
|
typedef unsigned int u_int16_t;
|
||||||
|
typedef signed int int16_t;
|
||||||
|
#elif SIZEOF_CHAR == 2
|
||||||
|
typedef unsigned char u_int16_t;
|
||||||
|
typedef signed char int16_t;
|
||||||
|
#else /* XXX */
|
||||||
|
#error "there's no appropriate type for u_int16_t"
|
||||||
|
#endif
|
||||||
|
#define HAVE_U_INT16_T 1
|
||||||
|
#define HAVE_INT16_T 1
|
||||||
|
|
||||||
|
#endif /* HAVE_U_INT16_T */
|
||||||
|
|
||||||
|
#ifndef HAVE_U_INT32_T
|
||||||
|
|
||||||
|
#if SIZEOF_INT == 4
|
||||||
|
typedef unsigned int u_int32_t;
|
||||||
|
typedef signed int int32_t;
|
||||||
|
#elif SIZEOF_LONG == 4
|
||||||
|
typedef unsigned long u_int32_t;
|
||||||
|
typedef signed long int32_t;
|
||||||
|
#elif SIZEOF_SHORT == 4
|
||||||
|
typedef unsigned short u_int32_t;
|
||||||
|
typedef signed short int32_t;
|
||||||
|
#else /* XXX */
|
||||||
|
#error "there's no appropriate type for u_int32_t"
|
||||||
|
#endif
|
||||||
|
#define HAVE_U_INT32_T 1
|
||||||
|
#define HAVE_INT32_T 1
|
||||||
|
|
||||||
|
#endif /* HAVE_U_INT32_T */
|
||||||
|
|
||||||
|
#ifndef HAVE_U_INT64_T
|
||||||
|
#if SIZEOF_LONG_LONG == 8
|
||||||
|
typedef unsigned long long u_int64_t;
|
||||||
|
typedef long long int64_t;
|
||||||
|
#elif defined(_MSC_EXTENSIONS)
|
||||||
|
typedef unsigned _int64 u_int64_t;
|
||||||
|
typedef _int64 int64_t;
|
||||||
|
#elif SIZEOF_INT == 8
|
||||||
|
typedef unsigned int u_int64_t;
|
||||||
|
#elif SIZEOF_LONG == 8
|
||||||
|
typedef unsigned long u_int64_t;
|
||||||
|
#elif SIZEOF_SHORT == 8
|
||||||
|
typedef unsigned short u_int64_t;
|
||||||
|
#else /* XXX */
|
||||||
|
#error "there's no appropriate type for u_int64_t"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAVE_U_INT64_T */
|
||||||
|
|
||||||
|
#ifndef PRId64
|
||||||
|
#ifdef _MSC_EXTENSIONS
|
||||||
|
#define PRId64 "I64d"
|
||||||
|
#else /* _MSC_EXTENSIONS */
|
||||||
|
#define PRId64 "lld"
|
||||||
|
#endif /* _MSC_EXTENSIONS */
|
||||||
|
#endif /* PRId64 */
|
||||||
|
|
||||||
|
#ifndef PRIo64
|
||||||
|
#ifdef _MSC_EXTENSIONS
|
||||||
|
#define PRIo64 "I64o"
|
||||||
|
#else /* _MSC_EXTENSIONS */
|
||||||
|
#define PRIo64 "llo"
|
||||||
|
#endif /* _MSC_EXTENSIONS */
|
||||||
|
#endif /* PRIo64 */
|
||||||
|
|
||||||
|
#ifndef PRIx64
|
||||||
|
#ifdef _MSC_EXTENSIONS
|
||||||
|
#define PRIx64 "I64x"
|
||||||
|
#else /* _MSC_EXTENSIONS */
|
||||||
|
#define PRIx64 "llx"
|
||||||
|
#endif /* _MSC_EXTENSIONS */
|
||||||
|
#endif /* PRIx64 */
|
||||||
|
|
||||||
|
#ifndef PRIu64
|
||||||
|
#ifdef _MSC_EXTENSIONS
|
||||||
|
#define PRIu64 "I64u"
|
||||||
|
#else /* _MSC_EXTENSIONS */
|
||||||
|
#define PRIu64 "llu"
|
||||||
|
#endif /* _MSC_EXTENSIONS */
|
||||||
|
#endif /* PRIu64 */
|
||||||
|
|
||||||
|
#endif /* _BITTYPES_H */
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1993, 1994, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that: (1) source code distributions
|
||||||
|
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||||
|
* distributions including binary code include the above copyright notice and
|
||||||
|
* this paragraph in its entirety in the documentation or other materials
|
||||||
|
* provided with the distribution, and (3) all advertising materials mentioning
|
||||||
|
* features or use of this software display the following acknowledgement:
|
||||||
|
* ``This product includes software developed by the University of California,
|
||||||
|
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||||
|
* the University nor the names of its contributors may be used to endorse
|
||||||
|
* or promote products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/Win32/Include/ip6_misc.h,v 1.5 2006-01-22 18:02:18 gianluca Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#ifndef __MINGW32__
|
||||||
|
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000)
|
||||||
|
|
||||||
|
#define IN_LOOPBACKNET 127
|
||||||
|
|
||||||
|
#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
|
||||||
|
/* IPv6 address */
|
||||||
|
struct in6_addr
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
u_int8_t u6_addr8[16];
|
||||||
|
u_int16_t u6_addr16[8];
|
||||||
|
u_int32_t u6_addr32[4];
|
||||||
|
} in6_u;
|
||||||
|
#define s6_addr in6_u.u6_addr8
|
||||||
|
#define s6_addr16 in6_u.u6_addr16
|
||||||
|
#define s6_addr32 in6_u.u6_addr32
|
||||||
|
#define s6_addr64 in6_u.u6_addr64
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
|
||||||
|
#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
|
||||||
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
|
||||||
|
#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF))
|
||||||
|
typedef unsigned short sa_family_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
|
||||||
|
|
||||||
|
#define __SOCKADDR_COMMON(sa_prefix) \
|
||||||
|
sa_family_t sa_prefix##family
|
||||||
|
|
||||||
|
/* Ditto, for IPv6. */
|
||||||
|
struct sockaddr_in6
|
||||||
|
{
|
||||||
|
__SOCKADDR_COMMON (sin6_);
|
||||||
|
u_int16_t sin6_port; /* Transport layer port # */
|
||||||
|
u_int32_t sin6_flowinfo; /* IPv6 flow information */
|
||||||
|
struct in6_addr sin6_addr; /* IPv6 address */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_V4MAPPED(a) \
|
||||||
|
((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
|
||||||
|
(((u_int32_t *) (a))[2] == htonl (0xffff)))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff)
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_LINKLOCAL(a) \
|
||||||
|
((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000))
|
||||||
|
|
||||||
|
#define IN6_IS_ADDR_LOOPBACK(a) \
|
||||||
|
(((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
|
||||||
|
((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
|
||||||
|
#endif /* __MINGW32__ */
|
||||||
|
|
||||||
|
#define ip6_vfc ip6_ctlun.ip6_un2_vfc
|
||||||
|
#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
|
||||||
|
#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
|
||||||
|
#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
|
||||||
|
#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||||
|
#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
|
||||||
|
|
||||||
|
#define nd_rd_type nd_rd_hdr.icmp6_type
|
||||||
|
#define nd_rd_code nd_rd_hdr.icmp6_code
|
||||||
|
#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
|
||||||
|
#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPV6 extension headers
|
||||||
|
*/
|
||||||
|
#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
|
||||||
|
#define IPPROTO_IPV6 41 /* IPv6 header. */
|
||||||
|
#define IPPROTO_ROUTING 43 /* IPv6 routing header */
|
||||||
|
#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
|
||||||
|
#define IPPROTO_ESP 50 /* encapsulating security payload */
|
||||||
|
#define IPPROTO_AH 51 /* authentication header */
|
||||||
|
#define IPPROTO_ICMPV6 58 /* ICMPv6 */
|
||||||
|
#define IPPROTO_NONE 59 /* IPv6 no next header */
|
||||||
|
#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
|
||||||
|
#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */
|
||||||
|
|
||||||
|
#define IPV6_RTHDR_TYPE_0 0
|
||||||
|
|
||||||
|
/* Option types and related macros */
|
||||||
|
#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
|
||||||
|
#define IP6OPT_PADN 0x01 /* 00 0 00001 */
|
||||||
|
#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
|
||||||
|
#define IP6OPT_JUMBO_LEN 6
|
||||||
|
#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
|
||||||
|
|
||||||
|
#define IP6OPT_RTALERT_LEN 4
|
||||||
|
#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
|
||||||
|
#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
|
||||||
|
#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
|
||||||
|
#define IP6OPT_MINLEN 2
|
||||||
|
|
||||||
|
#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
|
||||||
|
#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
|
||||||
|
#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
|
||||||
|
#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
|
||||||
|
#define IP6OPT_EID 0x8a /* 10 0 01010 */
|
||||||
|
|
||||||
|
#define IP6OPT_TYPE(o) ((o) & 0xC0)
|
||||||
|
#define IP6OPT_TYPE_SKIP 0x00
|
||||||
|
#define IP6OPT_TYPE_DISCARD 0x40
|
||||||
|
#define IP6OPT_TYPE_FORCEICMP 0x80
|
||||||
|
#define IP6OPT_TYPE_ICMP 0xC0
|
||||||
|
|
||||||
|
#define IP6OPT_MUTABLE 0x20
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
|
||||||
|
#ifndef EAI_ADDRFAMILY
|
||||||
|
struct addrinfo {
|
||||||
|
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||||
|
int ai_family; /* PF_xxx */
|
||||||
|
int ai_socktype; /* SOCK_xxx */
|
||||||
|
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||||
|
size_t ai_addrlen; /* length of ai_addr */
|
||||||
|
char *ai_canonname; /* canonical name for hostname */
|
||||||
|
struct sockaddr *ai_addr; /* binary address */
|
||||||
|
struct addrinfo *ai_next; /* next structure in linked list */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
#endif /* __MINGW32__ */
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from the Stanford/CMU enet packet filter,
|
||||||
|
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
||||||
|
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||||
|
* Berkeley Laboratory.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.50 2007/04/01 21:43:55 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For backwards compatibility.
|
||||||
|
*
|
||||||
|
* Note to OS vendors: do NOT get rid of this file! Some applications
|
||||||
|
* might expect to be able to include <pcap-bpf.h>.
|
||||||
|
*/
|
||||||
|
#include <pcap/bpf.h>
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1994, 1996
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the Computer Systems
|
||||||
|
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||||
|
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006/10/04 18:13:32 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For backwards compatibility.
|
||||||
|
*
|
||||||
|
* Note to OS vendors: do NOT get rid of this file! Some applications
|
||||||
|
* might expect to be able to include <pcap-namedb.h>.
|
||||||
|
*/
|
||||||
|
#include <pcap/namedb.h>
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
|
||||||
|
* Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SIZEOF_CHAR 1
|
||||||
|
#define SIZEOF_SHORT 2
|
||||||
|
#define SIZEOF_INT 4
|
||||||
|
#ifndef _MSC_EXTENSIONS
|
||||||
|
#define SIZEOF_LONG_LONG 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Avoids a compiler warning in case this was already defined
|
||||||
|
* (someone defined _WINSOCKAPI_ when including 'windows.h', in order
|
||||||
|
* to prevent it from including 'winsock.h')
|
||||||
|
*/
|
||||||
|
#ifdef _WINSOCKAPI_
|
||||||
|
#undef _WINSOCKAPI_
|
||||||
|
#endif
|
||||||
|
#include <winsock2.h>
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#include "bittypes.h"
|
||||||
|
#include <time.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
#ifndef __MINGW32__
|
||||||
|
#include "IP6_misc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define caddr_t char*
|
||||||
|
|
||||||
|
#if _MSC_VER < 1500
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
#define strdup _strdup
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// PCSX2 note: MSVC2012 error with DEV9ghzdrk because of a macro redefinition here
|
||||||
|
//#define inline __inline
|
||||||
|
|
||||||
|
#ifdef __MINGW32__
|
||||||
|
#include <stdint.h>
|
||||||
|
#else /*__MINGW32__*/
|
||||||
|
/* MSVC compiler */
|
||||||
|
#ifndef _UINTPTR_T_DEFINED
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef unsigned __int64 uintptr_t;
|
||||||
|
#else
|
||||||
|
typedef _W64 unsigned int uintptr_t;
|
||||||
|
#endif
|
||||||
|
#define _UINTPTR_T_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _INTPTR_T_DEFINED
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef __int64 intptr_t;
|
||||||
|
#else
|
||||||
|
typedef _W64 int intptr_t;
|
||||||
|
#endif
|
||||||
|
#define _INTPTR_T_DEFINED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__MINGW32__*/
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the Computer Systems
|
||||||
|
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||||
|
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For backwards compatibility.
|
||||||
|
*
|
||||||
|
* Note to OS vendors: do NOT get rid of this file! Many applications
|
||||||
|
* expect to be able to include <pcap.h>, and at least some of them
|
||||||
|
* go through contortions in their configure scripts to try to detect
|
||||||
|
* OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
|
||||||
|
* leaving behind a <pcap.h> file.
|
||||||
|
*/
|
||||||
|
#include <pcap/pcap.h>
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Paolo Abeni (Italy)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* bluetooth data struct
|
||||||
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
|
||||||
|
#define _PCAP_BLUETOOTH_STRUCTS_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header prepended libpcap to each bluetooth h:4 frame.
|
||||||
|
* fields are in network byte order
|
||||||
|
*/
|
||||||
|
typedef struct _pcap_bluetooth_h4_header {
|
||||||
|
u_int32_t direction; /* if first bit is set direction is incoming */
|
||||||
|
} pcap_bluetooth_h4_header;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,934 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from the Stanford/CMU enet packet filter,
|
||||||
|
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
||||||
|
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||||
|
* Berkeley Laboratory.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)bpf.h 7.1 (Berkeley) 5/7/91
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.19.2.8 2008-09-22 20:16:01 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is libpcap's cut-down version of bpf.h; it includes only
|
||||||
|
* the stuff needed for the code generator and the userland BPF
|
||||||
|
* interpreter, and the libpcap APIs for setting filters, etc..
|
||||||
|
*
|
||||||
|
* "pcap-bpf.c" will include the native OS version, as it deals with
|
||||||
|
* the OS's BPF implementation.
|
||||||
|
*
|
||||||
|
* XXX - should this all just be moved to "pcap.h"?
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef BPF_MAJOR_VERSION
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* BSD style release date */
|
||||||
|
#define BPF_RELEASE 199606
|
||||||
|
|
||||||
|
#ifdef MSDOS /* must be 32-bit */
|
||||||
|
typedef long bpf_int32;
|
||||||
|
typedef unsigned long bpf_u_int32;
|
||||||
|
#else
|
||||||
|
typedef int bpf_int32;
|
||||||
|
typedef u_int bpf_u_int32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alignment macros. BPF_WORDALIGN rounds up to the next
|
||||||
|
* even multiple of BPF_ALIGNMENT.
|
||||||
|
*/
|
||||||
|
#ifndef __NetBSD__
|
||||||
|
#define BPF_ALIGNMENT sizeof(bpf_int32)
|
||||||
|
#else
|
||||||
|
#define BPF_ALIGNMENT sizeof(long)
|
||||||
|
#endif
|
||||||
|
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
|
||||||
|
|
||||||
|
#define BPF_MAXBUFSIZE 0x8000
|
||||||
|
#define BPF_MINBUFSIZE 32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure for "pcap_compile()", "pcap_setfilter()", etc..
|
||||||
|
*/
|
||||||
|
struct bpf_program {
|
||||||
|
u_int bf_len;
|
||||||
|
struct bpf_insn *bf_insns;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Struct return by BIOCVERSION. This represents the version number of
|
||||||
|
* the filter language described by the instruction encodings below.
|
||||||
|
* bpf understands a program iff kernel_major == filter_major &&
|
||||||
|
* kernel_minor >= filter_minor, that is, if the value returned by the
|
||||||
|
* running kernel has the same major number and a minor number equal
|
||||||
|
* equal to or less than the filter being downloaded. Otherwise, the
|
||||||
|
* results are undefined, meaning an error may be returned or packets
|
||||||
|
* may be accepted haphazardly.
|
||||||
|
* It has nothing to do with the source code version.
|
||||||
|
*/
|
||||||
|
struct bpf_version {
|
||||||
|
u_short bv_major;
|
||||||
|
u_short bv_minor;
|
||||||
|
};
|
||||||
|
/* Current version number of filter architecture. */
|
||||||
|
#define BPF_MAJOR_VERSION 1
|
||||||
|
#define BPF_MINOR_VERSION 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Data-link level type codes.
|
||||||
|
*
|
||||||
|
* Do *NOT* add new values to this list without asking
|
||||||
|
* "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run
|
||||||
|
* the risk of using a value that's already being used for some other
|
||||||
|
* purpose, and of having tools that read libpcap-format captures not
|
||||||
|
* being able to handle captures with your new DLT_ value, with no hope
|
||||||
|
* that they will ever be changed to do so (as that would destroy their
|
||||||
|
* ability to read captures using that value for that other purpose).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are the types that are the same on all platforms, and that
|
||||||
|
* have been defined by <net/bpf.h> for ages.
|
||||||
|
*/
|
||||||
|
#define DLT_NULL 0 /* BSD loopback encapsulation */
|
||||||
|
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
|
||||||
|
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
|
||||||
|
#define DLT_AX25 3 /* Amateur Radio AX.25 */
|
||||||
|
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
|
||||||
|
#define DLT_CHAOS 5 /* Chaos */
|
||||||
|
#define DLT_IEEE802 6 /* 802.5 Token Ring */
|
||||||
|
#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
|
||||||
|
#define DLT_SLIP 8 /* Serial Line IP */
|
||||||
|
#define DLT_PPP 9 /* Point-to-point Protocol */
|
||||||
|
#define DLT_FDDI 10 /* FDDI */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These are types that are different on some platforms, and that
|
||||||
|
* have been defined by <net/bpf.h> for ages. We use #ifdefs to
|
||||||
|
* detect the BSDs that define them differently from the traditional
|
||||||
|
* libpcap <net/bpf.h>
|
||||||
|
*
|
||||||
|
* XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
|
||||||
|
* but I don't know what the right #define is for BSD/OS.
|
||||||
|
*/
|
||||||
|
#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
#define DLT_RAW 14 /* raw IP */
|
||||||
|
#else
|
||||||
|
#define DLT_RAW 12 /* raw IP */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Given that the only OS that currently generates BSD/OS SLIP or PPP
|
||||||
|
* is, well, BSD/OS, arguably everybody should have chosen its values
|
||||||
|
* for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
|
||||||
|
* didn't. So it goes.
|
||||||
|
*/
|
||||||
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||||
|
#ifndef DLT_SLIP_BSDOS
|
||||||
|
#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
|
||||||
|
#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
|
||||||
|
#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 17 is used for DLT_OLD_PFLOG in OpenBSD;
|
||||||
|
* OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
|
||||||
|
* 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apparently Redback uses this for its SmartEdge 400/800. I hope
|
||||||
|
* nobody else decided to use it, too.
|
||||||
|
*/
|
||||||
|
#define DLT_REDBACK_SMARTEDGE 32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These values are defined by NetBSD; other platforms should refrain from
|
||||||
|
* using them for other purposes, so that NetBSD savefiles with link
|
||||||
|
* types of 50 or 51 can be read as this type on all platforms.
|
||||||
|
*/
|
||||||
|
#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
|
||||||
|
#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
|
||||||
|
* a link-layer type of 99 for the tcpdump it supplies. The link-layer
|
||||||
|
* header has 6 bytes of unknown data, something that appears to be an
|
||||||
|
* Ethernet type, and 36 bytes that appear to be 0 in at least one capture
|
||||||
|
* I've seen.
|
||||||
|
*/
|
||||||
|
#define DLT_SYMANTEC_FIREWALL 99
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values between 100 and 103 are used in capture file headers as
|
||||||
|
* link-layer types corresponding to DLT_ types that differ
|
||||||
|
* between platforms; don't use those values for new DLT_ new types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This value was defined by libpcap 0.5; platforms that have defined
|
||||||
|
* it with a different value should define it here with that value -
|
||||||
|
* a link type of 104 in a save file will be mapped to DLT_C_HDLC,
|
||||||
|
* whatever value that happens to be, so programs will correctly
|
||||||
|
* handle files with that link type regardless of the value of
|
||||||
|
* DLT_C_HDLC.
|
||||||
|
*
|
||||||
|
* The name DLT_C_HDLC was used by BSD/OS; we use that name for source
|
||||||
|
* compatibility with programs written for BSD/OS.
|
||||||
|
*
|
||||||
|
* libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
|
||||||
|
* for source compatibility with programs written for libpcap 0.5.
|
||||||
|
*/
|
||||||
|
#define DLT_C_HDLC 104 /* Cisco HDLC */
|
||||||
|
#define DLT_CHDLC DLT_C_HDLC
|
||||||
|
|
||||||
|
#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
|
||||||
|
* except when it isn't. (I.e., sometimes it's just raw IP, and
|
||||||
|
* sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
|
||||||
|
* so that we don't have to worry about the link-layer header.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
|
||||||
|
* with other values.
|
||||||
|
* DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
|
||||||
|
* (DLCI, etc.).
|
||||||
|
*/
|
||||||
|
#define DLT_FRELAY 107
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
|
||||||
|
* that the AF_ type in the link-layer header is in network byte order.
|
||||||
|
*
|
||||||
|
* DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
|
||||||
|
* we don't use 12 for it in OSes other than OpenBSD.
|
||||||
|
*/
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
#define DLT_LOOP 12
|
||||||
|
#else
|
||||||
|
#define DLT_LOOP 108
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
|
||||||
|
* DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
|
||||||
|
* than OpenBSD.
|
||||||
|
*/
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
#define DLT_ENC 13
|
||||||
|
#else
|
||||||
|
#define DLT_ENC 109
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Values between 110 and 112 are reserved for use in capture file headers
|
||||||
|
* as link-layer types corresponding to DLT_ types that might differ
|
||||||
|
* between platforms; don't use those values for new DLT_ types
|
||||||
|
* other than the corresponding DLT_ types.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is for Linux cooked sockets.
|
||||||
|
*/
|
||||||
|
#define DLT_LINUX_SLL 113
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apple LocalTalk hardware.
|
||||||
|
*/
|
||||||
|
#define DLT_LTALK 114
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Acorn Econet.
|
||||||
|
*/
|
||||||
|
#define DLT_ECONET 115
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for use with OpenBSD ipfilter.
|
||||||
|
*/
|
||||||
|
#define DLT_IPFILTER 116
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
|
||||||
|
* in SuSE 6.3, so we can't use 17 for it in capture-file headers.
|
||||||
|
*
|
||||||
|
* XXX: is there a conflict with DLT_PFSYNC 18 as well?
|
||||||
|
*/
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
#define DLT_OLD_PFLOG 17
|
||||||
|
#define DLT_PFSYNC 18
|
||||||
|
#endif
|
||||||
|
#define DLT_PFLOG 117
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Registered for Cisco-internal use.
|
||||||
|
*/
|
||||||
|
#define DLT_CISCO_IOS 118
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For 802.11 cards using the Prism II chips, with a link-layer
|
||||||
|
* header including Prism monitor mode information plus an 802.11
|
||||||
|
* header.
|
||||||
|
*/
|
||||||
|
#define DLT_PRISM_HEADER 119
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for Aironet 802.11 cards, with an Aironet link-layer header
|
||||||
|
* (see Doug Ambrisko's FreeBSD patches).
|
||||||
|
*/
|
||||||
|
#define DLT_AIRONET_HEADER 120
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for Siemens HiPath HDLC.
|
||||||
|
*/
|
||||||
|
#define DLT_HHDLC 121
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is for RFC 2625 IP-over-Fibre Channel.
|
||||||
|
*
|
||||||
|
* This is not for use with raw Fibre Channel, where the link-layer
|
||||||
|
* header starts with a Fibre Channel frame header; it's for IP-over-FC,
|
||||||
|
* where the link-layer header starts with an RFC 2625 Network_Header
|
||||||
|
* field.
|
||||||
|
*/
|
||||||
|
#define DLT_IP_OVER_FC 122
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is for Full Frontal ATM on Solaris with SunATM, with a
|
||||||
|
* pseudo-header followed by an AALn PDU.
|
||||||
|
*
|
||||||
|
* There may be other forms of Full Frontal ATM on other OSes,
|
||||||
|
* with different pseudo-headers.
|
||||||
|
*
|
||||||
|
* If ATM software returns a pseudo-header with VPI/VCI information
|
||||||
|
* (and, ideally, packet type information, e.g. signalling, ILMI,
|
||||||
|
* LANE, LLC-multiplexed traffic, etc.), it should not use
|
||||||
|
* DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
|
||||||
|
* and the like don't have to infer the presence or absence of a
|
||||||
|
* pseudo-header and the form of the pseudo-header.
|
||||||
|
*/
|
||||||
|
#define DLT_SUNATM 123 /* Solaris+SunATM */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved as per request from Kent Dahlgren <kent@praesum.com>
|
||||||
|
* for private use.
|
||||||
|
*/
|
||||||
|
#define DLT_RIO 124 /* RapidIO */
|
||||||
|
#define DLT_PCI_EXP 125 /* PCI Express */
|
||||||
|
#define DLT_AURORA 126 /* Xilinx Aurora link layer */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header for 802.11 plus a number of bits of link-layer information
|
||||||
|
* including radio information, used by some recent BSD drivers as
|
||||||
|
* well as the madwifi Atheros driver for Linux.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for the TZSP encapsulation, as per request from
|
||||||
|
* Chris Waters <chris.waters@networkchemistry.com>
|
||||||
|
* TZSP is a generic encapsulation for any other link type,
|
||||||
|
* which includes a means to include meta-information
|
||||||
|
* with the packet, e.g. signal strength and channel
|
||||||
|
* for 802.11 packets.
|
||||||
|
*/
|
||||||
|
#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BSD's ARCNET headers have the source host, destination host,
|
||||||
|
* and type at the beginning of the packet; that's what's handed
|
||||||
|
* up to userland via BPF.
|
||||||
|
*
|
||||||
|
* Linux's ARCNET headers, however, have a 2-byte offset field
|
||||||
|
* between the host IDs and the type; that's what's handed up
|
||||||
|
* to userland via PF_PACKET sockets.
|
||||||
|
*
|
||||||
|
* We therefore have to have separate DLT_ values for them.
|
||||||
|
*/
|
||||||
|
#define DLT_ARCNET_LINUX 129 /* ARCNET */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link types, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
|
||||||
|
* for passing on chassis-internal metainformation such as
|
||||||
|
* QOS profiles, etc..
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_MLPPP 130
|
||||||
|
#define DLT_JUNIPER_MLFR 131
|
||||||
|
#define DLT_JUNIPER_ES 132
|
||||||
|
#define DLT_JUNIPER_GGSN 133
|
||||||
|
#define DLT_JUNIPER_MFR 134
|
||||||
|
#define DLT_JUNIPER_ATM2 135
|
||||||
|
#define DLT_JUNIPER_SERVICES 136
|
||||||
|
#define DLT_JUNIPER_ATM1 137
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund
|
||||||
|
* <dieter@apple.com>. The header that's presented is an Ethernet-like
|
||||||
|
* header:
|
||||||
|
*
|
||||||
|
* #define FIREWIRE_EUI64_LEN 8
|
||||||
|
* struct firewire_header {
|
||||||
|
* u_char firewire_dhost[FIREWIRE_EUI64_LEN];
|
||||||
|
* u_char firewire_shost[FIREWIRE_EUI64_LEN];
|
||||||
|
* u_short firewire_type;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* with "firewire_type" being an Ethernet type value, rather than,
|
||||||
|
* for example, raw GASP frames being handed up.
|
||||||
|
*/
|
||||||
|
#define DLT_APPLE_IP_OVER_IEEE1394 138
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various SS7 encapsulations, as per a request from Jeff Morriss
|
||||||
|
* <jeff.morriss[AT]ulticom.com> and subsequent discussions.
|
||||||
|
*/
|
||||||
|
#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
|
||||||
|
#define DLT_MTP2 140 /* MTP2, without pseudo-header */
|
||||||
|
#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
|
||||||
|
#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DOCSIS MAC frames.
|
||||||
|
*/
|
||||||
|
#define DLT_DOCSIS 143
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Linux-IrDA packets. Protocol defined at http://www.irda.org.
|
||||||
|
* Those packets include IrLAP headers and above (IrLMP...), but
|
||||||
|
* don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
|
||||||
|
* framing can be handled by the hardware and depend on the bitrate.
|
||||||
|
* This is exactly the format you would get capturing on a Linux-IrDA
|
||||||
|
* interface (irdaX), but not on a raw serial port.
|
||||||
|
* Note the capture is done in "Linux-cooked" mode, so each packet include
|
||||||
|
* a fake packet header (struct sll_header). This is because IrDA packet
|
||||||
|
* decoding is dependant on the direction of the packet (incomming or
|
||||||
|
* outgoing).
|
||||||
|
* When/if other platform implement IrDA capture, we may revisit the
|
||||||
|
* issue and define a real DLT_IRDA...
|
||||||
|
* Jean II
|
||||||
|
*/
|
||||||
|
#define DLT_LINUX_IRDA 144
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for IBM SP switch and IBM Next Federation switch.
|
||||||
|
*/
|
||||||
|
#define DLT_IBM_SP 145
|
||||||
|
#define DLT_IBM_SN 146
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for private use. If you have some link-layer header type
|
||||||
|
* that you want to use within your organization, with the capture files
|
||||||
|
* using that link-layer header type not ever be sent outside your
|
||||||
|
* organization, you can use these values.
|
||||||
|
*
|
||||||
|
* No libpcap release will use these for any purpose, nor will any
|
||||||
|
* tcpdump release use them, either.
|
||||||
|
*
|
||||||
|
* Do *NOT* use these in capture files that you expect anybody not using
|
||||||
|
* your private versions of capture-file-reading tools to read; in
|
||||||
|
* particular, do *NOT* use them in products, otherwise you may find that
|
||||||
|
* people won't be able to use tcpdump, or snort, or Ethereal, or... to
|
||||||
|
* read capture files from your firewall/intrusion detection/traffic
|
||||||
|
* monitoring/etc. appliance, or whatever product uses that DLT_ value,
|
||||||
|
* and you may also find that the developers of those applications will
|
||||||
|
* not accept patches to let them read those files.
|
||||||
|
*
|
||||||
|
* Also, do not use them if somebody might send you a capture using them
|
||||||
|
* for *their* private type and tools using them for *your* private type
|
||||||
|
* would have to read them.
|
||||||
|
*
|
||||||
|
* Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value,
|
||||||
|
* as per the comment above, and use the type you're given.
|
||||||
|
*/
|
||||||
|
#define DLT_USER0 147
|
||||||
|
#define DLT_USER1 148
|
||||||
|
#define DLT_USER2 149
|
||||||
|
#define DLT_USER3 150
|
||||||
|
#define DLT_USER4 151
|
||||||
|
#define DLT_USER5 152
|
||||||
|
#define DLT_USER6 153
|
||||||
|
#define DLT_USER7 154
|
||||||
|
#define DLT_USER8 155
|
||||||
|
#define DLT_USER9 156
|
||||||
|
#define DLT_USER10 157
|
||||||
|
#define DLT_USER11 158
|
||||||
|
#define DLT_USER12 159
|
||||||
|
#define DLT_USER13 160
|
||||||
|
#define DLT_USER14 161
|
||||||
|
#define DLT_USER15 162
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For future use with 802.11 captures - defined by AbsoluteValue
|
||||||
|
* Systems to store a number of bits of link-layer information
|
||||||
|
* including radio information:
|
||||||
|
*
|
||||||
|
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
|
||||||
|
*
|
||||||
|
* but it might be used by some non-AVS drivers now or in the
|
||||||
|
* future.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
|
||||||
|
* for passing on chassis-internal metainformation such as
|
||||||
|
* QOS profiles, etc..
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_MONITOR 164
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reserved for BACnet MS/TP.
|
||||||
|
*/
|
||||||
|
#define DLT_BACNET_MS_TP 165
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
|
||||||
|
*
|
||||||
|
* This is used in some OSes to allow a kernel socket filter to distinguish
|
||||||
|
* between incoming and outgoing packets, on a socket intended to
|
||||||
|
* supply pppd with outgoing packets so it can do dial-on-demand and
|
||||||
|
* hangup-on-lack-of-demand; incoming packets are filtered out so they
|
||||||
|
* don't cause pppd to hold the connection up (you don't want random
|
||||||
|
* input packets such as port scans, packets from old lost connections,
|
||||||
|
* etc. to force the connection to stay up).
|
||||||
|
*
|
||||||
|
* The first byte of the PPP header (0xff03) is modified to accomodate
|
||||||
|
* the direction - 0x00 = IN, 0x01 = OUT.
|
||||||
|
*/
|
||||||
|
#define DLT_PPP_PPPD 166
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Names for backwards compatibility with older versions of some PPP
|
||||||
|
* software; new software should use DLT_PPP_PPPD.
|
||||||
|
*/
|
||||||
|
#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
|
||||||
|
#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>. The DLT_s are used
|
||||||
|
* for passing on chassis-internal metainformation such as
|
||||||
|
* QOS profiles, cookies, etc..
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_PPPOE 167
|
||||||
|
#define DLT_JUNIPER_PPPOE_ATM 168
|
||||||
|
|
||||||
|
#define DLT_GPRS_LLC 169 /* GPRS LLC */
|
||||||
|
#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
|
||||||
|
#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
|
||||||
|
* monitoring equipment.
|
||||||
|
*/
|
||||||
|
#define DLT_GCOM_T1E1 172
|
||||||
|
#define DLT_GCOM_SERIAL 173
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>. The DLT_ is used
|
||||||
|
* for internal communication to Physical Interface Cards (PIC)
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_PIC_PEER 174
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Link types requested by Gregor Maier <gregor@endace.com> of Endace
|
||||||
|
* Measurement Systems. They add an ERF header (see
|
||||||
|
* http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
|
||||||
|
* the link-layer header.
|
||||||
|
*/
|
||||||
|
#define DLT_ERF_ETH 175 /* Ethernet */
|
||||||
|
#define DLT_ERF_POS 176 /* Packet-over-SONET */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
|
||||||
|
* for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
|
||||||
|
* includes additional information before the LAPD header, so it's
|
||||||
|
* not necessarily a generic LAPD header.
|
||||||
|
*/
|
||||||
|
#define DLT_LINUX_LAPD 177
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>.
|
||||||
|
* The DLT_ are used for prepending meta-information
|
||||||
|
* like interface index, interface name
|
||||||
|
* before standard Ethernet, PPP, Frelay & C-HDLC Frames
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_ETHER 178
|
||||||
|
#define DLT_JUNIPER_PPP 179
|
||||||
|
#define DLT_JUNIPER_FRELAY 180
|
||||||
|
#define DLT_JUNIPER_CHDLC 181
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Multi Link Frame Relay (FRF.16)
|
||||||
|
*/
|
||||||
|
#define DLT_MFR 182
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>.
|
||||||
|
* The DLT_ is used for internal communication with a
|
||||||
|
* voice Adapter Card (PIC)
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_VP 183
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arinc 429 frames.
|
||||||
|
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
|
||||||
|
* Every frame contains a 32bit A429 label.
|
||||||
|
* More documentation on Arinc 429 can be found at
|
||||||
|
* http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
|
||||||
|
*/
|
||||||
|
#define DLT_A429 184
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Arinc 653 Interpartition Communication messages.
|
||||||
|
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
|
||||||
|
* Please refer to the A653-1 standard for more information.
|
||||||
|
*/
|
||||||
|
#define DLT_A653_ICM 185
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB packets, beginning with a USB setup header; requested by
|
||||||
|
* Paolo Abeni <paolo.abeni@email.it>.
|
||||||
|
*/
|
||||||
|
#define DLT_USB 186
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bluetooth HCI UART transport layer (part H:4); requested by
|
||||||
|
* Paolo Abeni.
|
||||||
|
*/
|
||||||
|
#define DLT_BLUETOOTH_HCI_H4 187
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
|
||||||
|
* <cruz_petagay@bah.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_16_MAC_CPS 188
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB packets, beginning with a Linux USB header; requested by
|
||||||
|
* Paolo Abeni <paolo.abeni@email.it>.
|
||||||
|
*/
|
||||||
|
#define DLT_USB_LINUX 189
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Controller Area Network (CAN) v. 2.0B packets.
|
||||||
|
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
|
||||||
|
* Used to dump CAN packets coming from a CAN Vector board.
|
||||||
|
* More documentation on the CAN v2.0B frames can be found at
|
||||||
|
* http://www.can-cia.org/downloads/?269
|
||||||
|
*/
|
||||||
|
#define DLT_CAN20B 190
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IEEE 802.15.4, with address fields padded, as is done by Linux
|
||||||
|
* drivers; requested by Juergen Schimmer.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_15_4_LINUX 191
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Per Packet Information encapsulated packets.
|
||||||
|
* DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_PPI 192
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
|
||||||
|
* requested by Charles Clancy.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_16_MAC_CPS_RADIO 193
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>.
|
||||||
|
* The DLT_ is used for internal communication with a
|
||||||
|
* integrated service module (ISM).
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_ISM 194
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
|
||||||
|
* nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_15_4 195
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various link-layer types, with a pseudo-header, for SITA
|
||||||
|
* (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
|
||||||
|
*/
|
||||||
|
#define DLT_SITA 196
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various link-layer types, with a pseudo-header, for Endace DAG cards;
|
||||||
|
* encapsulates Endace ERF records. Requested by Stephen Donnelly
|
||||||
|
* <stephen@endace.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_ERF 197
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Special header prepended to Ethernet packets when capturing from a
|
||||||
|
* u10 Networks board. Requested by Phil Mulholland
|
||||||
|
* <phil@u10networks.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_RAIF1 198
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPMB packet for IPMI, beginning with the I2C slave address, followed
|
||||||
|
* by the netFn and LUN, etc.. Requested by Chanthy Toeung
|
||||||
|
* <chanthy.toeung@ca.kontron.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_IPMB 199
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Juniper-private data link type, as per request from
|
||||||
|
* Hannes Gredler <hannes@juniper.net>.
|
||||||
|
* The DLT_ is used for capturing data on a secure tunnel interface.
|
||||||
|
*/
|
||||||
|
#define DLT_JUNIPER_ST 200
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bluetooth HCI UART transport layer (part H:4), with pseudo-header
|
||||||
|
* that includes direction information; requested by Paolo Abeni.
|
||||||
|
*/
|
||||||
|
#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AX.25 packet with a 1-byte KISS header; see
|
||||||
|
*
|
||||||
|
* http://www.ax25.net/kiss.htm
|
||||||
|
*
|
||||||
|
* as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
|
||||||
|
*/
|
||||||
|
#define DLT_AX25_KISS 202
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LAPD packets from an ISDN channel, starting with the address field,
|
||||||
|
* with no pseudo-header.
|
||||||
|
* Requested by Varuna De Silva <varunax@gmail.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_LAPD 203
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Variants of various link-layer headers, with a one-byte direction
|
||||||
|
* pseudo-header prepended - zero means "received by this host",
|
||||||
|
* non-zero (any non-zero value) means "sent by this host" - as per
|
||||||
|
* Will Barker <w.barker@zen.co.uk>.
|
||||||
|
*/
|
||||||
|
#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
|
||||||
|
#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
|
||||||
|
#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
|
||||||
|
#define DLT_LAPB_WITH_DIR 207 /* LAPB */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 208 is reserved for an as-yet-unspecified proprietary link-layer
|
||||||
|
* type, as requested by Will Barker.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
|
||||||
|
* <avn@pigeonpoint.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_IPMB_LINUX 209
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FlexRay automotive bus - http://www.flexray.com/ - as requested
|
||||||
|
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
|
||||||
|
*/
|
||||||
|
#define DLT_FLEXRAY 210
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Media Oriented Systems Transport (MOST) bus for multimedia
|
||||||
|
* transport - http://www.mostcooperation.com/ - as requested
|
||||||
|
* by Hannes Kaelber <hannes.kaelber@x2e.de>.
|
||||||
|
*/
|
||||||
|
#define DLT_MOST 211
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Interconnect Network (LIN) bus for vehicle networks -
|
||||||
|
* http://www.lin-subbus.org/ - as requested by Hannes Kaelber
|
||||||
|
* <hannes.kaelber@x2e.de>.
|
||||||
|
*/
|
||||||
|
#define DLT_LIN 212
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X2E-private data link type used for serial line capture,
|
||||||
|
* as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
|
||||||
|
*/
|
||||||
|
#define DLT_X2E_SERIAL 213
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X2E-private data link type used for the Xoraya data logger
|
||||||
|
* family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
|
||||||
|
*/
|
||||||
|
#define DLT_X2E_XORAYA 214
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IEEE 802.15.4, exactly as it appears in the spec (no padding, no
|
||||||
|
* nothing), but with the PHY-level data for non-ASK PHYs (4 octets
|
||||||
|
* of 0 as preamble, one octet of SFD, one octet of frame length+
|
||||||
|
* reserved bit, and then the MAC-layer data, starting with the
|
||||||
|
* frame control field).
|
||||||
|
*
|
||||||
|
* Requested by Max Filippov <jcmvbkbc@gmail.com>.
|
||||||
|
*/
|
||||||
|
#define DLT_IEEE802_15_4_NONASK_PHY 215
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DLT and savefile link type values are split into a class and
|
||||||
|
* a member of that class. A class value of 0 indicates a regular
|
||||||
|
* DLT_/LINKTYPE_ value.
|
||||||
|
*/
|
||||||
|
#define DLT_CLASS(x) ((x) & 0x03ff0000)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NetBSD-specific generic "raw" link type. The class value indicates
|
||||||
|
* that this is the generic raw type, and the lower 16 bits are the
|
||||||
|
* address family we're dealing with. Those values are NetBSD-specific;
|
||||||
|
* do not assume that they correspond to AF_ values for your operating
|
||||||
|
* system.
|
||||||
|
*/
|
||||||
|
#define DLT_CLASS_NETBSD_RAWAF 0x02240000
|
||||||
|
#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af))
|
||||||
|
#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff)
|
||||||
|
#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The instruction encodings.
|
||||||
|
*/
|
||||||
|
/* instruction classes */
|
||||||
|
#define BPF_CLASS(code) ((code) & 0x07)
|
||||||
|
#define BPF_LD 0x00
|
||||||
|
#define BPF_LDX 0x01
|
||||||
|
#define BPF_ST 0x02
|
||||||
|
#define BPF_STX 0x03
|
||||||
|
#define BPF_ALU 0x04
|
||||||
|
#define BPF_JMP 0x05
|
||||||
|
#define BPF_RET 0x06
|
||||||
|
#define BPF_MISC 0x07
|
||||||
|
|
||||||
|
/* ld/ldx fields */
|
||||||
|
#define BPF_SIZE(code) ((code) & 0x18)
|
||||||
|
#define BPF_W 0x00
|
||||||
|
#define BPF_H 0x08
|
||||||
|
#define BPF_B 0x10
|
||||||
|
#define BPF_MODE(code) ((code) & 0xe0)
|
||||||
|
#define BPF_IMM 0x00
|
||||||
|
#define BPF_ABS 0x20
|
||||||
|
#define BPF_IND 0x40
|
||||||
|
#define BPF_MEM 0x60
|
||||||
|
#define BPF_LEN 0x80
|
||||||
|
#define BPF_MSH 0xa0
|
||||||
|
|
||||||
|
/* alu/jmp fields */
|
||||||
|
#define BPF_OP(code) ((code) & 0xf0)
|
||||||
|
#define BPF_ADD 0x00
|
||||||
|
#define BPF_SUB 0x10
|
||||||
|
#define BPF_MUL 0x20
|
||||||
|
#define BPF_DIV 0x30
|
||||||
|
#define BPF_OR 0x40
|
||||||
|
#define BPF_AND 0x50
|
||||||
|
#define BPF_LSH 0x60
|
||||||
|
#define BPF_RSH 0x70
|
||||||
|
#define BPF_NEG 0x80
|
||||||
|
#define BPF_JA 0x00
|
||||||
|
#define BPF_JEQ 0x10
|
||||||
|
#define BPF_JGT 0x20
|
||||||
|
#define BPF_JGE 0x30
|
||||||
|
#define BPF_JSET 0x40
|
||||||
|
#define BPF_SRC(code) ((code) & 0x08)
|
||||||
|
#define BPF_K 0x00
|
||||||
|
#define BPF_X 0x08
|
||||||
|
|
||||||
|
/* ret - BPF_K and BPF_X also apply */
|
||||||
|
#define BPF_RVAL(code) ((code) & 0x18)
|
||||||
|
#define BPF_A 0x10
|
||||||
|
|
||||||
|
/* misc */
|
||||||
|
#define BPF_MISCOP(code) ((code) & 0xf8)
|
||||||
|
#define BPF_TAX 0x00
|
||||||
|
#define BPF_TXA 0x80
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The instruction data structure.
|
||||||
|
*/
|
||||||
|
struct bpf_insn {
|
||||||
|
u_short code;
|
||||||
|
u_char jt;
|
||||||
|
u_char jf;
|
||||||
|
bpf_u_int32 k;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros for insn array initializers.
|
||||||
|
*/
|
||||||
|
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
|
||||||
|
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
|
||||||
|
|
||||||
|
#if __STDC__ || defined(__cplusplus)
|
||||||
|
extern int bpf_validate(const struct bpf_insn *, int);
|
||||||
|
extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
|
||||||
|
#else
|
||||||
|
extern int bpf_validate();
|
||||||
|
extern u_int bpf_filter();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
|
||||||
|
*/
|
||||||
|
#define BPF_MEMWORDS 16
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1994, 1996
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the Computer Systems
|
||||||
|
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||||
|
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006/10/04 18:09:22 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lib_pcap_namedb_h
|
||||||
|
#define lib_pcap_namedb_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As returned by the pcap_next_etherent()
|
||||||
|
* XXX this stuff doesn't belong in this interface, but this
|
||||||
|
* library already must do name to address translation, so
|
||||||
|
* on systems that don't have support for /etc/ethers, we
|
||||||
|
* export these hooks since they'll
|
||||||
|
*/
|
||||||
|
struct pcap_etherent {
|
||||||
|
u_char addr[6];
|
||||||
|
char name[122];
|
||||||
|
};
|
||||||
|
#ifndef PCAP_ETHERS_FILE
|
||||||
|
#define PCAP_ETHERS_FILE "/etc/ethers"
|
||||||
|
#endif
|
||||||
|
struct pcap_etherent *pcap_next_etherent(FILE *);
|
||||||
|
u_char *pcap_ether_hostton(const char*);
|
||||||
|
u_char *pcap_ether_aton(const char *);
|
||||||
|
|
||||||
|
bpf_u_int32 **pcap_nametoaddr(const char *);
|
||||||
|
#ifdef INET6
|
||||||
|
struct addrinfo *pcap_nametoaddrinfo(const char *);
|
||||||
|
#endif
|
||||||
|
bpf_u_int32 pcap_nametonetaddr(const char *);
|
||||||
|
|
||||||
|
int pcap_nametoport(const char *, int *, int *);
|
||||||
|
int pcap_nametoportrange(const char *, int *, int *, int *);
|
||||||
|
int pcap_nametoproto(const char *);
|
||||||
|
int pcap_nametoeproto(const char *);
|
||||||
|
int pcap_nametollc(const char *);
|
||||||
|
/*
|
||||||
|
* If a protocol is unknown, PROTO_UNDEF is returned.
|
||||||
|
* Also, pcap_nametoport() returns the protocol along with the port number.
|
||||||
|
* If there are ambiguous entried in /etc/services (i.e. domain
|
||||||
|
* can be either tcp or udp) PROTO_UNDEF is returned.
|
||||||
|
*/
|
||||||
|
#define PROTO_UNDEF -1
|
||||||
|
|
||||||
|
/* XXX move these to pcap-int.h? */
|
||||||
|
int __pcap_atodn(const char *, bpf_u_int32 *);
|
||||||
|
int __pcap_atoin(const char *, bpf_u_int32 *);
|
||||||
|
u_short __pcap_nametodnaddr(const char *);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,407 @@
|
||||||
|
/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the Computer Systems
|
||||||
|
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||||
|
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||||
|
* to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lib_pcap_pcap_h
|
||||||
|
#define lib_pcap_pcap_h
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
#include <pcap-stdinc.h>
|
||||||
|
#elif defined(MSDOS)
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h> /* u_int, u_char etc. */
|
||||||
|
#else /* UN*X */
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif /* WIN32/MSDOS/UN*X */
|
||||||
|
|
||||||
|
#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||||
|
#include <pcap/bpf.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTE
|
||||||
|
// We have to define the SOCKET here, although it has been defined in sockutils.h
|
||||||
|
// This is to avoid the distribution of the 'sockutils.h' file around
|
||||||
|
// (for example in the WinPcap developer's pack)
|
||||||
|
#ifndef SOCKET
|
||||||
|
#ifdef WIN32
|
||||||
|
#define SOCKET unsigned int
|
||||||
|
#else
|
||||||
|
#define SOCKET int
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PCAP_VERSION_MAJOR 2
|
||||||
|
#define PCAP_VERSION_MINOR 4
|
||||||
|
|
||||||
|
#define PCAP_ERRBUF_SIZE 256
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compatibility for systems that have a bpf.h that
|
||||||
|
* predates the bpf typedefs for 64-bit support.
|
||||||
|
*/
|
||||||
|
#if BPF_RELEASE - 0 < 199406
|
||||||
|
typedef int bpf_int32;
|
||||||
|
typedef u_int bpf_u_int32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct pcap pcap_t;
|
||||||
|
typedef struct pcap_dumper pcap_dumper_t;
|
||||||
|
typedef struct pcap_if pcap_if_t;
|
||||||
|
typedef struct pcap_addr pcap_addr_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first record in the file contains saved values for some
|
||||||
|
* of the flags used in the printout phases of tcpdump.
|
||||||
|
* Many fields here are 32 bit ints so compilers won't insert unwanted
|
||||||
|
* padding; these files need to be interchangeable across architectures.
|
||||||
|
*
|
||||||
|
* Do not change the layout of this structure, in any way (this includes
|
||||||
|
* changes that only affect the length of fields in this structure).
|
||||||
|
*
|
||||||
|
* Also, do not change the interpretation of any of the members of this
|
||||||
|
* structure, in any way (this includes using values other than
|
||||||
|
* LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
|
||||||
|
* field).
|
||||||
|
*
|
||||||
|
* Instead:
|
||||||
|
*
|
||||||
|
* introduce a new structure for the new format, if the layout
|
||||||
|
* of the structure changed;
|
||||||
|
*
|
||||||
|
* send mail to "tcpdump-workers@lists.tcpdump.org", requesting
|
||||||
|
* a new magic number for your new capture file format, and, when
|
||||||
|
* you get the new magic number, put it in "savefile.c";
|
||||||
|
*
|
||||||
|
* use that magic number for save files with the changed file
|
||||||
|
* header;
|
||||||
|
*
|
||||||
|
* make the code in "savefile.c" capable of reading files with
|
||||||
|
* the old file header as well as files with the new file header
|
||||||
|
* (using the magic number to determine the header format).
|
||||||
|
*
|
||||||
|
* Then supply the changes as a patch at
|
||||||
|
*
|
||||||
|
* http://sourceforge.net/projects/libpcap/
|
||||||
|
*
|
||||||
|
* so that future versions of libpcap and programs that use it (such as
|
||||||
|
* tcpdump) will be able to read your new capture file format.
|
||||||
|
*/
|
||||||
|
struct pcap_file_header {
|
||||||
|
bpf_u_int32 magic;
|
||||||
|
u_short version_major;
|
||||||
|
u_short version_minor;
|
||||||
|
bpf_int32 thiszone; /* gmt to local correction */
|
||||||
|
bpf_u_int32 sigfigs; /* accuracy of timestamps */
|
||||||
|
bpf_u_int32 snaplen; /* max length saved portion of each pkt */
|
||||||
|
bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Macros for the value returned by pcap_datalink_ext().
|
||||||
|
*
|
||||||
|
* If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
|
||||||
|
* gives the FCS length of packets in the capture.
|
||||||
|
*/
|
||||||
|
#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
|
||||||
|
#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
|
||||||
|
#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PCAP_D_INOUT = 0,
|
||||||
|
PCAP_D_IN,
|
||||||
|
PCAP_D_OUT
|
||||||
|
} pcap_direction_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic per-packet information, as supplied by libpcap.
|
||||||
|
*
|
||||||
|
* The time stamp can and should be a "struct timeval", regardless of
|
||||||
|
* whether your system supports 32-bit tv_sec in "struct timeval",
|
||||||
|
* 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
|
||||||
|
* and 64-bit applications. The on-disk format of savefiles uses 32-bit
|
||||||
|
* tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
|
||||||
|
* and 64-bit versions of libpcap, even if they're on the same platform,
|
||||||
|
* should supply the appropriate version of "struct timeval", even if
|
||||||
|
* that's not what the underlying packet capture mechanism supplies.
|
||||||
|
*/
|
||||||
|
struct pcap_pkthdr {
|
||||||
|
struct timeval ts; /* time stamp */
|
||||||
|
bpf_u_int32 caplen; /* length of portion present */
|
||||||
|
bpf_u_int32 len; /* length this packet (off wire) */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As returned by the pcap_stats()
|
||||||
|
*/
|
||||||
|
struct pcap_stat {
|
||||||
|
u_int ps_recv; /* number of packets received */
|
||||||
|
u_int ps_drop; /* number of packets dropped */
|
||||||
|
u_int ps_ifdrop; /* drops by interface XXX not yet supported */
|
||||||
|
#ifdef HAVE_REMOTE
|
||||||
|
u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */
|
||||||
|
u_int ps_sent; /* number of packets sent by the server on the network */
|
||||||
|
u_int ps_netdrop; /* number of packets lost on the network */
|
||||||
|
#endif /* HAVE_REMOTE */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef MSDOS
|
||||||
|
/*
|
||||||
|
* As returned by the pcap_stats_ex()
|
||||||
|
*/
|
||||||
|
struct pcap_stat_ex {
|
||||||
|
u_long rx_packets; /* total packets received */
|
||||||
|
u_long tx_packets; /* total packets transmitted */
|
||||||
|
u_long rx_bytes; /* total bytes received */
|
||||||
|
u_long tx_bytes; /* total bytes transmitted */
|
||||||
|
u_long rx_errors; /* bad packets received */
|
||||||
|
u_long tx_errors; /* packet transmit problems */
|
||||||
|
u_long rx_dropped; /* no space in Rx buffers */
|
||||||
|
u_long tx_dropped; /* no space available for Tx */
|
||||||
|
u_long multicast; /* multicast packets received */
|
||||||
|
u_long collisions;
|
||||||
|
|
||||||
|
/* detailed rx_errors: */
|
||||||
|
u_long rx_length_errors;
|
||||||
|
u_long rx_over_errors; /* receiver ring buff overflow */
|
||||||
|
u_long rx_crc_errors; /* recv'd pkt with crc error */
|
||||||
|
u_long rx_frame_errors; /* recv'd frame alignment error */
|
||||||
|
u_long rx_fifo_errors; /* recv'r fifo overrun */
|
||||||
|
u_long rx_missed_errors; /* recv'r missed packet */
|
||||||
|
|
||||||
|
/* detailed tx_errors */
|
||||||
|
u_long tx_aborted_errors;
|
||||||
|
u_long tx_carrier_errors;
|
||||||
|
u_long tx_fifo_errors;
|
||||||
|
u_long tx_heartbeat_errors;
|
||||||
|
u_long tx_window_errors;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Item in a list of interfaces.
|
||||||
|
*/
|
||||||
|
struct pcap_if {
|
||||||
|
struct pcap_if *next;
|
||||||
|
char *name; /* name to hand to "pcap_open_live()" */
|
||||||
|
char *description; /* textual description of interface, or NULL */
|
||||||
|
struct pcap_addr *addresses;
|
||||||
|
bpf_u_int32 flags; /* PCAP_IF_ interface flags */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Representation of an interface address.
|
||||||
|
*/
|
||||||
|
struct pcap_addr {
|
||||||
|
struct pcap_addr *next;
|
||||||
|
struct sockaddr *addr; /* address */
|
||||||
|
struct sockaddr *netmask; /* netmask for that address */
|
||||||
|
struct sockaddr *broadaddr; /* broadcast address for that address */
|
||||||
|
struct sockaddr *dstaddr; /* P2P destination address for that address */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
|
||||||
|
const u_char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error codes for the pcap API.
|
||||||
|
* These will all be negative, so you can check for the success or
|
||||||
|
* failure of a call that returns these codes by checking for a
|
||||||
|
* negative value.
|
||||||
|
*/
|
||||||
|
#define PCAP_ERROR -1 /* generic error code */
|
||||||
|
#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
|
||||||
|
#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
|
||||||
|
#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
|
||||||
|
#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
|
||||||
|
#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
|
||||||
|
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
|
||||||
|
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
|
||||||
|
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Warning codes for the pcap API.
|
||||||
|
* These will all be positive and non-zero, so they won't look like
|
||||||
|
* errors.
|
||||||
|
*/
|
||||||
|
#define PCAP_WARNING 1 /* generic warning code */
|
||||||
|
#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
|
||||||
|
|
||||||
|
char *pcap_lookupdev(char *);
|
||||||
|
int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
|
||||||
|
|
||||||
|
pcap_t *pcap_create(const char *, char *);
|
||||||
|
int pcap_set_snaplen(pcap_t *, int);
|
||||||
|
int pcap_set_promisc(pcap_t *, int);
|
||||||
|
int pcap_can_set_rfmon(pcap_t *);
|
||||||
|
int pcap_set_rfmon(pcap_t *, int);
|
||||||
|
int pcap_set_timeout(pcap_t *, int);
|
||||||
|
int pcap_set_buffer_size(pcap_t *, int);
|
||||||
|
int pcap_activate(pcap_t *);
|
||||||
|
|
||||||
|
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||||
|
pcap_t *pcap_open_dead(int, int);
|
||||||
|
pcap_t *pcap_open_offline(const char *, char *);
|
||||||
|
#if defined(WIN32)
|
||||||
|
pcap_t *pcap_hopen_offline(intptr_t, char *);
|
||||||
|
#if !defined(LIBPCAP_EXPORTS)
|
||||||
|
#define pcap_fopen_offline(f,b) \
|
||||||
|
pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
|
||||||
|
#else /*LIBPCAP_EXPORTS*/
|
||||||
|
static pcap_t *pcap_fopen_offline(FILE *, char *);
|
||||||
|
#endif
|
||||||
|
#else /*WIN32*/
|
||||||
|
pcap_t *pcap_fopen_offline(FILE *, char *);
|
||||||
|
#endif /*WIN32*/
|
||||||
|
|
||||||
|
void pcap_close(pcap_t *);
|
||||||
|
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
|
||||||
|
int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
|
||||||
|
const u_char*
|
||||||
|
pcap_next(pcap_t *, struct pcap_pkthdr *);
|
||||||
|
int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
|
||||||
|
void pcap_breakloop(pcap_t *);
|
||||||
|
int pcap_stats(pcap_t *, struct pcap_stat *);
|
||||||
|
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||||
|
int pcap_setdirection(pcap_t *, pcap_direction_t);
|
||||||
|
int pcap_getnonblock(pcap_t *, char *);
|
||||||
|
int pcap_setnonblock(pcap_t *, int, char *);
|
||||||
|
int pcap_inject(pcap_t *, const void *, size_t);
|
||||||
|
int pcap_sendpacket(pcap_t *, const u_char *, int);
|
||||||
|
const char *pcap_statustostr(int);
|
||||||
|
const char *pcap_strerror(int);
|
||||||
|
char *pcap_geterr(pcap_t *);
|
||||||
|
void pcap_perror(pcap_t *, char *);
|
||||||
|
int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
|
||||||
|
bpf_u_int32);
|
||||||
|
int pcap_compile_nopcap(int, int, struct bpf_program *,
|
||||||
|
const char *, int, bpf_u_int32);
|
||||||
|
void pcap_freecode(struct bpf_program *);
|
||||||
|
int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
|
||||||
|
const u_char *);
|
||||||
|
int pcap_datalink(pcap_t *);
|
||||||
|
int pcap_datalink_ext(pcap_t *);
|
||||||
|
int pcap_list_datalinks(pcap_t *, int **);
|
||||||
|
int pcap_set_datalink(pcap_t *, int);
|
||||||
|
void pcap_free_datalinks(int *);
|
||||||
|
int pcap_datalink_name_to_val(const char *);
|
||||||
|
const char *pcap_datalink_val_to_name(int);
|
||||||
|
const char *pcap_datalink_val_to_description(int);
|
||||||
|
int pcap_snapshot(pcap_t *);
|
||||||
|
int pcap_is_swapped(pcap_t *);
|
||||||
|
int pcap_major_version(pcap_t *);
|
||||||
|
int pcap_minor_version(pcap_t *);
|
||||||
|
|
||||||
|
/* XXX */
|
||||||
|
FILE *pcap_file(pcap_t *);
|
||||||
|
int pcap_fileno(pcap_t *);
|
||||||
|
|
||||||
|
pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
|
||||||
|
pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
|
||||||
|
FILE *pcap_dump_file(pcap_dumper_t *);
|
||||||
|
long pcap_dump_ftell(pcap_dumper_t *);
|
||||||
|
int pcap_dump_flush(pcap_dumper_t *);
|
||||||
|
void pcap_dump_close(pcap_dumper_t *);
|
||||||
|
void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||||
|
|
||||||
|
int pcap_findalldevs(pcap_if_t **, char *);
|
||||||
|
void pcap_freealldevs(pcap_if_t *);
|
||||||
|
|
||||||
|
const char *pcap_lib_version(void);
|
||||||
|
|
||||||
|
/* XXX this guy lives in the bpf tree */
|
||||||
|
u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
|
||||||
|
int bpf_validate(const struct bpf_insn *f, int len);
|
||||||
|
char *bpf_image(const struct bpf_insn *, int);
|
||||||
|
void bpf_dump(const struct bpf_program *, int);
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32 definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pcap_setbuff(pcap_t *p, int dim);
|
||||||
|
int pcap_setmode(pcap_t *p, int mode);
|
||||||
|
int pcap_setmintocopy(pcap_t *p, int size);
|
||||||
|
|
||||||
|
#ifdef WPCAP
|
||||||
|
/* Include file with the wpcap-specific extensions */
|
||||||
|
#include <Win32-Extensions.h>
|
||||||
|
#endif /* WPCAP */
|
||||||
|
|
||||||
|
#define MODE_CAPT 0
|
||||||
|
#define MODE_STAT 1
|
||||||
|
#define MODE_MON 2
|
||||||
|
|
||||||
|
#elif defined(MSDOS)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MS-DOS definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
|
||||||
|
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
|
||||||
|
u_long pcap_mac_packets (void);
|
||||||
|
|
||||||
|
#else /* UN*X */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UN*X definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
int pcap_get_selectable_fd(pcap_t *);
|
||||||
|
|
||||||
|
#endif /* WIN32/MSDOS/UN*X */
|
||||||
|
|
||||||
|
#ifdef HAVE_REMOTE
|
||||||
|
/* Includes most of the public stuff that is needed for the remote capture */
|
||||||
|
#include <remote-ext.h>
|
||||||
|
#endif /* HAVE_REMOTE */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from the Stanford/CMU enet packet filter,
|
||||||
|
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
||||||
|
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||||
|
* Berkeley Laboratory.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.2.2.1 2008-05-30 01:36:06 guy Exp $ (LBL)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For captures on Linux cooked sockets, we construct a fake header
|
||||||
|
* that includes:
|
||||||
|
*
|
||||||
|
* a 2-byte "packet type" which is one of:
|
||||||
|
*
|
||||||
|
* LINUX_SLL_HOST packet was sent to us
|
||||||
|
* LINUX_SLL_BROADCAST packet was broadcast
|
||||||
|
* LINUX_SLL_MULTICAST packet was multicast
|
||||||
|
* LINUX_SLL_OTHERHOST packet was sent to somebody else
|
||||||
|
* LINUX_SLL_OUTGOING packet was sent *by* us;
|
||||||
|
*
|
||||||
|
* a 2-byte Ethernet protocol field;
|
||||||
|
*
|
||||||
|
* a 2-byte link-layer type;
|
||||||
|
*
|
||||||
|
* a 2-byte link-layer address length;
|
||||||
|
*
|
||||||
|
* an 8-byte source link-layer address, whose actual length is
|
||||||
|
* specified by the previous value.
|
||||||
|
*
|
||||||
|
* All fields except for the link-layer address are in network byte order.
|
||||||
|
*
|
||||||
|
* DO NOT change the layout of this structure, or change any of the
|
||||||
|
* LINUX_SLL_ values below. If you must change the link-layer header
|
||||||
|
* for a "cooked" Linux capture, introduce a new DLT_ type (ask
|
||||||
|
* "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
|
||||||
|
* a value that collides with a value already being used), and use the
|
||||||
|
* new header in captures of that type, so that programs that can
|
||||||
|
* handle DLT_LINUX_SLL captures will continue to handle them correctly
|
||||||
|
* without any change, and so that capture files with different headers
|
||||||
|
* can be told apart and programs that read them can dissect the
|
||||||
|
* packets in them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lib_pcap_sll_h
|
||||||
|
#define lib_pcap_sll_h
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A DLT_LINUX_SLL fake link-layer header.
|
||||||
|
*/
|
||||||
|
#define SLL_HDR_LEN 16 /* total header length */
|
||||||
|
#define SLL_ADDRLEN 8 /* length of address field */
|
||||||
|
|
||||||
|
struct sll_header {
|
||||||
|
u_int16_t sll_pkttype; /* packet type */
|
||||||
|
u_int16_t sll_hatype; /* link-layer address type */
|
||||||
|
u_int16_t sll_halen; /* link-layer address length */
|
||||||
|
u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
|
||||||
|
u_int16_t sll_protocol; /* protocol */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
|
||||||
|
* PACKET_ values on Linux, but are defined here so that they're
|
||||||
|
* available even on systems other than Linux, and so that they
|
||||||
|
* don't change even if the PACKET_ values change.
|
||||||
|
*/
|
||||||
|
#define LINUX_SLL_HOST 0
|
||||||
|
#define LINUX_SLL_BROADCAST 1
|
||||||
|
#define LINUX_SLL_MULTICAST 2
|
||||||
|
#define LINUX_SLL_OTHERHOST 3
|
||||||
|
#define LINUX_SLL_OUTGOING 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The LINUX_SLL_ values for "sll_protocol"; these correspond to the
|
||||||
|
* ETH_P_ values on Linux, but are defined here so that they're
|
||||||
|
* available even on systems other than Linux. We assume, for now,
|
||||||
|
* that the ETH_P_ values won't change in Linux; if they do, then:
|
||||||
|
*
|
||||||
|
* if we don't translate them in "pcap-linux.c", capture files
|
||||||
|
* won't necessarily be readable if captured on a system that
|
||||||
|
* defines ETH_P_ values that don't match these values;
|
||||||
|
*
|
||||||
|
* if we do translate them in "pcap-linux.c", that makes life
|
||||||
|
* unpleasant for the BPF code generator, as the values you test
|
||||||
|
* for in the kernel aren't the values that you test for when
|
||||||
|
* reading a capture file, so the fixup code run on BPF programs
|
||||||
|
* handed to the kernel ends up having to do more work.
|
||||||
|
*
|
||||||
|
* Add other values here as necessary, for handling packet types that
|
||||||
|
* might show up on non-Ethernet, non-802.x networks. (Not all the ones
|
||||||
|
* in the Linux "if_ether.h" will, I suspect, actually show up in
|
||||||
|
* captures.)
|
||||||
|
*/
|
||||||
|
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
|
||||||
|
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006 Paolo Abeni (Italy)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior written
|
||||||
|
* permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* Basic USB data struct
|
||||||
|
* By Paolo Abeni <paolo.abeni@email.it>
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PCAP_USB_STRUCTS_H__
|
||||||
|
#define _PCAP_USB_STRUCTS_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
* possible transfer mode
|
||||||
|
*/
|
||||||
|
#define URB_TRANSFER_IN 0x80
|
||||||
|
#define URB_ISOCHRONOUS 0x0
|
||||||
|
#define URB_INTERRUPT 0x1
|
||||||
|
#define URB_CONTROL 0x2
|
||||||
|
#define URB_BULK 0x3
|
||||||
|
|
||||||
|
/*
|
||||||
|
* possible event type
|
||||||
|
*/
|
||||||
|
#define URB_SUBMIT 'S'
|
||||||
|
#define URB_COMPLETE 'C'
|
||||||
|
#define URB_ERROR 'E'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB setup header as defined in USB specification.
|
||||||
|
* Appears at the front of each packet in DLT_USB captures.
|
||||||
|
*/
|
||||||
|
typedef struct _usb_setup {
|
||||||
|
u_int8_t bmRequestType;
|
||||||
|
u_int8_t bRequest;
|
||||||
|
u_int16_t wValue;
|
||||||
|
u_int16_t wIndex;
|
||||||
|
u_int16_t wLength;
|
||||||
|
} pcap_usb_setup;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header prepended by linux kernel to each event.
|
||||||
|
* Appears at the front of each packet in DLT_USB_LINUX captures.
|
||||||
|
*/
|
||||||
|
typedef struct _usb_header {
|
||||||
|
u_int64_t id;
|
||||||
|
u_int8_t event_type;
|
||||||
|
u_int8_t transfer_type;
|
||||||
|
u_int8_t endpoint_number;
|
||||||
|
u_int8_t device_address;
|
||||||
|
u_int16_t bus_id;
|
||||||
|
char setup_flag;/*if !=0 the urb setup header is not present*/
|
||||||
|
char data_flag; /*if !=0 no urb data is present*/
|
||||||
|
int64_t ts_sec;
|
||||||
|
int32_t ts_usec;
|
||||||
|
int32_t status;
|
||||||
|
u_int32_t urb_len;
|
||||||
|
u_int32_t data_len; /* amount of urb data really present in this event*/
|
||||||
|
pcap_usb_setup setup;
|
||||||
|
} pcap_usb_header;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
|
* must display the following acknowledgement:
|
||||||
|
* This product includes software developed by the University of
|
||||||
|
* California, Berkeley and its contributors.
|
||||||
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#) $Header: /tcpdump/master/libpcap/pcap/vlan.h,v 1.1.2.2 2008-08-06 07:45:59 guy Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lib_pcap_vlan_h
|
||||||
|
#define lib_pcap_vlan_h
|
||||||
|
|
||||||
|
struct vlan_tag {
|
||||||
|
u_int16_t vlan_tpid; /* ETH_P_8021Q */
|
||||||
|
u_int16_t vlan_tci; /* VLAN TCI */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define VLAN_TAG_LEN 4
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,444 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2002 - 2003
|
||||||
|
* NetGroup, Politecnico di Torino (Italy)
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Politecnico di Torino nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __REMOTE_EXT_H__
|
||||||
|
#define __REMOTE_EXT_H__
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef HAVE_REMOTE
|
||||||
|
#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Definition for Microsoft Visual Studio
|
||||||
|
#if _MSC_VER > 1000
|
||||||
|
#pragma once
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\file remote-ext.h
|
||||||
|
|
||||||
|
The goal of this file it to include most of the new definitions that should be
|
||||||
|
placed into the pcap.h file.
|
||||||
|
|
||||||
|
It includes all new definitions (structures and functions like pcap_open().
|
||||||
|
Some of the functions are not really a remote feature, but, right now,
|
||||||
|
they are placed here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// All this stuff is public
|
||||||
|
/*! \addtogroup remote_struct
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Defines the maximum buffer size in which address, port, interface names are kept.
|
||||||
|
|
||||||
|
In case the adapter name or such is larger than this value, it is truncated.
|
||||||
|
This is not used by the user; however it must be aware that an hostname / interface
|
||||||
|
name longer than this value will be truncated.
|
||||||
|
*/
|
||||||
|
#define PCAP_BUF_SIZE 1024
|
||||||
|
|
||||||
|
|
||||||
|
/*! \addtogroup remote_source_ID
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Internal representation of the type of source in use (file,
|
||||||
|
remote/local interface).
|
||||||
|
|
||||||
|
This indicates a file, i.e. the user want to open a capture from a local file.
|
||||||
|
*/
|
||||||
|
#define PCAP_SRC_FILE 2
|
||||||
|
/*!
|
||||||
|
\brief Internal representation of the type of source in use (file,
|
||||||
|
remote/local interface).
|
||||||
|
|
||||||
|
This indicates a local interface, i.e. the user want to open a capture from
|
||||||
|
a local interface. This does not involve the RPCAP protocol.
|
||||||
|
*/
|
||||||
|
#define PCAP_SRC_IFLOCAL 3
|
||||||
|
/*!
|
||||||
|
\brief Internal representation of the type of source in use (file,
|
||||||
|
remote/local interface).
|
||||||
|
|
||||||
|
This indicates a remote interface, i.e. the user want to open a capture from
|
||||||
|
an interface on a remote host. This does involve the RPCAP protocol.
|
||||||
|
*/
|
||||||
|
#define PCAP_SRC_IFREMOTE 4
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*! \addtogroup remote_source_string
|
||||||
|
|
||||||
|
The formats allowed by the pcap_open() are the following:
|
||||||
|
- file://path_and_filename [opens a local file]
|
||||||
|
- rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
|
||||||
|
- rpcap://host/devicename [opens the selected device available on a remote host]
|
||||||
|
- rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
|
||||||
|
- adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
|
||||||
|
- (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
|
||||||
|
|
||||||
|
The formats allowed by the pcap_findalldevs_ex() are the following:
|
||||||
|
- file://folder/ [lists all the files in the given folder]
|
||||||
|
- rpcap:// [lists all local adapters]
|
||||||
|
- rpcap://host:port/ [lists the devices available on a remote host]
|
||||||
|
|
||||||
|
Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since
|
||||||
|
IPv6 is fully supported, these are the allowed formats:
|
||||||
|
|
||||||
|
- host (literal): e.g. host.foo.bar
|
||||||
|
- host (numeric IPv4): e.g. 10.11.12.13
|
||||||
|
- host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
|
||||||
|
- host (numeric IPv6): e.g. [1:2:3::4]
|
||||||
|
- port: can be either numeric (e.g. '80') or literal (e.g. 'http')
|
||||||
|
|
||||||
|
Here you find some allowed examples:
|
||||||
|
- rpcap://host.foo.bar/devicename [everything literal, no port number]
|
||||||
|
- rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
|
||||||
|
- rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
|
||||||
|
- rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
|
||||||
|
- rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
|
||||||
|
- rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
|
||||||
|
- rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
|
||||||
|
- rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
|
||||||
|
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief String that will be used to determine the type of source in use (file,
|
||||||
|
remote/local interface).
|
||||||
|
|
||||||
|
This string will be prepended to the interface name in order to create a string
|
||||||
|
that contains all the information required to open the source.
|
||||||
|
|
||||||
|
This string indicates that the user wants to open a capture from a local file.
|
||||||
|
*/
|
||||||
|
#define PCAP_SRC_FILE_STRING "file://"
|
||||||
|
/*!
|
||||||
|
\brief String that will be used to determine the type of source in use (file,
|
||||||
|
remote/local interface).
|
||||||
|
|
||||||
|
This string will be prepended to the interface name in order to create a string
|
||||||
|
that contains all the information required to open the source.
|
||||||
|
|
||||||
|
This string indicates that the user wants to open a capture from a network interface.
|
||||||
|
This string does not necessarily involve the use of the RPCAP protocol. If the
|
||||||
|
interface required resides on the local host, the RPCAP protocol is not involved
|
||||||
|
and the local functions are used.
|
||||||
|
*/
|
||||||
|
#define PCAP_SRC_IF_STRING "rpcap://"
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\addtogroup remote_open_flags
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Defines if the adapter has to go in promiscuous mode.
|
||||||
|
|
||||||
|
It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
|
||||||
|
Note that even if this parameter is false, the interface could well be in promiscuous
|
||||||
|
mode for some other reason (for example because another capture process with
|
||||||
|
promiscuous mode enabled is currently using that interface).
|
||||||
|
On on Linux systems with 2.2 or later kernels (that have the "any" device), this
|
||||||
|
flag does not work on the "any" device; if an argument of "any" is supplied,
|
||||||
|
the 'promisc' flag is ignored.
|
||||||
|
*/
|
||||||
|
#define PCAP_OPENFLAG_PROMISCUOUS 1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Defines if the data trasfer (in case of a remote
|
||||||
|
capture) has to be done with UDP protocol.
|
||||||
|
|
||||||
|
If it is '1' if you want a UDP data connection, '0' if you want
|
||||||
|
a TCP data connection; control connection is always TCP-based.
|
||||||
|
A UDP connection is much lighter, but it does not guarantee that all
|
||||||
|
the captured packets arrive to the client workstation. Moreover,
|
||||||
|
it could be harmful in case of network congestion.
|
||||||
|
This flag is meaningless if the source is not a remote interface.
|
||||||
|
In that case, it is simply ignored.
|
||||||
|
*/
|
||||||
|
#define PCAP_OPENFLAG_DATATX_UDP 2
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Defines if the remote probe will capture its own generated traffic.
|
||||||
|
|
||||||
|
In case the remote probe uses the same interface to capture traffic and to send
|
||||||
|
data back to the caller, the captured traffic includes the RPCAP traffic as well.
|
||||||
|
If this flag is turned on, the RPCAP traffic is excluded from the capture, so that
|
||||||
|
the trace returned back to the collector is does not include this traffic.
|
||||||
|
*/
|
||||||
|
#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Defines if the local adapter will capture its own generated traffic.
|
||||||
|
|
||||||
|
This flag tells the underlying capture driver to drop the packets that were sent by itself.
|
||||||
|
This is usefult when building applications like bridges, that should ignore the traffic
|
||||||
|
they just sent.
|
||||||
|
*/
|
||||||
|
#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This flag configures the adapter for maximum responsiveness.
|
||||||
|
|
||||||
|
In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before
|
||||||
|
copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage,
|
||||||
|
i.e. better performance, which is good for applications like sniffers. If the user sets the
|
||||||
|
PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application
|
||||||
|
is ready to receive them. This is suggested for real time applications (like, for example, a bridge)
|
||||||
|
that need the best responsiveness.*/
|
||||||
|
#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\addtogroup remote_samp_methods
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief No sampling has to be done on the current capture.
|
||||||
|
|
||||||
|
In this case, no sampling algorithms are applied to the current capture.
|
||||||
|
*/
|
||||||
|
#define PCAP_SAMP_NOSAMP 0
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief It defines that only 1 out of N packets must be returned to the user.
|
||||||
|
|
||||||
|
In this case, the 'value' field of the 'pcap_samp' structure indicates the
|
||||||
|
number of packets (minus 1) that must be discarded before one packet got accepted.
|
||||||
|
In other words, if 'value = 10', the first packet is returned to the caller, while
|
||||||
|
the following 9 are discarded.
|
||||||
|
*/
|
||||||
|
#define PCAP_SAMP_1_EVERY_N 1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief It defines that we have to return 1 packet every N milliseconds.
|
||||||
|
|
||||||
|
In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting
|
||||||
|
time' in milliseconds before one packet got accepted.
|
||||||
|
In other words, if 'value = 10', the first packet is returned to the caller; the next
|
||||||
|
returned one will be the first packet that arrives when 10ms have elapsed.
|
||||||
|
*/
|
||||||
|
#define PCAP_SAMP_FIRST_AFTER_N_MS 2
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\addtogroup remote_auth_methods
|
||||||
|
\{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief It defines the NULL authentication.
|
||||||
|
|
||||||
|
This value has to be used within the 'type' member of the pcap_rmtauth structure.
|
||||||
|
The 'NULL' authentication has to be equal to 'zero', so that old applications
|
||||||
|
can just put every field of struct pcap_rmtauth to zero, and it does work.
|
||||||
|
*/
|
||||||
|
#define RPCAP_RMTAUTH_NULL 0
|
||||||
|
/*!
|
||||||
|
\brief It defines the username/password authentication.
|
||||||
|
|
||||||
|
With this type of authentication, the RPCAP protocol will use the username/
|
||||||
|
password provided to authenticate the user on the remote machine. If the
|
||||||
|
authentication is successful (and the user has the right to open network devices)
|
||||||
|
the RPCAP connection will continue; otherwise it will be dropped.
|
||||||
|
|
||||||
|
This value has to be used within the 'type' member of the pcap_rmtauth structure.
|
||||||
|
*/
|
||||||
|
#define RPCAP_RMTAUTH_PWD 1
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
|
||||||
|
\brief This structure keeps the information needed to autheticate
|
||||||
|
the user on a remote machine.
|
||||||
|
|
||||||
|
The remote machine can either grant or refuse the access according
|
||||||
|
to the information provided.
|
||||||
|
In case the NULL authentication is required, both 'username' and
|
||||||
|
'password' can be NULL pointers.
|
||||||
|
|
||||||
|
This structure is meaningless if the source is not a remote interface;
|
||||||
|
in that case, the functions which requires such a structure can accept
|
||||||
|
a NULL pointer as well.
|
||||||
|
*/
|
||||||
|
struct pcap_rmtauth
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
\brief Type of the authentication required.
|
||||||
|
|
||||||
|
In order to provide maximum flexibility, we can support different types
|
||||||
|
of authentication based on the value of this 'type' variable. The currently
|
||||||
|
supported authentication methods are defined into the
|
||||||
|
\link remote_auth_methods Remote Authentication Methods Section\endlink.
|
||||||
|
|
||||||
|
*/
|
||||||
|
int type;
|
||||||
|
/*!
|
||||||
|
\brief Zero-terminated string containing the username that has to be
|
||||||
|
used on the remote machine for authentication.
|
||||||
|
|
||||||
|
This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
|
||||||
|
and it can be NULL.
|
||||||
|
*/
|
||||||
|
char *username;
|
||||||
|
/*!
|
||||||
|
\brief Zero-terminated string containing the password that has to be
|
||||||
|
used on the remote machine for authentication.
|
||||||
|
|
||||||
|
This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
|
||||||
|
and it can be NULL.
|
||||||
|
*/
|
||||||
|
char *password;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief This structure defines the information related to sampling.
|
||||||
|
|
||||||
|
In case the sampling is requested, the capturing device should read
|
||||||
|
only a subset of the packets coming from the source. The returned packets depend
|
||||||
|
on the sampling parameters.
|
||||||
|
|
||||||
|
\warning The sampling process is applied <strong>after</strong> the filtering process.
|
||||||
|
In other words, packets are filtered first, then the sampling process selects a
|
||||||
|
subset of the 'filtered' packets and it returns them to the caller.
|
||||||
|
*/
|
||||||
|
struct pcap_samp
|
||||||
|
{
|
||||||
|
/*!
|
||||||
|
Method used for sampling. Currently, the supported methods are listed in the
|
||||||
|
\link remote_samp_methods Sampling Methods Section\endlink.
|
||||||
|
*/
|
||||||
|
int method;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
This value depends on the sampling method defined. For its meaning, please check
|
||||||
|
at the \link remote_samp_methods Sampling Methods Section\endlink.
|
||||||
|
*/
|
||||||
|
int value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//! Maximum lenght of an host name (needed for the RPCAP active mode)
|
||||||
|
#define RPCAP_HOSTLIST_SIZE 1024
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\}
|
||||||
|
*/ // end of public documentation
|
||||||
|
|
||||||
|
|
||||||
|
// Exported functions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \name New WinPcap functions
|
||||||
|
|
||||||
|
This section lists the new functions that are able to help considerably in writing
|
||||||
|
WinPcap programs because of their easiness of use.
|
||||||
|
*/
|
||||||
|
//\{
|
||||||
|
pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
|
||||||
|
int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf);
|
||||||
|
int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf);
|
||||||
|
int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
|
||||||
|
struct pcap_samp *pcap_setsampling(pcap_t *p);
|
||||||
|
|
||||||
|
//\}
|
||||||
|
// End of new winpcap functions
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** \name Remote Capture functions
|
||||||
|
*/
|
||||||
|
//\{
|
||||||
|
SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf);
|
||||||
|
int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf);
|
||||||
|
int pcap_remoteact_close(const char *host, char *errbuf);
|
||||||
|
void pcap_remoteact_cleanup();
|
||||||
|
//\}
|
||||||
|
// End of remote capture functions
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
Winpcap is version 4.1.2 downloaded from
|
||||||
|
https://www.winpcap.org/install/bin/WpdPack_4_1_2.zip
|
||||||
|
Just the /include and /lib directories are included to keep the size small.
|
|
@ -221,7 +221,7 @@
|
||||||
<ClInclude Include="..\..\include\wx\wizard.h" />
|
<ClInclude Include="..\..\include\wx\wizard.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="wx_config.vcxproj">
|
<ProjectReference Include="wx_config_vs11.vcxproj">
|
||||||
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -379,7 +379,7 @@
|
||||||
<ClInclude Include="..\..\include\wx\zstream.h" />
|
<ClInclude Include="..\..\include\wx\zstream.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="wx_config.vcxproj">
|
<ProjectReference Include="wx_config_vs11.vcxproj">
|
||||||
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -1527,11 +1527,11 @@
|
||||||
</ResourceCompile>
|
</ResourceCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\libjpeg\libjpeg.vcxproj">
|
<ProjectReference Include="..\..\..\libjpeg\libjpeg_vs11.vcxproj">
|
||||||
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
|
<Project>{bc236261-77e8-4567-8d09-45cd02965eb6}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="wx_config.vcxproj">
|
<ProjectReference Include="wx_config_vs11.vcxproj">
|
||||||
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
<Project>{c34487af-228a-4d11-8e50-27803df76873}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,366 +1,368 @@
|
||||||
|
|
||||||
Frequently Asked Questions about zlib
|
Frequently Asked Questions about zlib
|
||||||
|
|
||||||
|
|
||||||
If your question is not there, please check the zlib home page
|
If your question is not there, please check the zlib home page
|
||||||
http://zlib.net/ which may have more recent information.
|
http://zlib.net/ which may have more recent information.
|
||||||
The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
|
The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
|
||||||
|
|
||||||
|
|
||||||
1. Is zlib Y2K-compliant?
|
1. Is zlib Y2K-compliant?
|
||||||
|
|
||||||
Yes. zlib doesn't handle dates.
|
Yes. zlib doesn't handle dates.
|
||||||
|
|
||||||
2. Where can I get a Windows DLL version?
|
2. Where can I get a Windows DLL version?
|
||||||
|
|
||||||
The zlib sources can be compiled without change to produce a DLL. See the
|
The zlib sources can be compiled without change to produce a DLL. See the
|
||||||
file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
|
file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the
|
||||||
precompiled DLL are found in the zlib web site at http://zlib.net/ .
|
precompiled DLL are found in the zlib web site at http://zlib.net/ .
|
||||||
|
|
||||||
3. Where can I get a Visual Basic interface to zlib?
|
3. Where can I get a Visual Basic interface to zlib?
|
||||||
|
|
||||||
See
|
See
|
||||||
* http://marknelson.us/1997/01/01/zlib-engine/
|
* http://marknelson.us/1997/01/01/zlib-engine/
|
||||||
* win32/DLL_FAQ.txt in the zlib distribution
|
* win32/DLL_FAQ.txt in the zlib distribution
|
||||||
|
|
||||||
4. compress() returns Z_BUF_ERROR.
|
4. compress() returns Z_BUF_ERROR.
|
||||||
|
|
||||||
Make sure that before the call of compress(), the length of the compressed
|
Make sure that before the call of compress(), the length of the compressed
|
||||||
buffer is equal to the available size of the compressed buffer and not
|
buffer is equal to the available size of the compressed buffer and not
|
||||||
zero. For Visual Basic, check that this parameter is passed by reference
|
zero. For Visual Basic, check that this parameter is passed by reference
|
||||||
("as any"), not by value ("as long").
|
("as any"), not by value ("as long").
|
||||||
|
|
||||||
5. deflate() or inflate() returns Z_BUF_ERROR.
|
5. deflate() or inflate() returns Z_BUF_ERROR.
|
||||||
|
|
||||||
Before making the call, make sure that avail_in and avail_out are not zero.
|
Before making the call, make sure that avail_in and avail_out are not zero.
|
||||||
When setting the parameter flush equal to Z_FINISH, also make sure that
|
When setting the parameter flush equal to Z_FINISH, also make sure that
|
||||||
avail_out is big enough to allow processing all pending input. Note that a
|
avail_out is big enough to allow processing all pending input. Note that a
|
||||||
Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
|
Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
|
||||||
made with more input or output space. A Z_BUF_ERROR may in fact be
|
made with more input or output space. A Z_BUF_ERROR may in fact be
|
||||||
unavoidable depending on how the functions are used, since it is not
|
unavoidable depending on how the functions are used, since it is not
|
||||||
possible to tell whether or not there is more output pending when
|
possible to tell whether or not there is more output pending when
|
||||||
strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
|
strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a
|
||||||
heavily annotated example.
|
heavily annotated example.
|
||||||
|
|
||||||
6. Where's the zlib documentation (man pages, etc.)?
|
6. Where's the zlib documentation (man pages, etc.)?
|
||||||
|
|
||||||
It's in zlib.h . Examples of zlib usage are in the files example.c and
|
It's in zlib.h . Examples of zlib usage are in the files test/example.c
|
||||||
minigzip.c, with more in examples/ .
|
and test/minigzip.c, with more in examples/ .
|
||||||
|
|
||||||
7. Why don't you use GNU autoconf or libtool or ...?
|
7. Why don't you use GNU autoconf or libtool or ...?
|
||||||
|
|
||||||
Because we would like to keep zlib as a very small and simple package.
|
Because we would like to keep zlib as a very small and simple package.
|
||||||
zlib is rather portable and doesn't need much configuration.
|
zlib is rather portable and doesn't need much configuration.
|
||||||
|
|
||||||
8. I found a bug in zlib.
|
8. I found a bug in zlib.
|
||||||
|
|
||||||
Most of the time, such problems are due to an incorrect usage of zlib.
|
Most of the time, such problems are due to an incorrect usage of zlib.
|
||||||
Please try to reproduce the problem with a small program and send the
|
Please try to reproduce the problem with a small program and send the
|
||||||
corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
|
corresponding source to us at zlib@gzip.org . Do not send multi-megabyte
|
||||||
data files without prior agreement.
|
data files without prior agreement.
|
||||||
|
|
||||||
9. Why do I get "undefined reference to gzputc"?
|
9. Why do I get "undefined reference to gzputc"?
|
||||||
|
|
||||||
If "make test" produces something like
|
If "make test" produces something like
|
||||||
|
|
||||||
example.o(.text+0x154): undefined reference to `gzputc'
|
example.o(.text+0x154): undefined reference to `gzputc'
|
||||||
|
|
||||||
check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
|
check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
|
||||||
/usr/X11R6/lib. Remove any old versions, then do "make install".
|
/usr/X11R6/lib. Remove any old versions, then do "make install".
|
||||||
|
|
||||||
10. I need a Delphi interface to zlib.
|
10. I need a Delphi interface to zlib.
|
||||||
|
|
||||||
See the contrib/delphi directory in the zlib distribution.
|
See the contrib/delphi directory in the zlib distribution.
|
||||||
|
|
||||||
11. Can zlib handle .zip archives?
|
11. Can zlib handle .zip archives?
|
||||||
|
|
||||||
Not by itself, no. See the directory contrib/minizip in the zlib
|
Not by itself, no. See the directory contrib/minizip in the zlib
|
||||||
distribution.
|
distribution.
|
||||||
|
|
||||||
12. Can zlib handle .Z files?
|
12. Can zlib handle .Z files?
|
||||||
|
|
||||||
No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
|
No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
|
||||||
the code of uncompress on your own.
|
the code of uncompress on your own.
|
||||||
|
|
||||||
13. How can I make a Unix shared library?
|
13. How can I make a Unix shared library?
|
||||||
|
|
||||||
make clean
|
By default a shared (and a static) library is built for Unix. So:
|
||||||
./configure -s
|
|
||||||
make
|
make distclean
|
||||||
|
./configure
|
||||||
14. How do I install a shared zlib library on Unix?
|
make
|
||||||
|
|
||||||
After the above, then:
|
14. How do I install a shared zlib library on Unix?
|
||||||
|
|
||||||
make install
|
After the above, then:
|
||||||
|
|
||||||
However, many flavors of Unix come with a shared zlib already installed.
|
make install
|
||||||
Before going to the trouble of compiling a shared version of zlib and
|
|
||||||
trying to install it, you may want to check if it's already there! If you
|
However, many flavors of Unix come with a shared zlib already installed.
|
||||||
can #include <zlib.h>, it's there. The -lz option will probably link to
|
Before going to the trouble of compiling a shared version of zlib and
|
||||||
it. You can check the version at the top of zlib.h or with the
|
trying to install it, you may want to check if it's already there! If you
|
||||||
ZLIB_VERSION symbol defined in zlib.h .
|
can #include <zlib.h>, it's there. The -lz option will probably link to
|
||||||
|
it. You can check the version at the top of zlib.h or with the
|
||||||
15. I have a question about OttoPDF.
|
ZLIB_VERSION symbol defined in zlib.h .
|
||||||
|
|
||||||
We are not the authors of OttoPDF. The real author is on the OttoPDF web
|
15. I have a question about OttoPDF.
|
||||||
site: Joel Hainley, jhainley@myndkryme.com.
|
|
||||||
|
We are not the authors of OttoPDF. The real author is on the OttoPDF web
|
||||||
16. Can zlib decode Flate data in an Adobe PDF file?
|
site: Joel Hainley, jhainley@myndkryme.com.
|
||||||
|
|
||||||
Yes. See http://www.pdflib.com/ . To modify PDF forms, see
|
16. Can zlib decode Flate data in an Adobe PDF file?
|
||||||
http://sourceforge.net/projects/acroformtool/ .
|
|
||||||
|
Yes. See http://www.pdflib.com/ . To modify PDF forms, see
|
||||||
17. Why am I getting this "register_frame_info not found" error on Solaris?
|
http://sourceforge.net/projects/acroformtool/ .
|
||||||
|
|
||||||
After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
|
17. Why am I getting this "register_frame_info not found" error on Solaris?
|
||||||
generates an error such as:
|
|
||||||
|
After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
|
||||||
ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
|
generates an error such as:
|
||||||
symbol __register_frame_info: referenced symbol not found
|
|
||||||
|
ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
|
||||||
The symbol __register_frame_info is not part of zlib, it is generated by
|
symbol __register_frame_info: referenced symbol not found
|
||||||
the C compiler (cc or gcc). You must recompile applications using zlib
|
|
||||||
which have this problem. This problem is specific to Solaris. See
|
The symbol __register_frame_info is not part of zlib, it is generated by
|
||||||
http://www.sunfreeware.com for Solaris versions of zlib and applications
|
the C compiler (cc or gcc). You must recompile applications using zlib
|
||||||
using zlib.
|
which have this problem. This problem is specific to Solaris. See
|
||||||
|
http://www.sunfreeware.com for Solaris versions of zlib and applications
|
||||||
18. Why does gzip give an error on a file I make with compress/deflate?
|
using zlib.
|
||||||
|
|
||||||
The compress and deflate functions produce data in the zlib format, which
|
18. Why does gzip give an error on a file I make with compress/deflate?
|
||||||
is different and incompatible with the gzip format. The gz* functions in
|
|
||||||
zlib on the other hand use the gzip format. Both the zlib and gzip formats
|
The compress and deflate functions produce data in the zlib format, which
|
||||||
use the same compressed data format internally, but have different headers
|
is different and incompatible with the gzip format. The gz* functions in
|
||||||
and trailers around the compressed data.
|
zlib on the other hand use the gzip format. Both the zlib and gzip formats
|
||||||
|
use the same compressed data format internally, but have different headers
|
||||||
19. Ok, so why are there two different formats?
|
and trailers around the compressed data.
|
||||||
|
|
||||||
The gzip format was designed to retain the directory information about a
|
19. Ok, so why are there two different formats?
|
||||||
single file, such as the name and last modification date. The zlib format
|
|
||||||
on the other hand was designed for in-memory and communication channel
|
The gzip format was designed to retain the directory information about a
|
||||||
applications, and has a much more compact header and trailer and uses a
|
single file, such as the name and last modification date. The zlib format
|
||||||
faster integrity check than gzip.
|
on the other hand was designed for in-memory and communication channel
|
||||||
|
applications, and has a much more compact header and trailer and uses a
|
||||||
20. Well that's nice, but how do I make a gzip file in memory?
|
faster integrity check than gzip.
|
||||||
|
|
||||||
You can request that deflate write the gzip format instead of the zlib
|
20. Well that's nice, but how do I make a gzip file in memory?
|
||||||
format using deflateInit2(). You can also request that inflate decode the
|
|
||||||
gzip format using inflateInit2(). Read zlib.h for more details.
|
You can request that deflate write the gzip format instead of the zlib
|
||||||
|
format using deflateInit2(). You can also request that inflate decode the
|
||||||
21. Is zlib thread-safe?
|
gzip format using inflateInit2(). Read zlib.h for more details.
|
||||||
|
|
||||||
Yes. However any library routines that zlib uses and any application-
|
21. Is zlib thread-safe?
|
||||||
provided memory allocation routines must also be thread-safe. zlib's gz*
|
|
||||||
functions use stdio library routines, and most of zlib's functions use the
|
Yes. However any library routines that zlib uses and any application-
|
||||||
library memory allocation routines by default. zlib's *Init* functions
|
provided memory allocation routines must also be thread-safe. zlib's gz*
|
||||||
allow for the application to provide custom memory allocation routines.
|
functions use stdio library routines, and most of zlib's functions use the
|
||||||
|
library memory allocation routines by default. zlib's *Init* functions
|
||||||
Of course, you should only operate on any given zlib or gzip stream from a
|
allow for the application to provide custom memory allocation routines.
|
||||||
single thread at a time.
|
|
||||||
|
Of course, you should only operate on any given zlib or gzip stream from a
|
||||||
22. Can I use zlib in my commercial application?
|
single thread at a time.
|
||||||
|
|
||||||
Yes. Please read the license in zlib.h.
|
22. Can I use zlib in my commercial application?
|
||||||
|
|
||||||
23. Is zlib under the GNU license?
|
Yes. Please read the license in zlib.h.
|
||||||
|
|
||||||
No. Please read the license in zlib.h.
|
23. Is zlib under the GNU license?
|
||||||
|
|
||||||
24. The license says that altered source versions must be "plainly marked". So
|
No. Please read the license in zlib.h.
|
||||||
what exactly do I need to do to meet that requirement?
|
|
||||||
|
24. The license says that altered source versions must be "plainly marked". So
|
||||||
You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
|
what exactly do I need to do to meet that requirement?
|
||||||
particular, the final version number needs to be changed to "f", and an
|
|
||||||
identification string should be appended to ZLIB_VERSION. Version numbers
|
You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
|
||||||
x.x.x.f are reserved for modifications to zlib by others than the zlib
|
particular, the final version number needs to be changed to "f", and an
|
||||||
maintainers. For example, if the version of the base zlib you are altering
|
identification string should be appended to ZLIB_VERSION. Version numbers
|
||||||
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
|
x.x.x.f are reserved for modifications to zlib by others than the zlib
|
||||||
ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
|
maintainers. For example, if the version of the base zlib you are altering
|
||||||
update the version strings in deflate.c and inftrees.c.
|
is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
|
||||||
|
ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
|
||||||
For altered source distributions, you should also note the origin and
|
update the version strings in deflate.c and inftrees.c.
|
||||||
nature of the changes in zlib.h, as well as in ChangeLog and README, along
|
|
||||||
with the dates of the alterations. The origin should include at least your
|
For altered source distributions, you should also note the origin and
|
||||||
name (or your company's name), and an email address to contact for help or
|
nature of the changes in zlib.h, as well as in ChangeLog and README, along
|
||||||
issues with the library.
|
with the dates of the alterations. The origin should include at least your
|
||||||
|
name (or your company's name), and an email address to contact for help or
|
||||||
Note that distributing a compiled zlib library along with zlib.h and
|
issues with the library.
|
||||||
zconf.h is also a source distribution, and so you should change
|
|
||||||
ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
|
Note that distributing a compiled zlib library along with zlib.h and
|
||||||
in zlib.h as you would for a full source distribution.
|
zconf.h is also a source distribution, and so you should change
|
||||||
|
ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
|
||||||
25. Will zlib work on a big-endian or little-endian architecture, and can I
|
in zlib.h as you would for a full source distribution.
|
||||||
exchange compressed data between them?
|
|
||||||
|
25. Will zlib work on a big-endian or little-endian architecture, and can I
|
||||||
Yes and yes.
|
exchange compressed data between them?
|
||||||
|
|
||||||
26. Will zlib work on a 64-bit machine?
|
Yes and yes.
|
||||||
|
|
||||||
Yes. It has been tested on 64-bit machines, and has no dependence on any
|
26. Will zlib work on a 64-bit machine?
|
||||||
data types being limited to 32-bits in length. If you have any
|
|
||||||
difficulties, please provide a complete problem report to zlib@gzip.org
|
Yes. It has been tested on 64-bit machines, and has no dependence on any
|
||||||
|
data types being limited to 32-bits in length. If you have any
|
||||||
27. Will zlib decompress data from the PKWare Data Compression Library?
|
difficulties, please provide a complete problem report to zlib@gzip.org
|
||||||
|
|
||||||
No. The PKWare DCL uses a completely different compressed data format than
|
27. Will zlib decompress data from the PKWare Data Compression Library?
|
||||||
does PKZIP and zlib. However, you can look in zlib's contrib/blast
|
|
||||||
directory for a possible solution to your problem.
|
No. The PKWare DCL uses a completely different compressed data format than
|
||||||
|
does PKZIP and zlib. However, you can look in zlib's contrib/blast
|
||||||
28. Can I access data randomly in a compressed stream?
|
directory for a possible solution to your problem.
|
||||||
|
|
||||||
No, not without some preparation. If when compressing you periodically use
|
28. Can I access data randomly in a compressed stream?
|
||||||
Z_FULL_FLUSH, carefully write all the pending data at those points, and
|
|
||||||
keep an index of those locations, then you can start decompression at those
|
No, not without some preparation. If when compressing you periodically use
|
||||||
points. You have to be careful to not use Z_FULL_FLUSH too often, since it
|
Z_FULL_FLUSH, carefully write all the pending data at those points, and
|
||||||
can significantly degrade compression. Alternatively, you can scan a
|
keep an index of those locations, then you can start decompression at those
|
||||||
deflate stream once to generate an index, and then use that index for
|
points. You have to be careful to not use Z_FULL_FLUSH too often, since it
|
||||||
random access. See examples/zran.c .
|
can significantly degrade compression. Alternatively, you can scan a
|
||||||
|
deflate stream once to generate an index, and then use that index for
|
||||||
29. Does zlib work on MVS, OS/390, CICS, etc.?
|
random access. See examples/zran.c .
|
||||||
|
|
||||||
It has in the past, but we have not heard of any recent evidence. There
|
29. Does zlib work on MVS, OS/390, CICS, etc.?
|
||||||
were working ports of zlib 1.1.4 to MVS, but those links no longer work.
|
|
||||||
If you know of recent, successful applications of zlib on these operating
|
It has in the past, but we have not heard of any recent evidence. There
|
||||||
systems, please let us know. Thanks.
|
were working ports of zlib 1.1.4 to MVS, but those links no longer work.
|
||||||
|
If you know of recent, successful applications of zlib on these operating
|
||||||
30. Is there some simpler, easier to read version of inflate I can look at to
|
systems, please let us know. Thanks.
|
||||||
understand the deflate format?
|
|
||||||
|
30. Is there some simpler, easier to read version of inflate I can look at to
|
||||||
First off, you should read RFC 1951. Second, yes. Look in zlib's
|
understand the deflate format?
|
||||||
contrib/puff directory.
|
|
||||||
|
First off, you should read RFC 1951. Second, yes. Look in zlib's
|
||||||
31. Does zlib infringe on any patents?
|
contrib/puff directory.
|
||||||
|
|
||||||
As far as we know, no. In fact, that was originally the whole point behind
|
31. Does zlib infringe on any patents?
|
||||||
zlib. Look here for some more information:
|
|
||||||
|
As far as we know, no. In fact, that was originally the whole point behind
|
||||||
http://www.gzip.org/#faq11
|
zlib. Look here for some more information:
|
||||||
|
|
||||||
32. Can zlib work with greater than 4 GB of data?
|
http://www.gzip.org/#faq11
|
||||||
|
|
||||||
Yes. inflate() and deflate() will process any amount of data correctly.
|
32. Can zlib work with greater than 4 GB of data?
|
||||||
Each call of inflate() or deflate() is limited to input and output chunks
|
|
||||||
of the maximum value that can be stored in the compiler's "unsigned int"
|
Yes. inflate() and deflate() will process any amount of data correctly.
|
||||||
type, but there is no limit to the number of chunks. Note however that the
|
Each call of inflate() or deflate() is limited to input and output chunks
|
||||||
strm.total_in and strm_total_out counters may be limited to 4 GB. These
|
of the maximum value that can be stored in the compiler's "unsigned int"
|
||||||
counters are provided as a convenience and are not used internally by
|
type, but there is no limit to the number of chunks. Note however that the
|
||||||
inflate() or deflate(). The application can easily set up its own counters
|
strm.total_in and strm_total_out counters may be limited to 4 GB. These
|
||||||
updated after each call of inflate() or deflate() to count beyond 4 GB.
|
counters are provided as a convenience and are not used internally by
|
||||||
compress() and uncompress() may be limited to 4 GB, since they operate in a
|
inflate() or deflate(). The application can easily set up its own counters
|
||||||
single call. gzseek() and gztell() may be limited to 4 GB depending on how
|
updated after each call of inflate() or deflate() to count beyond 4 GB.
|
||||||
zlib is compiled. See the zlibCompileFlags() function in zlib.h.
|
compress() and uncompress() may be limited to 4 GB, since they operate in a
|
||||||
|
single call. gzseek() and gztell() may be limited to 4 GB depending on how
|
||||||
The word "may" appears several times above since there is a 4 GB limit only
|
zlib is compiled. See the zlibCompileFlags() function in zlib.h.
|
||||||
if the compiler's "long" type is 32 bits. If the compiler's "long" type is
|
|
||||||
64 bits, then the limit is 16 exabytes.
|
The word "may" appears several times above since there is a 4 GB limit only
|
||||||
|
if the compiler's "long" type is 32 bits. If the compiler's "long" type is
|
||||||
33. Does zlib have any security vulnerabilities?
|
64 bits, then the limit is 16 exabytes.
|
||||||
|
|
||||||
The only one that we are aware of is potentially in gzprintf(). If zlib is
|
33. Does zlib have any security vulnerabilities?
|
||||||
compiled to use sprintf() or vsprintf(), then there is no protection
|
|
||||||
against a buffer overflow of an 8K string space (or other value as set by
|
The only one that we are aware of is potentially in gzprintf(). If zlib is
|
||||||
gzbuffer()), other than the caller of gzprintf() assuring that the output
|
compiled to use sprintf() or vsprintf(), then there is no protection
|
||||||
will not exceed 8K. On the other hand, if zlib is compiled to use
|
against a buffer overflow of an 8K string space (or other value as set by
|
||||||
snprintf() or vsnprintf(), which should normally be the case, then there is
|
gzbuffer()), other than the caller of gzprintf() assuring that the output
|
||||||
no vulnerability. The ./configure script will display warnings if an
|
will not exceed 8K. On the other hand, if zlib is compiled to use
|
||||||
insecure variation of sprintf() will be used by gzprintf(). Also the
|
snprintf() or vsnprintf(), which should normally be the case, then there is
|
||||||
zlibCompileFlags() function will return information on what variant of
|
no vulnerability. The ./configure script will display warnings if an
|
||||||
sprintf() is used by gzprintf().
|
insecure variation of sprintf() will be used by gzprintf(). Also the
|
||||||
|
zlibCompileFlags() function will return information on what variant of
|
||||||
If you don't have snprintf() or vsnprintf() and would like one, you can
|
sprintf() is used by gzprintf().
|
||||||
find a portable implementation here:
|
|
||||||
|
If you don't have snprintf() or vsnprintf() and would like one, you can
|
||||||
http://www.ijs.si/software/snprintf/
|
find a portable implementation here:
|
||||||
|
|
||||||
Note that you should be using the most recent version of zlib. Versions
|
http://www.ijs.si/software/snprintf/
|
||||||
1.1.3 and before were subject to a double-free vulnerability, and versions
|
|
||||||
1.2.1 and 1.2.2 were subject to an access exception when decompressing
|
Note that you should be using the most recent version of zlib. Versions
|
||||||
invalid compressed data.
|
1.1.3 and before were subject to a double-free vulnerability, and versions
|
||||||
|
1.2.1 and 1.2.2 were subject to an access exception when decompressing
|
||||||
34. Is there a Java version of zlib?
|
invalid compressed data.
|
||||||
|
|
||||||
Probably what you want is to use zlib in Java. zlib is already included
|
34. Is there a Java version of zlib?
|
||||||
as part of the Java SDK in the java.util.zip package. If you really want
|
|
||||||
a version of zlib written in the Java language, look on the zlib home
|
Probably what you want is to use zlib in Java. zlib is already included
|
||||||
page for links: http://zlib.net/ .
|
as part of the Java SDK in the java.util.zip package. If you really want
|
||||||
|
a version of zlib written in the Java language, look on the zlib home
|
||||||
35. I get this or that compiler or source-code scanner warning when I crank it
|
page for links: http://zlib.net/ .
|
||||||
up to maximally-pedantic. Can't you guys write proper code?
|
|
||||||
|
35. I get this or that compiler or source-code scanner warning when I crank it
|
||||||
Many years ago, we gave up attempting to avoid warnings on every compiler
|
up to maximally-pedantic. Can't you guys write proper code?
|
||||||
in the universe. It just got to be a waste of time, and some compilers
|
|
||||||
were downright silly as well as contradicted each other. So now, we simply
|
Many years ago, we gave up attempting to avoid warnings on every compiler
|
||||||
make sure that the code always works.
|
in the universe. It just got to be a waste of time, and some compilers
|
||||||
|
were downright silly as well as contradicted each other. So now, we simply
|
||||||
36. Valgrind (or some similar memory access checker) says that deflate is
|
make sure that the code always works.
|
||||||
performing a conditional jump that depends on an uninitialized value.
|
|
||||||
Isn't that a bug?
|
36. Valgrind (or some similar memory access checker) says that deflate is
|
||||||
|
performing a conditional jump that depends on an uninitialized value.
|
||||||
No. That is intentional for performance reasons, and the output of deflate
|
Isn't that a bug?
|
||||||
is not affected. This only started showing up recently since zlib 1.2.x
|
|
||||||
uses malloc() by default for allocations, whereas earlier versions used
|
No. That is intentional for performance reasons, and the output of deflate
|
||||||
calloc(), which zeros out the allocated memory. Even though the code was
|
is not affected. This only started showing up recently since zlib 1.2.x
|
||||||
correct, versions 1.2.4 and later was changed to not stimulate these
|
uses malloc() by default for allocations, whereas earlier versions used
|
||||||
checkers.
|
calloc(), which zeros out the allocated memory. Even though the code was
|
||||||
|
correct, versions 1.2.4 and later was changed to not stimulate these
|
||||||
37. Will zlib read the (insert any ancient or arcane format here) compressed
|
checkers.
|
||||||
data format?
|
|
||||||
|
37. Will zlib read the (insert any ancient or arcane format here) compressed
|
||||||
Probably not. Look in the comp.compression FAQ for pointers to various
|
data format?
|
||||||
formats and associated software.
|
|
||||||
|
Probably not. Look in the comp.compression FAQ for pointers to various
|
||||||
38. How can I encrypt/decrypt zip files with zlib?
|
formats and associated software.
|
||||||
|
|
||||||
zlib doesn't support encryption. The original PKZIP encryption is very
|
38. How can I encrypt/decrypt zip files with zlib?
|
||||||
weak and can be broken with freely available programs. To get strong
|
|
||||||
encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
|
zlib doesn't support encryption. The original PKZIP encryption is very
|
||||||
compression. For PKZIP compatible "encryption", look at
|
weak and can be broken with freely available programs. To get strong
|
||||||
http://www.info-zip.org/
|
encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
|
||||||
|
compression. For PKZIP compatible "encryption", look at
|
||||||
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
|
http://www.info-zip.org/
|
||||||
|
|
||||||
"gzip" is the gzip format, and "deflate" is the zlib format. They should
|
39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
|
||||||
probably have called the second one "zlib" instead to avoid confusion with
|
|
||||||
the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
|
"gzip" is the gzip format, and "deflate" is the zlib format. They should
|
||||||
correctly points to the zlib specification in RFC 1950 for the "deflate"
|
probably have called the second one "zlib" instead to avoid confusion with
|
||||||
transfer encoding, there have been reports of servers and browsers that
|
the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
|
||||||
incorrectly produce or expect raw deflate data per the deflate
|
correctly points to the zlib specification in RFC 1950 for the "deflate"
|
||||||
specficiation in RFC 1951, most notably Microsoft. So even though the
|
transfer encoding, there have been reports of servers and browsers that
|
||||||
"deflate" transfer encoding using the zlib format would be the more
|
incorrectly produce or expect raw deflate data per the deflate
|
||||||
efficient approach (and in fact exactly what the zlib format was designed
|
specification in RFC 1951, most notably Microsoft. So even though the
|
||||||
for), using the "gzip" transfer encoding is probably more reliable due to
|
"deflate" transfer encoding using the zlib format would be the more
|
||||||
an unfortunate choice of name on the part of the HTTP 1.1 authors.
|
efficient approach (and in fact exactly what the zlib format was designed
|
||||||
|
for), using the "gzip" transfer encoding is probably more reliable due to
|
||||||
Bottom line: use the gzip format for HTTP 1.1 encoding.
|
an unfortunate choice of name on the part of the HTTP 1.1 authors.
|
||||||
|
|
||||||
40. Does zlib support the new "Deflate64" format introduced by PKWare?
|
Bottom line: use the gzip format for HTTP 1.1 encoding.
|
||||||
|
|
||||||
No. PKWare has apparently decided to keep that format proprietary, since
|
40. Does zlib support the new "Deflate64" format introduced by PKWare?
|
||||||
they have not documented it as they have previous compression formats. In
|
|
||||||
any case, the compression improvements are so modest compared to other more
|
No. PKWare has apparently decided to keep that format proprietary, since
|
||||||
modern approaches, that it's not worth the effort to implement.
|
they have not documented it as they have previous compression formats. In
|
||||||
|
any case, the compression improvements are so modest compared to other more
|
||||||
41. I'm having a problem with the zip functions in zlib, can you help?
|
modern approaches, that it's not worth the effort to implement.
|
||||||
|
|
||||||
There are no zip functions in zlib. You are probably using minizip by
|
41. I'm having a problem with the zip functions in zlib, can you help?
|
||||||
Giles Vollant, which is found in the contrib directory of zlib. It is not
|
|
||||||
part of zlib. In fact none of the stuff in contrib is part of zlib. The
|
There are no zip functions in zlib. You are probably using minizip by
|
||||||
files in there are not supported by the zlib authors. You need to contact
|
Giles Vollant, which is found in the contrib directory of zlib. It is not
|
||||||
the authors of the respective contribution for help.
|
part of zlib. In fact none of the stuff in contrib is part of zlib. The
|
||||||
|
files in there are not supported by the zlib authors. You need to contact
|
||||||
42. The match.asm code in contrib is under the GNU General Public License.
|
the authors of the respective contribution for help.
|
||||||
Since it's part of zlib, doesn't that mean that all of zlib falls under the
|
|
||||||
GNU GPL?
|
42. The match.asm code in contrib is under the GNU General Public License.
|
||||||
|
Since it's part of zlib, doesn't that mean that all of zlib falls under the
|
||||||
No. The files in contrib are not part of zlib. They were contributed by
|
GNU GPL?
|
||||||
other authors and are provided as a convenience to the user within the zlib
|
|
||||||
distribution. Each item in contrib has its own license.
|
No. The files in contrib are not part of zlib. They were contributed by
|
||||||
|
other authors and are provided as a convenience to the user within the zlib
|
||||||
43. Is zlib subject to export controls? What is its ECCN?
|
distribution. Each item in contrib has its own license.
|
||||||
|
|
||||||
zlib is not subject to export controls, and so is classified as EAR99.
|
43. Is zlib subject to export controls? What is its ECCN?
|
||||||
|
|
||||||
44. Can you please sign these lengthy legal documents and fax them back to us
|
zlib is not subject to export controls, and so is classified as EAR99.
|
||||||
so that we can use your software in our product?
|
|
||||||
|
44. Can you please sign these lengthy legal documents and fax them back to us
|
||||||
No. Go away. Shoo.
|
so that we can use your software in our product?
|
||||||
|
|
||||||
|
No. Go away. Shoo.
|
||||||
|
|
|
@ -1,114 +1,115 @@
|
||||||
ZLIB DATA COMPRESSION LIBRARY
|
ZLIB DATA COMPRESSION LIBRARY
|
||||||
|
|
||||||
zlib 1.2.4 is a general purpose data compression library. All the code is
|
zlib 1.2.7 is a general purpose data compression library. All the code is
|
||||||
thread safe. The data format used by the zlib library is described by RFCs
|
thread safe. The data format used by the zlib library is described by RFCs
|
||||||
(Request for Comments) 1950 to 1952 in the files
|
(Request for Comments) 1950 to 1952 in the files
|
||||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||||||
and rfc1952.txt (gzip format).
|
rfc1952 (gzip format).
|
||||||
|
|
||||||
All functions of the compression library are documented in the file zlib.h
|
All functions of the compression library are documented in the file zlib.h
|
||||||
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
|
||||||
of the library is given in the file example.c which also tests that the library
|
of the library is given in the file test/example.c which also tests that
|
||||||
is working correctly. Another example is given in the file minigzip.c. The
|
the library is working correctly. Another example is given in the file
|
||||||
compression library itself is composed of all source files except example.c and
|
test/minigzip.c. The compression library itself is composed of all source
|
||||||
minigzip.c.
|
files in the root directory.
|
||||||
|
|
||||||
To compile all files and run the test program, follow the instructions given at
|
To compile all files and run the test program, follow the instructions given at
|
||||||
the top of Makefile.in. In short "./configure; make test", and if that goes
|
the top of Makefile.in. In short "./configure; make test", and if that goes
|
||||||
well, "make install" should work for most flavors of Unix. For Windows, use one
|
well, "make install" should work for most flavors of Unix. For Windows, use
|
||||||
of the special makefiles in win32/ or projects/ . For VMS, use make_vms.com.
|
one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use
|
||||||
|
make_vms.com.
|
||||||
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
|
||||||
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
|
||||||
http://zlib.net/ . Before reporting a problem, please check this site to
|
<info@winimage.com> for the Windows DLL version. The zlib home page is
|
||||||
verify that you have the latest version of zlib; otherwise get the latest
|
http://zlib.net/ . Before reporting a problem, please check this site to
|
||||||
version and check whether the problem still exists or not.
|
verify that you have the latest version of zlib; otherwise get the latest
|
||||||
|
version and check whether the problem still exists or not.
|
||||||
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
|
|
||||||
|
PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
|
||||||
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
|
||||||
issue of Dr. Dobb's Journal; a copy of the article is available at
|
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||||
http://marknelson.us/1997/01/01/zlib-engine/ .
|
issue of Dr. Dobb's Journal; a copy of the article is available at
|
||||||
|
http://marknelson.us/1997/01/01/zlib-engine/ .
|
||||||
The changes made in version 1.2.4 are documented in the file ChangeLog.
|
|
||||||
|
The changes made in version 1.2.7 are documented in the file ChangeLog.
|
||||||
Unsupported third party contributions are provided in directory contrib/ .
|
|
||||||
|
Unsupported third party contributions are provided in directory contrib/ .
|
||||||
zlib is available in Java using the java.util.zip package, documented at
|
|
||||||
http://java.sun.com/developer/technicalArticles/Programming/compression/ .
|
zlib is available in Java using the java.util.zip package, documented at
|
||||||
|
http://java.sun.com/developer/technicalArticles/Programming/compression/ .
|
||||||
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
|
|
||||||
at CPAN (Comprehensive Perl Archive Network) sites, including
|
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
|
||||||
http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
|
at CPAN (Comprehensive Perl Archive Network) sites, including
|
||||||
|
http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
|
||||||
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
|
||||||
available in Python 1.5 and later versions, see
|
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
|
||||||
http://www.python.org/doc/lib/module-zlib.html .
|
available in Python 1.5 and later versions, see
|
||||||
|
http://docs.python.org/library/zlib.html .
|
||||||
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
|
||||||
|
zlib is built into tcl: http://wiki.tcl.tk/4610 .
|
||||||
An experimental package to read and write files in .zip format, written on top
|
|
||||||
of zlib by Gilles Vollant <info@winimage.com>, is available in the
|
An experimental package to read and write files in .zip format, written on top
|
||||||
contrib/minizip directory of zlib.
|
of zlib by Gilles Vollant <info@winimage.com>, is available in the
|
||||||
|
contrib/minizip directory of zlib.
|
||||||
|
|
||||||
Notes for some targets:
|
|
||||||
|
Notes for some targets:
|
||||||
- For Windows DLL versions, please see win32/DLL_FAQ.txt
|
|
||||||
|
- For Windows DLL versions, please see win32/DLL_FAQ.txt
|
||||||
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
|
|
||||||
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
|
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
|
||||||
compiler flag). The compiler bug has been reported to SGI.
|
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
|
||||||
|
compiler flag). The compiler bug has been reported to SGI.
|
||||||
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
|
|
||||||
when compiled with cc.
|
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
|
||||||
|
when compiled with cc.
|
||||||
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
|
|
||||||
necessary to get gzprintf working correctly. This is done by configure.
|
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
|
||||||
|
necessary to get gzprintf working correctly. This is done by configure.
|
||||||
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
|
|
||||||
other compilers. Use "make test" to check your compiler.
|
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
|
||||||
|
other compilers. Use "make test" to check your compiler.
|
||||||
- gzdopen is not supported on RISCOS or BEOS.
|
|
||||||
|
- gzdopen is not supported on RISCOS or BEOS.
|
||||||
- For PalmOs, see http://palmzlib.sourceforge.net/
|
|
||||||
|
- For PalmOs, see http://palmzlib.sourceforge.net/
|
||||||
|
|
||||||
Acknowledgments:
|
|
||||||
|
Acknowledgments:
|
||||||
The deflate format used by zlib was defined by Phil Katz. The deflate and
|
|
||||||
zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
The deflate format used by zlib was defined by Phil Katz. The deflate and
|
||||||
people who reported problems and suggested various improvements in zlib; they
|
zlib specifications were written by L. Peter Deutsch. Thanks to all the
|
||||||
are too numerous to cite here.
|
people who reported problems and suggested various improvements in zlib; they
|
||||||
|
are too numerous to cite here.
|
||||||
Copyright notice:
|
|
||||||
|
Copyright notice:
|
||||||
(C) 1995-2010 Jean-loup Gailly and Mark Adler
|
|
||||||
|
(C) 1995-2012 Jean-loup Gailly and Mark Adler
|
||||||
This software is provided 'as-is', without any express or implied
|
|
||||||
warranty. In no event will the authors be held liable for any damages
|
This software is provided 'as-is', without any express or implied
|
||||||
arising from the use of this software.
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
Permission is granted to anyone to use this software for any purpose,
|
|
||||||
including commercial applications, and to alter it and redistribute it
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
freely, subject to the following restrictions:
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
1. The origin of this software must not be misrepresented; you must not
|
|
||||||
claim that you wrote the original software. If you use this software
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
in a product, an acknowledgment in the product documentation would be
|
claim that you wrote the original software. If you use this software
|
||||||
appreciated but is not required.
|
in a product, an acknowledgment in the product documentation would be
|
||||||
2. Altered source versions must be plainly marked as such, and must not be
|
appreciated but is not required.
|
||||||
misrepresented as being the original software.
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
3. This notice may not be removed or altered from any source distribution.
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
Jean-loup Gailly Mark Adler
|
|
||||||
jloup@gzip.org madler@alumni.caltech.edu
|
Jean-loup Gailly Mark Adler
|
||||||
|
jloup@gzip.org madler@alumni.caltech.edu
|
||||||
If you use the zlib library in a product, we would appreciate *not* receiving
|
|
||||||
lengthy legal documents to sign. The sources are provided for free but without
|
If you use the zlib library in a product, we would appreciate *not* receiving
|
||||||
warranty of any kind. The library has been entirely written by Jean-loup
|
lengthy legal documents to sign. The sources are provided for free but without
|
||||||
Gailly and Mark Adler; it does not include third-party code.
|
warranty of any kind. The library has been entirely written by Jean-loup
|
||||||
|
Gailly and Mark Adler; it does not include third-party code.
|
||||||
If you redistribute modified sources, we would appreciate that you include in
|
|
||||||
the file ChangeLog history information documenting your changes. Please read
|
If you redistribute modified sources, we would appreciate that you include in
|
||||||
the FAQ for more information on the distribution of modified source versions.
|
the file ChangeLog history information documenting your changes. Please read
|
||||||
|
the FAQ for more information on the distribution of modified source versions.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
/* adler32.c -- compute the Adler-32 checksum of a data stream
|
||||||
* Copyright (C) 1995-2007 Mark Adler
|
* Copyright (C) 1995-2011 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@
|
||||||
|
|
||||||
#define local static
|
#define local static
|
||||||
|
|
||||||
local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
|
||||||
|
|
||||||
#define BASE 65521UL /* largest prime smaller than 65536 */
|
#define BASE 65521 /* largest prime smaller than 65536 */
|
||||||
#define NMAX 5552
|
#define NMAX 5552
|
||||||
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
|
||||||
|
|
||||||
|
@ -21,39 +21,44 @@ local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2);
|
||||||
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
|
||||||
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
#define DO16(buf) DO8(buf,0); DO8(buf,8);
|
||||||
|
|
||||||
/* use NO_DIVIDE if your processor does not do division in hardware */
|
/* use NO_DIVIDE if your processor does not do division in hardware --
|
||||||
|
try it both ways to see which is faster */
|
||||||
#ifdef NO_DIVIDE
|
#ifdef NO_DIVIDE
|
||||||
# define MOD(a) \
|
/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
|
||||||
|
(thank you to John Reiser for pointing this out) */
|
||||||
|
# define CHOP(a) \
|
||||||
do { \
|
do { \
|
||||||
if (a >= (BASE << 16)) a -= (BASE << 16); \
|
unsigned long tmp = a >> 16; \
|
||||||
if (a >= (BASE << 15)) a -= (BASE << 15); \
|
a &= 0xffffUL; \
|
||||||
if (a >= (BASE << 14)) a -= (BASE << 14); \
|
a += (tmp << 4) - tmp; \
|
||||||
if (a >= (BASE << 13)) a -= (BASE << 13); \
|
} while (0)
|
||||||
if (a >= (BASE << 12)) a -= (BASE << 12); \
|
# define MOD28(a) \
|
||||||
if (a >= (BASE << 11)) a -= (BASE << 11); \
|
do { \
|
||||||
if (a >= (BASE << 10)) a -= (BASE << 10); \
|
CHOP(a); \
|
||||||
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; \
|
if (a >= BASE) a -= BASE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
# define MOD4(a) \
|
# define MOD(a) \
|
||||||
do { \
|
do { \
|
||||||
if (a >= (BASE << 4)) a -= (BASE << 4); \
|
CHOP(a); \
|
||||||
if (a >= (BASE << 3)) a -= (BASE << 3); \
|
MOD28(a); \
|
||||||
if (a >= (BASE << 2)) a -= (BASE << 2); \
|
} while (0)
|
||||||
if (a >= (BASE << 1)) a -= (BASE << 1); \
|
# define MOD63(a) \
|
||||||
|
do { /* this assumes a is not negative */ \
|
||||||
|
z_off64_t tmp = a >> 32; \
|
||||||
|
a &= 0xffffffffL; \
|
||||||
|
a += (tmp << 8) - (tmp << 5) + tmp; \
|
||||||
|
tmp = a >> 16; \
|
||||||
|
a &= 0xffffL; \
|
||||||
|
a += (tmp << 4) - tmp; \
|
||||||
|
tmp = a >> 16; \
|
||||||
|
a &= 0xffffL; \
|
||||||
|
a += (tmp << 4) - tmp; \
|
||||||
if (a >= BASE) a -= BASE; \
|
if (a >= BASE) a -= BASE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#else
|
#else
|
||||||
# define MOD(a) a %= BASE
|
# define MOD(a) a %= BASE
|
||||||
# define MOD4(a) a %= BASE
|
# define MOD28(a) a %= BASE
|
||||||
|
# define MOD63(a) a %= BASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -92,7 +97,7 @@ uLong ZEXPORT adler32(adler, buf, len)
|
||||||
}
|
}
|
||||||
if (adler >= BASE)
|
if (adler >= BASE)
|
||||||
adler -= BASE;
|
adler -= BASE;
|
||||||
MOD4(sum2); /* only added so many BASE's */
|
MOD28(sum2); /* only added so many BASE's */
|
||||||
return adler | (sum2 << 16);
|
return adler | (sum2 << 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +142,13 @@ local uLong adler32_combine_(adler1, adler2, len2)
|
||||||
unsigned long sum2;
|
unsigned long sum2;
|
||||||
unsigned rem;
|
unsigned rem;
|
||||||
|
|
||||||
|
/* for negative len, return invalid adler32 as a clue for debugging */
|
||||||
|
if (len2 < 0)
|
||||||
|
return 0xffffffffUL;
|
||||||
|
|
||||||
/* the derivation of this formula is left as an exercise for the reader */
|
/* the derivation of this formula is left as an exercise for the reader */
|
||||||
rem = (unsigned)(len2 % BASE);
|
MOD63(len2); /* assumes len2 >= 0 */
|
||||||
|
rem = (unsigned)len2;
|
||||||
sum1 = adler1 & 0xffff;
|
sum1 = adler1 & 0xffff;
|
||||||
sum2 = rem * sum1;
|
sum2 = rem * sum1;
|
||||||
MOD(sum2);
|
MOD(sum2);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* crc32.c -- compute the CRC-32 of a data stream
|
/* crc32.c -- compute the CRC-32 of a data stream
|
||||||
* Copyright (C) 1995-2006 Mark Adler
|
* Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* 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
|
* Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
|
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
|
first call get_crc_table() to initialize the tables before allowing more than
|
||||||
one thread to use crc32().
|
one thread to use crc32().
|
||||||
|
|
||||||
|
DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
|
@ -30,31 +32,11 @@
|
||||||
|
|
||||||
#define local static
|
#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. */
|
/* Definitions for doing the crc four data bytes at a time. */
|
||||||
|
#if !defined(NOBYFOUR) && defined(Z_U4)
|
||||||
|
# define BYFOUR
|
||||||
|
#endif
|
||||||
#ifdef BYFOUR
|
#ifdef BYFOUR
|
||||||
# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
|
|
||||||
(((w)&0xff00)<<8)+(((w)&0xff)<<24))
|
|
||||||
local unsigned long crc32_little OF((unsigned long,
|
local unsigned long crc32_little OF((unsigned long,
|
||||||
const unsigned char FAR *, unsigned));
|
const unsigned char FAR *, unsigned));
|
||||||
local unsigned long crc32_big OF((unsigned long,
|
local unsigned long crc32_big OF((unsigned long,
|
||||||
|
@ -68,16 +50,16 @@
|
||||||
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
local unsigned long gf2_matrix_times OF((unsigned long *mat,
|
||||||
unsigned long vec));
|
unsigned long vec));
|
||||||
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
|
||||||
local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
|
local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
|
||||||
|
|
||||||
|
|
||||||
#ifdef DYNAMIC_CRC_TABLE
|
#ifdef DYNAMIC_CRC_TABLE
|
||||||
|
|
||||||
local volatile int crc_table_empty = 1;
|
local volatile int crc_table_empty = 1;
|
||||||
local unsigned long FAR crc_table[TBLS][256];
|
local z_crc_t FAR crc_table[TBLS][256];
|
||||||
local void make_crc_table OF((void));
|
local void make_crc_table OF((void));
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
local void write_table OF((FILE *, const unsigned long FAR *));
|
local void write_table OF((FILE *, const z_crc_t FAR *));
|
||||||
#endif /* MAKECRCH */
|
#endif /* MAKECRCH */
|
||||||
/*
|
/*
|
||||||
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
|
||||||
|
@ -107,9 +89,9 @@ local void make_crc_table OF((void));
|
||||||
*/
|
*/
|
||||||
local void make_crc_table()
|
local void make_crc_table()
|
||||||
{
|
{
|
||||||
unsigned long c;
|
z_crc_t c;
|
||||||
int n, k;
|
int n, k;
|
||||||
unsigned long poly; /* polynomial exclusive-or pattern */
|
z_crc_t poly; /* polynomial exclusive-or pattern */
|
||||||
/* terms of polynomial defining this crc (except x^32): */
|
/* terms of polynomial defining this crc (except x^32): */
|
||||||
static volatile int first = 1; /* flag to limit concurrent making */
|
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};
|
static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
|
||||||
|
@ -121,13 +103,13 @@ local void make_crc_table()
|
||||||
first = 0;
|
first = 0;
|
||||||
|
|
||||||
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
/* make exclusive-or pattern from polynomial (0xedb88320UL) */
|
||||||
poly = 0UL;
|
poly = 0;
|
||||||
for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
|
for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
|
||||||
poly |= 1UL << (31 - p[n]);
|
poly |= (z_crc_t)1 << (31 - p[n]);
|
||||||
|
|
||||||
/* generate a crc for every 8-bit value */
|
/* generate a crc for every 8-bit value */
|
||||||
for (n = 0; n < 256; n++) {
|
for (n = 0; n < 256; n++) {
|
||||||
c = (unsigned long)n;
|
c = (z_crc_t)n;
|
||||||
for (k = 0; k < 8; k++)
|
for (k = 0; k < 8; k++)
|
||||||
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
c = c & 1 ? poly ^ (c >> 1) : c >> 1;
|
||||||
crc_table[0][n] = c;
|
crc_table[0][n] = c;
|
||||||
|
@ -138,11 +120,11 @@ local void make_crc_table()
|
||||||
and then the byte reversal of those as well as the first table */
|
and then the byte reversal of those as well as the first table */
|
||||||
for (n = 0; n < 256; n++) {
|
for (n = 0; n < 256; n++) {
|
||||||
c = crc_table[0][n];
|
c = crc_table[0][n];
|
||||||
crc_table[4][n] = REV(c);
|
crc_table[4][n] = ZSWAP32(c);
|
||||||
for (k = 1; k < 4; k++) {
|
for (k = 1; k < 4; k++) {
|
||||||
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
c = crc_table[0][c & 0xff] ^ (c >> 8);
|
||||||
crc_table[k][n] = c;
|
crc_table[k][n] = c;
|
||||||
crc_table[k + 4][n] = REV(c);
|
crc_table[k + 4][n] = ZSWAP32(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* BYFOUR */
|
#endif /* BYFOUR */
|
||||||
|
@ -164,7 +146,7 @@ local void make_crc_table()
|
||||||
if (out == NULL) return;
|
if (out == NULL) return;
|
||||||
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
|
||||||
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
|
||||||
fprintf(out, "local const unsigned long FAR ");
|
fprintf(out, "local const z_crc_t FAR ");
|
||||||
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
|
||||||
write_table(out, crc_table[0]);
|
write_table(out, crc_table[0]);
|
||||||
# ifdef BYFOUR
|
# ifdef BYFOUR
|
||||||
|
@ -184,12 +166,13 @@ local void make_crc_table()
|
||||||
#ifdef MAKECRCH
|
#ifdef MAKECRCH
|
||||||
local void write_table(out, table)
|
local void write_table(out, table)
|
||||||
FILE *out;
|
FILE *out;
|
||||||
const unsigned long FAR *table;
|
const z_crc_t FAR *table;
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
for (n = 0; n < 256; n++)
|
for (n = 0; n < 256; n++)
|
||||||
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
|
fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
|
||||||
|
(unsigned long)(table[n]),
|
||||||
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
|
||||||
}
|
}
|
||||||
#endif /* MAKECRCH */
|
#endif /* MAKECRCH */
|
||||||
|
@ -204,13 +187,13 @@ local void write_table(out, table)
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* This function can be used by asm versions of crc32()
|
* This function can be used by asm versions of crc32()
|
||||||
*/
|
*/
|
||||||
const unsigned long FAR * ZEXPORT get_crc_table()
|
const z_crc_t FAR * ZEXPORT get_crc_table()
|
||||||
{
|
{
|
||||||
#ifdef DYNAMIC_CRC_TABLE
|
#ifdef DYNAMIC_CRC_TABLE
|
||||||
if (crc_table_empty)
|
if (crc_table_empty)
|
||||||
make_crc_table();
|
make_crc_table();
|
||||||
#endif /* DYNAMIC_CRC_TABLE */
|
#endif /* DYNAMIC_CRC_TABLE */
|
||||||
return (const unsigned long FAR *)crc_table;
|
return (const z_crc_t FAR *)crc_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
@ -221,7 +204,7 @@ const unsigned long FAR * ZEXPORT get_crc_table()
|
||||||
unsigned long ZEXPORT crc32(crc, buf, len)
|
unsigned long ZEXPORT crc32(crc, buf, len)
|
||||||
unsigned long crc;
|
unsigned long crc;
|
||||||
const unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
uInt len;
|
||||||
{
|
{
|
||||||
if (buf == Z_NULL) return 0UL;
|
if (buf == Z_NULL) return 0UL;
|
||||||
|
|
||||||
|
@ -232,7 +215,7 @@ unsigned long ZEXPORT crc32(crc, buf, len)
|
||||||
|
|
||||||
#ifdef BYFOUR
|
#ifdef BYFOUR
|
||||||
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
if (sizeof(void *) == sizeof(ptrdiff_t)) {
|
||||||
u4 endian;
|
z_crc_t endian;
|
||||||
|
|
||||||
endian = 1;
|
endian = 1;
|
||||||
if (*((unsigned char *)(&endian)))
|
if (*((unsigned char *)(&endian)))
|
||||||
|
@ -266,17 +249,17 @@ local unsigned long crc32_little(crc, buf, len)
|
||||||
const unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
{
|
{
|
||||||
register u4 c;
|
register z_crc_t c;
|
||||||
register const u4 FAR *buf4;
|
register const z_crc_t FAR *buf4;
|
||||||
|
|
||||||
c = (u4)crc;
|
c = (z_crc_t)crc;
|
||||||
c = ~c;
|
c = ~c;
|
||||||
while (len && ((ptrdiff_t)buf & 3)) {
|
while (len && ((ptrdiff_t)buf & 3)) {
|
||||||
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||||
while (len >= 32) {
|
while (len >= 32) {
|
||||||
DOLIT32;
|
DOLIT32;
|
||||||
len -= 32;
|
len -= 32;
|
||||||
|
@ -306,17 +289,17 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
const unsigned char FAR *buf;
|
const unsigned char FAR *buf;
|
||||||
unsigned len;
|
unsigned len;
|
||||||
{
|
{
|
||||||
register u4 c;
|
register z_crc_t c;
|
||||||
register const u4 FAR *buf4;
|
register const z_crc_t FAR *buf4;
|
||||||
|
|
||||||
c = REV((u4)crc);
|
c = ZSWAP32((z_crc_t)crc);
|
||||||
c = ~c;
|
c = ~c;
|
||||||
while (len && ((ptrdiff_t)buf & 3)) {
|
while (len && ((ptrdiff_t)buf & 3)) {
|
||||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf4 = (const u4 FAR *)(const void FAR *)buf;
|
buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
|
||||||
buf4--;
|
buf4--;
|
||||||
while (len >= 32) {
|
while (len >= 32) {
|
||||||
DOBIG32;
|
DOBIG32;
|
||||||
|
@ -333,7 +316,7 @@ local unsigned long crc32_big(crc, buf, len)
|
||||||
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
|
||||||
} while (--len);
|
} while (--len);
|
||||||
c = ~c;
|
c = ~c;
|
||||||
return (unsigned long)(REV(c));
|
return (unsigned long)(ZSWAP32(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* BYFOUR */
|
#endif /* BYFOUR */
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* Generated automatically by crc32.c
|
* Generated automatically by crc32.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
local const unsigned long FAR crc_table[TBLS][256] =
|
local const z_crc_t FAR crc_table[TBLS][256] =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* deflate.c -- compress data using the deflation algorithm
|
/* deflate.c -- compress data using the deflation algorithm
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
* Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
* REFERENCES
|
* REFERENCES
|
||||||
*
|
*
|
||||||
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
* Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
|
||||||
* Available in http://www.ietf.org/rfc/rfc1951.txt
|
* Available in http://tools.ietf.org/html/rfc1951
|
||||||
*
|
*
|
||||||
* A description of the Rabin and Karp algorithm is given in the book
|
* A description of the Rabin and Karp algorithm is given in the book
|
||||||
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
* "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
#include "deflate.h"
|
#include "deflate.h"
|
||||||
|
|
||||||
const char deflate_copyright[] =
|
const char deflate_copyright[] =
|
||||||
" deflate 1.2.4 Copyright 1995-2010 Jean-loup Gailly and Mark Adler ";
|
" deflate 1.2.7 Copyright 1995-2012 Jean-loup Gailly and Mark Adler ";
|
||||||
/*
|
/*
|
||||||
If you use the zlib library in a product, an acknowledgment is welcome
|
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
|
in the documentation of your product. If for some reason you cannot
|
||||||
|
@ -155,6 +155,9 @@ local const config configuration_table[10] = {
|
||||||
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
|
||||||
|
#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Update a hash value with the given input byte
|
* Update a hash value with the given input byte
|
||||||
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
||||||
|
@ -235,10 +238,19 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
|
||||||
|
|
||||||
strm->msg = Z_NULL;
|
strm->msg = Z_NULL;
|
||||||
if (strm->zalloc == (alloc_func)0) {
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
strm->zalloc = zcalloc;
|
strm->zalloc = zcalloc;
|
||||||
strm->opaque = (voidpf)0;
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FASTEST
|
#ifdef FASTEST
|
||||||
if (level != 0) level = 1;
|
if (level != 0) level = 1;
|
||||||
|
@ -314,43 +326,70 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
|
||||||
uInt dictLength;
|
uInt dictLength;
|
||||||
{
|
{
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
uInt length = dictLength;
|
uInt str, n;
|
||||||
uInt n;
|
int wrap;
|
||||||
IPos hash_head = 0;
|
unsigned avail;
|
||||||
|
unsigned char *next;
|
||||||
|
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
|
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
|
||||||
strm->state->wrap == 2 ||
|
return Z_STREAM_ERROR;
|
||||||
(strm->state->wrap == 1 && strm->state->status != INIT_STATE))
|
s = strm->state;
|
||||||
|
wrap = s->wrap;
|
||||||
|
if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
|
||||||
return Z_STREAM_ERROR;
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
s = strm->state;
|
/* when using zlib wrappers, compute Adler-32 for provided dictionary */
|
||||||
if (s->wrap)
|
if (wrap == 1)
|
||||||
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
strm->adler = adler32(strm->adler, dictionary, dictLength);
|
||||||
|
s->wrap = 0; /* avoid computing Adler-32 in read_buf */
|
||||||
|
|
||||||
if (length < MIN_MATCH) return Z_OK;
|
/* if dictionary would fill window, just replace the history */
|
||||||
if (length > s->w_size) {
|
if (dictLength >= s->w_size) {
|
||||||
length = s->w_size;
|
if (wrap == 0) { /* already empty otherwise */
|
||||||
dictionary += dictLength - length; /* use the tail of the dictionary */
|
CLEAR_HASH(s);
|
||||||
|
s->strstart = 0;
|
||||||
|
s->block_start = 0L;
|
||||||
|
s->insert = 0;
|
||||||
|
}
|
||||||
|
dictionary += dictLength - s->w_size; /* use the tail */
|
||||||
|
dictLength = s->w_size;
|
||||||
}
|
}
|
||||||
zmemcpy(s->window, dictionary, length);
|
|
||||||
s->strstart = length;
|
|
||||||
s->block_start = (long)length;
|
|
||||||
|
|
||||||
/* Insert all strings in the hash table (except for the last two bytes).
|
/* insert dictionary into window and hash */
|
||||||
* s->lookahead stays null, so s->ins_h will be recomputed at the next
|
avail = strm->avail_in;
|
||||||
* call of fill_window.
|
next = strm->next_in;
|
||||||
*/
|
strm->avail_in = dictLength;
|
||||||
s->ins_h = s->window[0];
|
strm->next_in = (Bytef *)dictionary;
|
||||||
UPDATE_HASH(s, s->ins_h, s->window[1]);
|
fill_window(s);
|
||||||
for (n = 0; n <= length - MIN_MATCH; n++) {
|
while (s->lookahead >= MIN_MATCH) {
|
||||||
INSERT_STRING(s, n, hash_head);
|
str = s->strstart;
|
||||||
|
n = s->lookahead - (MIN_MATCH-1);
|
||||||
|
do {
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||||
|
#ifndef FASTEST
|
||||||
|
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||||
|
#endif
|
||||||
|
s->head[s->ins_h] = (Pos)str;
|
||||||
|
str++;
|
||||||
|
} while (--n);
|
||||||
|
s->strstart = str;
|
||||||
|
s->lookahead = MIN_MATCH-1;
|
||||||
|
fill_window(s);
|
||||||
}
|
}
|
||||||
if (hash_head) hash_head = 0; /* to make compiler happy */
|
s->strstart += s->lookahead;
|
||||||
|
s->block_start = (long)s->strstart;
|
||||||
|
s->insert = s->lookahead;
|
||||||
|
s->lookahead = 0;
|
||||||
|
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||||
|
s->match_available = 0;
|
||||||
|
strm->next_in = next;
|
||||||
|
strm->avail_in = avail;
|
||||||
|
s->wrap = wrap;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflateReset (strm)
|
int ZEXPORT deflateResetKeep (strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
|
@ -380,11 +419,22 @@ int ZEXPORT deflateReset (strm)
|
||||||
s->last_flush = Z_NO_FLUSH;
|
s->last_flush = Z_NO_FLUSH;
|
||||||
|
|
||||||
_tr_init(s);
|
_tr_init(s);
|
||||||
lm_init(s);
|
|
||||||
|
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
int ZEXPORT deflateReset (strm)
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = deflateResetKeep(strm);
|
||||||
|
if (ret == Z_OK)
|
||||||
|
lm_init(strm->state);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflateSetHeader (strm, head)
|
int ZEXPORT deflateSetHeader (strm, head)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
|
@ -396,15 +446,43 @@ int ZEXPORT deflateSetHeader (strm, head)
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
int ZEXPORT deflatePending (strm, pending, bits)
|
||||||
|
unsigned *pending;
|
||||||
|
int *bits;
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
if (pending != Z_NULL)
|
||||||
|
*pending = strm->state->pending;
|
||||||
|
if (bits != Z_NULL)
|
||||||
|
*bits = strm->state->bi_valid;
|
||||||
|
return Z_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
int ZEXPORT deflatePrime (strm, bits, value)
|
int ZEXPORT deflatePrime (strm, bits, value)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
int bits;
|
int bits;
|
||||||
int value;
|
int value;
|
||||||
{
|
{
|
||||||
|
deflate_state *s;
|
||||||
|
int put;
|
||||||
|
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
strm->state->bi_valid = bits;
|
s = strm->state;
|
||||||
strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
|
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
|
||||||
|
return Z_BUF_ERROR;
|
||||||
|
do {
|
||||||
|
put = Buf_size - s->bi_valid;
|
||||||
|
if (put > bits)
|
||||||
|
put = bits;
|
||||||
|
s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
|
||||||
|
s->bi_valid += put;
|
||||||
|
_tr_flush_bits(s);
|
||||||
|
value >>= put;
|
||||||
|
bits -= put;
|
||||||
|
} while (bits);
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,19 +640,22 @@ local void putShortMSB (s, b)
|
||||||
local void flush_pending(strm)
|
local void flush_pending(strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
unsigned len = strm->state->pending;
|
unsigned len;
|
||||||
|
deflate_state *s = strm->state;
|
||||||
|
|
||||||
|
_tr_flush_bits(s);
|
||||||
|
len = s->pending;
|
||||||
if (len > strm->avail_out) len = strm->avail_out;
|
if (len > strm->avail_out) len = strm->avail_out;
|
||||||
if (len == 0) return;
|
if (len == 0) return;
|
||||||
|
|
||||||
zmemcpy(strm->next_out, strm->state->pending_out, len);
|
zmemcpy(strm->next_out, s->pending_out, len);
|
||||||
strm->next_out += len;
|
strm->next_out += len;
|
||||||
strm->state->pending_out += len;
|
s->pending_out += len;
|
||||||
strm->total_out += len;
|
strm->total_out += len;
|
||||||
strm->avail_out -= len;
|
strm->avail_out -= len;
|
||||||
strm->state->pending -= len;
|
s->pending -= len;
|
||||||
if (strm->state->pending == 0) {
|
if (s->pending == 0) {
|
||||||
strm->state->pending_out = strm->state->pending_buf;
|
s->pending_out = s->pending_buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -801,7 +882,7 @@ int ZEXPORT deflate (strm, flush)
|
||||||
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
* flushes. For repeated and useless calls with Z_FINISH, we keep
|
||||||
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
* returning Z_STREAM_END instead of Z_BUF_ERROR.
|
||||||
*/
|
*/
|
||||||
} else if (strm->avail_in == 0 && flush <= old_flush &&
|
} else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
|
||||||
flush != Z_FINISH) {
|
flush != Z_FINISH) {
|
||||||
ERR_RETURN(strm, Z_BUF_ERROR);
|
ERR_RETURN(strm, Z_BUF_ERROR);
|
||||||
}
|
}
|
||||||
|
@ -850,6 +931,7 @@ int ZEXPORT deflate (strm, flush)
|
||||||
if (s->lookahead == 0) {
|
if (s->lookahead == 0) {
|
||||||
s->strstart = 0;
|
s->strstart = 0;
|
||||||
s->block_start = 0L;
|
s->block_start = 0L;
|
||||||
|
s->insert = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,12 +1027,12 @@ int ZEXPORT deflateCopy (dest, source)
|
||||||
|
|
||||||
ss = source->state;
|
ss = source->state;
|
||||||
|
|
||||||
zmemcpy(dest, source, sizeof(z_stream));
|
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||||
|
|
||||||
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
|
||||||
if (ds == Z_NULL) return Z_MEM_ERROR;
|
if (ds == Z_NULL) return Z_MEM_ERROR;
|
||||||
dest->state = (struct internal_state FAR *) ds;
|
dest->state = (struct internal_state FAR *) ds;
|
||||||
zmemcpy(ds, ss, sizeof(deflate_state));
|
zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
|
||||||
ds->strm = dest;
|
ds->strm = dest;
|
||||||
|
|
||||||
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
|
||||||
|
@ -966,8 +1048,8 @@ int ZEXPORT deflateCopy (dest, source)
|
||||||
}
|
}
|
||||||
/* following zmemcpy do not work for 16-bit MSDOS */
|
/* following zmemcpy do not work for 16-bit MSDOS */
|
||||||
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
|
||||||
zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
|
zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
|
||||||
zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
|
zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
|
||||||
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
|
||||||
|
|
||||||
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
|
||||||
|
@ -1001,15 +1083,15 @@ local int read_buf(strm, buf, size)
|
||||||
|
|
||||||
strm->avail_in -= len;
|
strm->avail_in -= len;
|
||||||
|
|
||||||
|
zmemcpy(buf, strm->next_in, len);
|
||||||
if (strm->state->wrap == 1) {
|
if (strm->state->wrap == 1) {
|
||||||
strm->adler = adler32(strm->adler, strm->next_in, len);
|
strm->adler = adler32(strm->adler, buf, len);
|
||||||
}
|
}
|
||||||
#ifdef GZIP
|
#ifdef GZIP
|
||||||
else if (strm->state->wrap == 2) {
|
else if (strm->state->wrap == 2) {
|
||||||
strm->adler = crc32(strm->adler, strm->next_in, len);
|
strm->adler = crc32(strm->adler, buf, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
zmemcpy(buf, strm->next_in, len);
|
|
||||||
strm->next_in += len;
|
strm->next_in += len;
|
||||||
strm->total_in += len;
|
strm->total_in += len;
|
||||||
|
|
||||||
|
@ -1036,6 +1118,7 @@ local void lm_init (s)
|
||||||
s->strstart = 0;
|
s->strstart = 0;
|
||||||
s->block_start = 0L;
|
s->block_start = 0L;
|
||||||
s->lookahead = 0;
|
s->lookahead = 0;
|
||||||
|
s->insert = 0;
|
||||||
s->match_length = s->prev_length = MIN_MATCH-1;
|
s->match_length = s->prev_length = MIN_MATCH-1;
|
||||||
s->match_available = 0;
|
s->match_available = 0;
|
||||||
s->ins_h = 0;
|
s->ins_h = 0;
|
||||||
|
@ -1310,6 +1393,8 @@ local void fill_window(s)
|
||||||
unsigned more; /* Amount of free space at the end of the window. */
|
unsigned more; /* Amount of free space at the end of the window. */
|
||||||
uInt wsize = s->w_size;
|
uInt wsize = s->w_size;
|
||||||
|
|
||||||
|
Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
|
||||||
|
|
||||||
do {
|
do {
|
||||||
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
|
||||||
|
|
||||||
|
@ -1362,7 +1447,7 @@ local void fill_window(s)
|
||||||
#endif
|
#endif
|
||||||
more += wsize;
|
more += wsize;
|
||||||
}
|
}
|
||||||
if (s->strm->avail_in == 0) return;
|
if (s->strm->avail_in == 0) break;
|
||||||
|
|
||||||
/* If there was no sliding:
|
/* If there was no sliding:
|
||||||
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
* strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
|
||||||
|
@ -1381,12 +1466,24 @@ local void fill_window(s)
|
||||||
s->lookahead += n;
|
s->lookahead += n;
|
||||||
|
|
||||||
/* Initialize the hash value now that we have some input: */
|
/* Initialize the hash value now that we have some input: */
|
||||||
if (s->lookahead >= MIN_MATCH) {
|
if (s->lookahead + s->insert >= MIN_MATCH) {
|
||||||
s->ins_h = s->window[s->strstart];
|
uInt str = s->strstart - s->insert;
|
||||||
UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
|
s->ins_h = s->window[str];
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
|
||||||
#if MIN_MATCH != 3
|
#if MIN_MATCH != 3
|
||||||
Call UPDATE_HASH() MIN_MATCH-3 more times
|
Call UPDATE_HASH() MIN_MATCH-3 more times
|
||||||
#endif
|
#endif
|
||||||
|
while (s->insert) {
|
||||||
|
UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
|
||||||
|
#ifndef FASTEST
|
||||||
|
s->prev[str & s->w_mask] = s->head[s->ins_h];
|
||||||
|
#endif
|
||||||
|
s->head[s->ins_h] = (Pos)str;
|
||||||
|
str++;
|
||||||
|
s->insert--;
|
||||||
|
if (s->lookahead + s->insert < MIN_MATCH)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
/* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
|
||||||
* but this is not important since only literal bytes will be emitted.
|
* but this is not important since only literal bytes will be emitted.
|
||||||
|
@ -1427,6 +1524,9 @@ local void fill_window(s)
|
||||||
s->high_water += init;
|
s->high_water += init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
|
||||||
|
"not enough room for search");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1506,8 +1606,14 @@ local block_state deflate_stored(s, flush)
|
||||||
FLUSH_BLOCK(s, 0);
|
FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if ((long)s->strstart > s->block_start)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1603,8 +1709,14 @@ local block_state deflate_fast(s, flush)
|
||||||
}
|
}
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef FASTEST
|
#ifndef FASTEST
|
||||||
|
@ -1728,8 +1840,14 @@ local block_state deflate_slow(s, flush)
|
||||||
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
_tr_tally_lit(s, s->window[s->strstart-1], bflush);
|
||||||
s->match_available = 0;
|
s->match_available = 0;
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
#endif /* FASTEST */
|
#endif /* FASTEST */
|
||||||
|
|
||||||
|
@ -1749,11 +1867,11 @@ local block_state deflate_rle(s, flush)
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* Make sure that we always have enough lookahead, except
|
/* Make sure that we always have enough lookahead, except
|
||||||
* at the end of the input file. We need MAX_MATCH bytes
|
* at the end of the input file. We need MAX_MATCH bytes
|
||||||
* for the longest encodable run.
|
* for the longest run, plus one for the unrolled loop.
|
||||||
*/
|
*/
|
||||||
if (s->lookahead < MAX_MATCH) {
|
if (s->lookahead <= MAX_MATCH) {
|
||||||
fill_window(s);
|
fill_window(s);
|
||||||
if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
|
if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
|
||||||
return need_more;
|
return need_more;
|
||||||
}
|
}
|
||||||
if (s->lookahead == 0) break; /* flush the current block */
|
if (s->lookahead == 0) break; /* flush the current block */
|
||||||
|
@ -1776,6 +1894,7 @@ local block_state deflate_rle(s, flush)
|
||||||
if (s->match_length > s->lookahead)
|
if (s->match_length > s->lookahead)
|
||||||
s->match_length = s->lookahead;
|
s->match_length = s->lookahead;
|
||||||
}
|
}
|
||||||
|
Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
/* Emit match if have run of MIN_MATCH or longer, else emit literal */
|
||||||
|
@ -1796,8 +1915,14 @@ local block_state deflate_rle(s, flush)
|
||||||
}
|
}
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1829,6 +1954,12 @@ local block_state deflate_huff(s, flush)
|
||||||
s->strstart++;
|
s->strstart++;
|
||||||
if (bflush) FLUSH_BLOCK(s, 0);
|
if (bflush) FLUSH_BLOCK(s, 0);
|
||||||
}
|
}
|
||||||
FLUSH_BLOCK(s, flush == Z_FINISH);
|
s->insert = 0;
|
||||||
return flush == Z_FINISH ? finish_done : block_done;
|
if (flush == Z_FINISH) {
|
||||||
|
FLUSH_BLOCK(s, 1);
|
||||||
|
return finish_done;
|
||||||
|
}
|
||||||
|
if (s->last_lit)
|
||||||
|
FLUSH_BLOCK(s, 0);
|
||||||
|
return block_done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* deflate.h -- internal compression state
|
/* deflate.h -- internal compression state
|
||||||
* Copyright (C) 1995-2009 Jean-loup Gailly
|
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -48,6 +48,9 @@
|
||||||
#define MAX_BITS 15
|
#define MAX_BITS 15
|
||||||
/* All codes must not exceed MAX_BITS bits */
|
/* All codes must not exceed MAX_BITS bits */
|
||||||
|
|
||||||
|
#define Buf_size 16
|
||||||
|
/* size of bit buffer in bi_buf */
|
||||||
|
|
||||||
#define INIT_STATE 42
|
#define INIT_STATE 42
|
||||||
#define EXTRA_STATE 69
|
#define EXTRA_STATE 69
|
||||||
#define NAME_STATE 73
|
#define NAME_STATE 73
|
||||||
|
@ -188,7 +191,7 @@ typedef struct internal_state {
|
||||||
int nice_match; /* Stop searching when current match exceeds this */
|
int nice_match; /* Stop searching when current match exceeds this */
|
||||||
|
|
||||||
/* used by trees.c: */
|
/* used by trees.c: */
|
||||||
/* Didn't use ct_data typedef below to supress compiler warning */
|
/* Didn't use ct_data typedef below to suppress compiler warning */
|
||||||
struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
|
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 dyn_dtree[2*D_CODES+1]; /* distance tree */
|
||||||
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
|
||||||
|
@ -244,7 +247,7 @@ typedef struct internal_state {
|
||||||
ulg opt_len; /* bit length of current block with optimal trees */
|
ulg opt_len; /* bit length of current block with optimal trees */
|
||||||
ulg static_len; /* bit length of current block with static trees */
|
ulg static_len; /* bit length of current block with static trees */
|
||||||
uInt matches; /* number of string matches in current block */
|
uInt matches; /* number of string matches in current block */
|
||||||
int last_eob_len; /* bit length of EOB code for last block */
|
uInt insert; /* bytes at end of window left to insert */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
ulg compressed_len; /* total bit length of compressed file mod 2^32 */
|
||||||
|
@ -290,13 +293,14 @@ typedef struct internal_state {
|
||||||
memory checker errors from longest match routines */
|
memory checker errors from longest match routines */
|
||||||
|
|
||||||
/* in trees.c */
|
/* in trees.c */
|
||||||
void _tr_init OF((deflate_state *s));
|
void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
|
||||||
int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
|
||||||
void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
|
||||||
int last));
|
ulg stored_len, int last));
|
||||||
void _tr_align OF((deflate_state *s));
|
void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
|
||||||
void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
|
||||||
int last));
|
void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
|
||||||
|
ulg stored_len, int last));
|
||||||
|
|
||||||
#define d_code(dist) \
|
#define d_code(dist) \
|
||||||
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
|
||||||
|
@ -309,11 +313,11 @@ void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
|
||||||
/* Inline versions of _tr_tally for speed: */
|
/* Inline versions of _tr_tally for speed: */
|
||||||
|
|
||||||
#if defined(GEN_TREES_H) || !defined(STDC)
|
#if defined(GEN_TREES_H) || !defined(STDC)
|
||||||
extern uch _length_code[];
|
extern uch ZLIB_INTERNAL _length_code[];
|
||||||
extern uch _dist_code[];
|
extern uch ZLIB_INTERNAL _dist_code[];
|
||||||
#else
|
#else
|
||||||
extern const uch _length_code[];
|
extern const uch ZLIB_INTERNAL _length_code[];
|
||||||
extern const uch _dist_code[];
|
extern const uch ZLIB_INTERNAL _dist_code[];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
# define _tr_tally_lit(s, c, flush) \
|
# define _tr_tally_lit(s, c, flush) \
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
/* gzguts.h -- zlib internal header definitions for gz* operations
|
/* gzguts.h -- zlib internal header definitions for gz* operations
|
||||||
* Copyright (C) 2004, 2005, 2010 Mark Adler
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
#ifdef _LARGEFILE64_SOURCE
|
||||||
# ifndef _LARGEFILE_SOURCE
|
# ifndef _LARGEFILE_SOURCE
|
||||||
# define _LARGEFILE_SOURCE
|
# define _LARGEFILE_SOURCE 1
|
||||||
# endif
|
# endif
|
||||||
# ifdef _FILE_OFFSET_BITS
|
# ifdef _FILE_OFFSET_BITS
|
||||||
# undef _FILE_OFFSET_BITS
|
# undef _FILE_OFFSET_BITS
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZLIB_INTERNAL
|
#ifdef HAVE_HIDDEN
|
||||||
|
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||||
|
#else
|
||||||
|
# define ZLIB_INTERNAL
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
@ -23,13 +27,65 @@
|
||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <stddef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
|
||||||
|
# include <io.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef NO_DEFLATE /* for compatibility with old definition */
|
#ifdef NO_DEFLATE /* for compatibility with old definition */
|
||||||
# define NO_GZCOMPRESS
|
# define NO_GZCOMPRESS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
||||||
# include <io.h>
|
# ifndef HAVE_VSNPRINTF
|
||||||
# define vsnprintf _vsnprintf
|
# define HAVE_VSNPRINTF
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__CYGWIN__)
|
||||||
|
# ifndef HAVE_VSNPRINTF
|
||||||
|
# define HAVE_VSNPRINTF
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
|
||||||
|
# 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)
|
||||||
|
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
||||||
|
# define vsnprintf _vsnprintf
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# ifdef __SASC
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef VMS
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef __OS400__
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
|
# ifdef __MVS__
|
||||||
|
# define NO_vsnprintf
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef local
|
#ifndef local
|
||||||
|
@ -44,11 +100,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* get errno and strerror definition */
|
/* get errno and strerror definition */
|
||||||
#if defined UNDER_CE && defined NO_ERRNO_H
|
#if defined UNDER_CE
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
|
# define zstrerror() gz_strwinerror((DWORD)GetLastError())
|
||||||
#else
|
#else
|
||||||
# ifdef STDC
|
# ifndef NO_STRERROR
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
# define zstrerror() strerror(errno)
|
# define zstrerror() strerror(errno)
|
||||||
# else
|
# else
|
||||||
|
@ -56,16 +112,19 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MVS fdopen() */
|
/* provide prototypes for these when building zlib without LFS */
|
||||||
#ifdef __MVS__
|
#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
|
||||||
#pragma map (fdopen , "\174\174FDOPEN")
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
FILE *fdopen(int, const char *);
|
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
/* default memLevel */
|
||||||
# define z_off64_t off64_t
|
#if MAX_MEM_LEVEL >= 8
|
||||||
|
# define DEF_MEM_LEVEL 8
|
||||||
#else
|
#else
|
||||||
# define z_off64_t z_off_t
|
# define DEF_MEM_LEVEL MAX_MEM_LEVEL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* default i/o buffer size -- double this for output when reading */
|
/* default i/o buffer size -- double this for output when reading */
|
||||||
|
@ -84,23 +143,25 @@
|
||||||
|
|
||||||
/* internal gzip file state data structure */
|
/* internal gzip file state data structure */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
/* exposed contents for gzgetc() macro */
|
||||||
|
struct gzFile_s x; /* "x" for exposed */
|
||||||
|
/* x.have: number of bytes available at x.next */
|
||||||
|
/* x.next: next output data to deliver or write */
|
||||||
|
/* x.pos: current position in uncompressed data */
|
||||||
/* used for both reading and writing */
|
/* used for both reading and writing */
|
||||||
int mode; /* see gzip modes above */
|
int mode; /* see gzip modes above */
|
||||||
int fd; /* file descriptor */
|
int fd; /* file descriptor */
|
||||||
char *path; /* path or fd for error messages */
|
char *path; /* path or fd for error messages */
|
||||||
z_off64_t pos; /* current position in uncompressed data */
|
|
||||||
unsigned size; /* buffer size, zero if not allocated yet */
|
unsigned size; /* buffer size, zero if not allocated yet */
|
||||||
unsigned want; /* requested buffer size, default is GZBUFSIZE */
|
unsigned want; /* requested buffer size, default is GZBUFSIZE */
|
||||||
unsigned char *in; /* input buffer */
|
unsigned char *in; /* input buffer */
|
||||||
unsigned char *out; /* output buffer (double-sized when reading) */
|
unsigned char *out; /* output buffer (double-sized when reading) */
|
||||||
unsigned char *next; /* next output data to deliver or write */
|
int direct; /* 0 if processing gzip, 1 if transparent */
|
||||||
/* just for reading */
|
/* just for reading */
|
||||||
unsigned have; /* amount of output data unused at next */
|
|
||||||
int eof; /* true if end of input file reached */
|
|
||||||
z_off64_t start; /* where the gzip data started, for rewinding */
|
|
||||||
z_off64_t raw; /* where the raw data started, for seeking */
|
|
||||||
int how; /* 0: get header, 1: copy, 2: decompress */
|
int how; /* 0: get header, 1: copy, 2: decompress */
|
||||||
int direct; /* true if last read direct, false if gzip */
|
z_off64_t start; /* where the gzip data started, for rewinding */
|
||||||
|
int eof; /* true if end of input file reached */
|
||||||
|
int past; /* true if read requested past end */
|
||||||
/* just for writing */
|
/* just for writing */
|
||||||
int level; /* compression level */
|
int level; /* compression level */
|
||||||
int strategy; /* compression strategy */
|
int strategy; /* compression strategy */
|
||||||
|
@ -116,9 +177,9 @@ typedef struct {
|
||||||
typedef gz_state FAR *gz_statep;
|
typedef gz_state FAR *gz_statep;
|
||||||
|
|
||||||
/* shared functions */
|
/* shared functions */
|
||||||
ZEXTERN void ZEXPORT gz_error OF((gz_statep, int, const char *));
|
void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
|
||||||
#if defined UNDER_CE && defined NO_ERRNO_H
|
#if defined UNDER_CE
|
||||||
ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
|
char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
|
/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
|
||||||
|
@ -127,6 +188,6 @@ ZEXTERN char ZEXPORT *gz_strwinerror OF((DWORD error));
|
||||||
#ifdef INT_MAX
|
#ifdef INT_MAX
|
||||||
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
|
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
|
||||||
#else
|
#else
|
||||||
ZEXTERN unsigned ZEXPORT gz_intmax OF((void));
|
unsigned ZLIB_INTERNAL gz_intmax OF((void));
|
||||||
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
|
# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||||||
* Copyright (C) 2004, 2010 Mark Adler
|
* Copyright (C) 2004, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "gzguts.h"
|
#include "gzguts.h"
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
#if defined(_WIN32) && !defined(__BORLANDC__)
|
||||||
|
# define LSEEK _lseeki64
|
||||||
|
#else
|
||||||
|
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
|
||||||
# define LSEEK lseek64
|
# define LSEEK lseek64
|
||||||
#else
|
#else
|
||||||
# define LSEEK lseek
|
# define LSEEK lseek
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
local void gz_reset OF((gz_statep));
|
local void gz_reset OF((gz_statep));
|
||||||
local gzFile gz_open OF((const char *, int, const char *));
|
local gzFile gz_open OF((const void *, int, const char *));
|
||||||
|
|
||||||
#if defined UNDER_CE && defined NO_ERRNO_H
|
#if defined UNDER_CE
|
||||||
|
|
||||||
/* Map the Windows error number in ERROR to a locale-dependent error message
|
/* Map the Windows error number in ERROR to a locale-dependent error message
|
||||||
string and return a pointer to it. Typically, the values for ERROR come
|
string and return a pointer to it. Typically, the values for ERROR come
|
||||||
|
@ -26,7 +30,7 @@ local gzFile gz_open OF((const char *, int, const char *));
|
||||||
|
|
||||||
The gz_strwinerror function does not change the current setting of
|
The gz_strwinerror function does not change the current setting of
|
||||||
GetLastError. */
|
GetLastError. */
|
||||||
char ZEXPORT *gz_strwinerror (error)
|
char ZLIB_INTERNAL *gz_strwinerror (error)
|
||||||
DWORD error;
|
DWORD error;
|
||||||
{
|
{
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
|
@ -65,31 +69,43 @@ char ZEXPORT *gz_strwinerror (error)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* UNDER_CE && NO_ERRNO_H */
|
#endif /* UNDER_CE */
|
||||||
|
|
||||||
/* Reset gzip file state */
|
/* Reset gzip file state */
|
||||||
local void gz_reset(state)
|
local void gz_reset(state)
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
{
|
{
|
||||||
|
state->x.have = 0; /* no output data available */
|
||||||
if (state->mode == GZ_READ) { /* for reading ... */
|
if (state->mode == GZ_READ) { /* for reading ... */
|
||||||
state->have = 0; /* no output data available */
|
|
||||||
state->eof = 0; /* not at end of file */
|
state->eof = 0; /* not at end of file */
|
||||||
|
state->past = 0; /* have not read past end yet */
|
||||||
state->how = LOOK; /* look for gzip header */
|
state->how = LOOK; /* look for gzip header */
|
||||||
state->direct = 1; /* default for empty file */
|
|
||||||
}
|
}
|
||||||
state->seek = 0; /* no seek request pending */
|
state->seek = 0; /* no seek request pending */
|
||||||
gz_error(state, Z_OK, NULL); /* clear error */
|
gz_error(state, Z_OK, NULL); /* clear error */
|
||||||
state->pos = 0; /* no uncompressed data yet */
|
state->x.pos = 0; /* no uncompressed data yet */
|
||||||
state->strm.avail_in = 0; /* no input data yet */
|
state->strm.avail_in = 0; /* no input data yet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a gzip file either by name or file descriptor. */
|
/* Open a gzip file either by name or file descriptor. */
|
||||||
local gzFile gz_open(path, fd, mode)
|
local gzFile gz_open(path, fd, mode)
|
||||||
const char *path;
|
const void *path;
|
||||||
int fd;
|
int fd;
|
||||||
const char *mode;
|
const char *mode;
|
||||||
{
|
{
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
|
size_t len;
|
||||||
|
int oflag;
|
||||||
|
#ifdef O_CLOEXEC
|
||||||
|
int cloexec = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef O_EXCL
|
||||||
|
int exclusive = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check input */
|
||||||
|
if (path == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/* allocate gzFile structure to return */
|
/* allocate gzFile structure to return */
|
||||||
state = malloc(sizeof(gz_state));
|
state = malloc(sizeof(gz_state));
|
||||||
|
@ -103,6 +119,7 @@ local gzFile gz_open(path, fd, mode)
|
||||||
state->mode = GZ_NONE;
|
state->mode = GZ_NONE;
|
||||||
state->level = Z_DEFAULT_COMPRESSION;
|
state->level = Z_DEFAULT_COMPRESSION;
|
||||||
state->strategy = Z_DEFAULT_STRATEGY;
|
state->strategy = Z_DEFAULT_STRATEGY;
|
||||||
|
state->direct = 0;
|
||||||
while (*mode) {
|
while (*mode) {
|
||||||
if (*mode >= '0' && *mode <= '9')
|
if (*mode >= '0' && *mode <= '9')
|
||||||
state->level = *mode - '0';
|
state->level = *mode - '0';
|
||||||
|
@ -124,6 +141,16 @@ local gzFile gz_open(path, fd, mode)
|
||||||
return NULL;
|
return NULL;
|
||||||
case 'b': /* ignore -- will request binary anyway */
|
case 'b': /* ignore -- will request binary anyway */
|
||||||
break;
|
break;
|
||||||
|
#ifdef O_CLOEXEC
|
||||||
|
case 'e':
|
||||||
|
cloexec = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef O_EXCL
|
||||||
|
case 'x':
|
||||||
|
exclusive = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 'f':
|
case 'f':
|
||||||
state->strategy = Z_FILTERED;
|
state->strategy = Z_FILTERED;
|
||||||
break;
|
break;
|
||||||
|
@ -135,6 +162,8 @@ local gzFile gz_open(path, fd, mode)
|
||||||
break;
|
break;
|
||||||
case 'F':
|
case 'F':
|
||||||
state->strategy = Z_FIXED;
|
state->strategy = Z_FIXED;
|
||||||
|
case 'T':
|
||||||
|
state->direct = 1;
|
||||||
default: /* could consider as an error, but just ignore */
|
default: /* could consider as an error, but just ignore */
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -147,31 +176,69 @@ local gzFile gz_open(path, fd, mode)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* can't force transparent read */
|
||||||
|
if (state->mode == GZ_READ) {
|
||||||
|
if (state->direct) {
|
||||||
|
free(state);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state->direct = 1; /* for empty file */
|
||||||
|
}
|
||||||
|
|
||||||
/* save the path name for error messages */
|
/* save the path name for error messages */
|
||||||
state->path = malloc(strlen(path) + 1);
|
#ifdef _WIN32
|
||||||
|
if (fd == -2) {
|
||||||
|
len = wcstombs(NULL, path, 0);
|
||||||
|
if (len == (size_t)-1)
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
len = strlen(path);
|
||||||
|
state->path = malloc(len + 1);
|
||||||
if (state->path == NULL) {
|
if (state->path == NULL) {
|
||||||
free(state);
|
free(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(state->path, path);
|
#ifdef _WIN32
|
||||||
|
if (fd == -2)
|
||||||
|
if (len)
|
||||||
|
wcstombs(state->path, path, len + 1);
|
||||||
|
else
|
||||||
|
*(state->path) = 0;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
strcpy(state->path, path);
|
||||||
|
|
||||||
/* open the file with the appropriate mode (or just use fd) */
|
/* compute the flags for open() */
|
||||||
state->fd = fd != -1 ? fd :
|
oflag =
|
||||||
open(path,
|
|
||||||
#ifdef O_LARGEFILE
|
#ifdef O_LARGEFILE
|
||||||
O_LARGEFILE |
|
O_LARGEFILE |
|
||||||
#endif
|
#endif
|
||||||
#ifdef O_BINARY
|
#ifdef O_BINARY
|
||||||
O_BINARY |
|
O_BINARY |
|
||||||
#endif
|
#endif
|
||||||
(state->mode == GZ_READ ?
|
#ifdef O_CLOEXEC
|
||||||
O_RDONLY :
|
(cloexec ? O_CLOEXEC : 0) |
|
||||||
(O_WRONLY | O_CREAT | (
|
#endif
|
||||||
state->mode == GZ_WRITE ?
|
(state->mode == GZ_READ ?
|
||||||
O_TRUNC :
|
O_RDONLY :
|
||||||
O_APPEND))),
|
(O_WRONLY | O_CREAT |
|
||||||
0666);
|
#ifdef O_EXCL
|
||||||
|
(exclusive ? O_EXCL : 0) |
|
||||||
|
#endif
|
||||||
|
(state->mode == GZ_WRITE ?
|
||||||
|
O_TRUNC :
|
||||||
|
O_APPEND)));
|
||||||
|
|
||||||
|
/* open the file with the appropriate flags (or just use fd) */
|
||||||
|
state->fd = fd > -1 ? fd : (
|
||||||
|
#ifdef _WIN32
|
||||||
|
fd == -2 ? _wopen(path, oflag, 0666) :
|
||||||
|
#endif
|
||||||
|
open(path, oflag, 0666));
|
||||||
if (state->fd == -1) {
|
if (state->fd == -1) {
|
||||||
|
free(state->path);
|
||||||
free(state);
|
free(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -217,12 +284,22 @@ gzFile ZEXPORT gzdopen(fd, mode)
|
||||||
|
|
||||||
if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
|
if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
sprintf(path, "<fd:%d>", fd);
|
sprintf(path, "<fd:%d>", fd); /* for debugging */
|
||||||
gz = gz_open(path, fd, mode);
|
gz = gz_open(path, fd, mode);
|
||||||
free(path);
|
free(path);
|
||||||
return gz;
|
return gz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -- see zlib.h -- */
|
||||||
|
#ifdef _WIN32
|
||||||
|
gzFile ZEXPORT gzopen_w(path, mode)
|
||||||
|
const wchar_t *path;
|
||||||
|
const char *mode;
|
||||||
|
{
|
||||||
|
return gz_open(path, -2, mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
int ZEXPORT gzbuffer(file, size)
|
int ZEXPORT gzbuffer(file, size)
|
||||||
gzFile file;
|
gzFile file;
|
||||||
|
@ -242,8 +319,8 @@ int ZEXPORT gzbuffer(file, size)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* check and set requested size */
|
/* check and set requested size */
|
||||||
if (size == 0)
|
if (size < 2)
|
||||||
return -1;
|
size = 2; /* need two bytes to check magic header */
|
||||||
state->want = size;
|
state->want = size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -260,7 +337,8 @@ int ZEXPORT gzrewind(file)
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
|
|
||||||
/* check that we're reading and that there's no error */
|
/* check that we're reading and that there's no error */
|
||||||
if (state->mode != GZ_READ || state->err != Z_OK)
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* back up and start over */
|
/* back up and start over */
|
||||||
|
@ -288,7 +366,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* check that there's no error */
|
/* check that there's no error */
|
||||||
if (state->err != Z_OK)
|
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* can only seek from start or relative to current position */
|
/* can only seek from start or relative to current position */
|
||||||
|
@ -297,31 +375,32 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||||
|
|
||||||
/* normalize offset to a SEEK_CUR specification */
|
/* normalize offset to a SEEK_CUR specification */
|
||||||
if (whence == SEEK_SET)
|
if (whence == SEEK_SET)
|
||||||
offset -= state->pos;
|
offset -= state->x.pos;
|
||||||
else if (state->seek)
|
else if (state->seek)
|
||||||
offset += state->skip;
|
offset += state->skip;
|
||||||
state->seek = 0;
|
state->seek = 0;
|
||||||
|
|
||||||
/* if within raw area while reading, just go there */
|
/* if within raw area while reading, just go there */
|
||||||
if (state->mode == GZ_READ && state->how == COPY &&
|
if (state->mode == GZ_READ && state->how == COPY &&
|
||||||
state->pos + offset >= state->raw) {
|
state->x.pos + offset >= 0) {
|
||||||
ret = LSEEK(state->fd, offset, SEEK_CUR);
|
ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return -1;
|
return -1;
|
||||||
state->have = 0;
|
state->x.have = 0;
|
||||||
state->eof = 0;
|
state->eof = 0;
|
||||||
|
state->past = 0;
|
||||||
state->seek = 0;
|
state->seek = 0;
|
||||||
gz_error(state, Z_OK, NULL);
|
gz_error(state, Z_OK, NULL);
|
||||||
state->strm.avail_in = 0;
|
state->strm.avail_in = 0;
|
||||||
state->pos += offset;
|
state->x.pos += offset;
|
||||||
return state->pos;
|
return state->x.pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* calculate skip amount, rewinding if needed for back seek when reading */
|
/* calculate skip amount, rewinding if needed for back seek when reading */
|
||||||
if (offset < 0) {
|
if (offset < 0) {
|
||||||
if (state->mode != GZ_READ) /* writing -- can't go backwards */
|
if (state->mode != GZ_READ) /* writing -- can't go backwards */
|
||||||
return -1;
|
return -1;
|
||||||
offset += state->pos;
|
offset += state->x.pos;
|
||||||
if (offset < 0) /* before start of file! */
|
if (offset < 0) /* before start of file! */
|
||||||
return -1;
|
return -1;
|
||||||
if (gzrewind(file) == -1) /* rewind, then skip to offset */
|
if (gzrewind(file) == -1) /* rewind, then skip to offset */
|
||||||
|
@ -330,11 +409,11 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||||
|
|
||||||
/* if reading, skip what's in output buffer (one less gzgetc() check) */
|
/* if reading, skip what's in output buffer (one less gzgetc() check) */
|
||||||
if (state->mode == GZ_READ) {
|
if (state->mode == GZ_READ) {
|
||||||
n = GT_OFF(state->have) || (z_off64_t)state->have > offset ?
|
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
|
||||||
(unsigned)offset : state->have;
|
(unsigned)offset : state->x.have;
|
||||||
state->have -= n;
|
state->x.have -= n;
|
||||||
state->next += n;
|
state->x.next += n;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
offset -= n;
|
offset -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +422,7 @@ z_off64_t ZEXPORT gzseek64(file, offset, whence)
|
||||||
state->seek = 1;
|
state->seek = 1;
|
||||||
state->skip = offset;
|
state->skip = offset;
|
||||||
}
|
}
|
||||||
return state->pos + offset;
|
return state->x.pos + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
@ -372,7 +451,7 @@ z_off64_t ZEXPORT gztell64(file)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* return position */
|
/* return position */
|
||||||
return state->pos + (state->seek ? state->skip : 0);
|
return state->x.pos + (state->seek ? state->skip : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
@ -432,7 +511,7 @@ int ZEXPORT gzeof(file)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* return end-of-file state */
|
/* return end-of-file state */
|
||||||
return state->mode == GZ_READ ? (state->eof && state->have == 0) : 0;
|
return state->mode == GZ_READ ? state->past : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
@ -469,8 +548,10 @@ void ZEXPORT gzclearerr(file)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* clear error and end-of-file */
|
/* clear error and end-of-file */
|
||||||
if (state->mode == GZ_READ)
|
if (state->mode == GZ_READ) {
|
||||||
state->eof = 0;
|
state->eof = 0;
|
||||||
|
state->past = 0;
|
||||||
|
}
|
||||||
gz_error(state, Z_OK, NULL);
|
gz_error(state, Z_OK, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +561,7 @@ void ZEXPORT gzclearerr(file)
|
||||||
memory). Simply save the error message as a static string. If there is an
|
memory). Simply save the error message as a static string. If there is an
|
||||||
allocation failure constructing the error message, then convert the error to
|
allocation failure constructing the error message, then convert the error to
|
||||||
out of memory. */
|
out of memory. */
|
||||||
void ZEXPORT gz_error(state, err, msg)
|
void ZLIB_INTERNAL gz_error(state, err, msg)
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
int err;
|
int err;
|
||||||
const char *msg;
|
const char *msg;
|
||||||
|
@ -492,6 +573,10 @@ void ZEXPORT gz_error(state, err, msg)
|
||||||
state->msg = NULL;
|
state->msg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
|
||||||
|
if (err != Z_OK && err != Z_BUF_ERROR)
|
||||||
|
state->x.have = 0;
|
||||||
|
|
||||||
/* set error code, and if no message, then done */
|
/* set error code, and if no message, then done */
|
||||||
state->err = err;
|
state->err = err;
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
|
@ -520,7 +605,7 @@ void ZEXPORT gz_error(state, err, msg)
|
||||||
available) -- we need to do this to cover cases where 2's complement not
|
available) -- we need to do this to cover cases where 2's complement not
|
||||||
used, since C standard permits 1's complement and sign-bit representations,
|
used, since C standard permits 1's complement and sign-bit representations,
|
||||||
otherwise we could just use ((unsigned)-1) >> 1 */
|
otherwise we could just use ((unsigned)-1) >> 1 */
|
||||||
unsigned ZEXPORT gz_intmax()
|
unsigned ZLIB_INTERNAL gz_intmax()
|
||||||
{
|
{
|
||||||
unsigned p, q;
|
unsigned p, q;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* gzread.c -- zlib functions for reading gzip files
|
/* gzread.c -- zlib functions for reading gzip files
|
||||||
* Copyright (C) 2004, 2005, 2010 Mark Adler
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -8,10 +8,9 @@
|
||||||
/* Local functions */
|
/* Local functions */
|
||||||
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
|
local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
|
||||||
local int gz_avail OF((gz_statep));
|
local int gz_avail OF((gz_statep));
|
||||||
local int gz_next4 OF((gz_statep, unsigned long *));
|
local int gz_look OF((gz_statep));
|
||||||
local int gz_head OF((gz_statep));
|
|
||||||
local int gz_decomp OF((gz_statep));
|
local int gz_decomp OF((gz_statep));
|
||||||
local int gz_make OF((gz_statep));
|
local int gz_fetch OF((gz_statep));
|
||||||
local int gz_skip OF((gz_statep, z_off64_t));
|
local int gz_skip OF((gz_statep, z_off64_t));
|
||||||
|
|
||||||
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from
|
||||||
|
@ -46,66 +45,47 @@ local int gz_load(state, buf, len, have)
|
||||||
error, 0 otherwise. Note that the eof flag is set when the end of the input
|
error, 0 otherwise. Note that the eof flag is set when the end of the input
|
||||||
file is reached, even though there may be unused data in the buffer. Once
|
file is reached, even though there may be unused data in the buffer. Once
|
||||||
that data has been used, no more attempts will be made to read the file.
|
that data has been used, no more attempts will be made to read the file.
|
||||||
gz_avail() assumes that strm->avail_in == 0. */
|
If strm->avail_in != 0, then the current data is moved to the beginning of
|
||||||
|
the input buffer, and then the remainder of the buffer is loaded with the
|
||||||
|
available data from the input file. */
|
||||||
local int gz_avail(state)
|
local int gz_avail(state)
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
{
|
{
|
||||||
|
unsigned got;
|
||||||
z_streamp strm = &(state->strm);
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
if (state->err != Z_OK)
|
if (state->err != Z_OK && state->err != Z_BUF_ERROR)
|
||||||
return -1;
|
return -1;
|
||||||
if (state->eof == 0) {
|
if (state->eof == 0) {
|
||||||
if (gz_load(state, state->in, state->size, &(strm->avail_in)) == -1)
|
if (strm->avail_in) { /* copy what's there to the start */
|
||||||
|
unsigned char *p = state->in, *q = strm->next_in;
|
||||||
|
unsigned n = strm->avail_in;
|
||||||
|
do {
|
||||||
|
*p++ = *q++;
|
||||||
|
} while (--n);
|
||||||
|
}
|
||||||
|
if (gz_load(state, state->in + strm->avail_in,
|
||||||
|
state->size - strm->avail_in, &got) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
strm->avail_in += got;
|
||||||
strm->next_in = state->in;
|
strm->next_in = state->in;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get next byte from input, or -1 if end or error. */
|
/* Look for gzip header, set up for inflate or copy. state->x.have must be 0.
|
||||||
#define NEXT() ((strm->avail_in == 0 && gz_avail(state) == -1) ? -1 : \
|
|
||||||
(strm->avail_in == 0 ? -1 : \
|
|
||||||
(strm->avail_in--, *(strm->next_in)++)))
|
|
||||||
|
|
||||||
/* Get a four-byte little-endian integer and return 0 on success and the value
|
|
||||||
in *ret. Otherwise -1 is returned and *ret is not modified. */
|
|
||||||
local int gz_next4(state, ret)
|
|
||||||
gz_statep state;
|
|
||||||
unsigned long *ret;
|
|
||||||
{
|
|
||||||
int ch;
|
|
||||||
unsigned long val;
|
|
||||||
z_streamp strm = &(state->strm);
|
|
||||||
|
|
||||||
val = NEXT();
|
|
||||||
val += (unsigned)NEXT() << 8;
|
|
||||||
val += (unsigned long)NEXT() << 16;
|
|
||||||
ch = NEXT();
|
|
||||||
if (ch == -1)
|
|
||||||
return -1;
|
|
||||||
val += (unsigned long)ch << 24;
|
|
||||||
*ret = val;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for gzip header, set up for inflate or copy. state->have must be zero.
|
|
||||||
If this is the first time in, allocate required memory. state->how will be
|
If this is the first time in, allocate required memory. state->how will be
|
||||||
left unchanged if there is no more input data available, will be set to COPY
|
left unchanged if there is no more input data available, will be set to COPY
|
||||||
if there is no gzip header and direct copying will be performed, or it will
|
if there is no gzip header and direct copying will be performed, or it will
|
||||||
be set to GZIP for decompression, and the gzip header will be skipped so
|
be set to GZIP for decompression. If direct copying, then leftover input
|
||||||
that the next available input data is the raw deflate stream. If direct
|
data from the input buffer will be copied to the output buffer. In that
|
||||||
copying, then leftover input data from the input buffer will be copied to
|
case, all further file reads will be directly to either the output buffer or
|
||||||
the output buffer. In that case, all further file reads will be directly to
|
a user buffer. If decompressing, the inflate state will be initialized.
|
||||||
either the output buffer or a user buffer. If decompressing, the inflate
|
gz_look() will return 0 on success or -1 on failure. */
|
||||||
state and the check value will be initialized. gz_head() will return 0 on
|
local int gz_look(state)
|
||||||
success or -1 on failure. Failures may include read errors or gzip header
|
|
||||||
errors. */
|
|
||||||
local int gz_head(state)
|
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
{
|
{
|
||||||
z_streamp strm = &(state->strm);
|
z_streamp strm = &(state->strm);
|
||||||
int flags;
|
|
||||||
unsigned len;
|
|
||||||
|
|
||||||
/* allocate read buffers and inflate memory */
|
/* allocate read buffers and inflate memory */
|
||||||
if (state->size == 0) {
|
if (state->size == 0) {
|
||||||
|
@ -128,7 +108,7 @@ local int gz_head(state)
|
||||||
state->strm.opaque = Z_NULL;
|
state->strm.opaque = Z_NULL;
|
||||||
state->strm.avail_in = 0;
|
state->strm.avail_in = 0;
|
||||||
state->strm.next_in = Z_NULL;
|
state->strm.next_in = Z_NULL;
|
||||||
if (inflateInit2(&(state->strm), -15) != Z_OK) { /* raw inflate */
|
if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */
|
||||||
free(state->out);
|
free(state->out);
|
||||||
free(state->in);
|
free(state->in);
|
||||||
state->size = 0;
|
state->size = 0;
|
||||||
|
@ -137,83 +117,45 @@ local int gz_head(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get some data in the input buffer */
|
/* get at least the magic bytes in the input buffer */
|
||||||
if (strm->avail_in == 0) {
|
if (strm->avail_in < 2) {
|
||||||
if (gz_avail(state) == -1)
|
if (gz_avail(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (strm->avail_in == 0)
|
if (strm->avail_in == 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look for the gzip magic header bytes 31 and 139 */
|
/* look for gzip magic bytes -- if there, do gzip decoding (note: there is
|
||||||
if (strm->next_in[0] == 31) {
|
a logical dilemma here when considering the case of a partially written
|
||||||
strm->avail_in--;
|
gzip file, to wit, if a single 31 byte is written, then we cannot tell
|
||||||
strm->next_in++;
|
whether this is a single-byte file, or just a partially written gzip
|
||||||
if (strm->avail_in == 0 && gz_avail(state) == -1)
|
file -- for here we assume that if a gzip file is being written, then
|
||||||
return -1;
|
the header will be written in a single operation, so that reading a
|
||||||
if (strm->avail_in && strm->next_in[0] == 139) {
|
single byte is sufficient indication that it is not a gzip file) */
|
||||||
/* we have a gzip header, woo hoo! */
|
if (strm->avail_in > 1 &&
|
||||||
strm->avail_in--;
|
strm->next_in[0] == 31 && strm->next_in[1] == 139) {
|
||||||
strm->next_in++;
|
inflateReset(strm);
|
||||||
|
state->how = GZIP;
|
||||||
/* skip rest of header */
|
state->direct = 0;
|
||||||
if (NEXT() != 8) { /* compression method */
|
return 0;
|
||||||
gz_error(state, Z_DATA_ERROR, "unknown compression method");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
flags = NEXT();
|
|
||||||
if (flags & 0xe0) { /* reserved flag bits */
|
|
||||||
gz_error(state, Z_DATA_ERROR, "unknown header flags set");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
NEXT(); /* modification time */
|
|
||||||
NEXT();
|
|
||||||
NEXT();
|
|
||||||
NEXT();
|
|
||||||
NEXT(); /* extra flags */
|
|
||||||
NEXT(); /* operating system */
|
|
||||||
if (flags & 4) { /* extra field */
|
|
||||||
len = (unsigned)NEXT();
|
|
||||||
len += (unsigned)NEXT() << 8;
|
|
||||||
while (len--)
|
|
||||||
if (NEXT() < 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (flags & 8) /* file name */
|
|
||||||
while (NEXT() > 0)
|
|
||||||
;
|
|
||||||
if (flags & 16) /* comment */
|
|
||||||
while (NEXT() > 0)
|
|
||||||
;
|
|
||||||
if (flags & 2) { /* header crc */
|
|
||||||
NEXT();
|
|
||||||
NEXT();
|
|
||||||
}
|
|
||||||
/* an unexpected end of file is not checked for here -- it will be
|
|
||||||
noticed on the first request for uncompressed data */
|
|
||||||
|
|
||||||
/* set up for decompression */
|
|
||||||
inflateReset(strm);
|
|
||||||
strm->adler = crc32(0L, Z_NULL, 0);
|
|
||||||
state->how = GZIP;
|
|
||||||
state->direct = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* not a gzip file -- save first byte (31) and fall to raw i/o */
|
|
||||||
state->out[0] = 31;
|
|
||||||
state->have = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* doing raw i/o, save start of raw data for seeking, copy any leftover
|
/* no gzip header -- if we were decoding gzip before, then this is trailing
|
||||||
input to output -- this assumes that the output buffer is larger than
|
garbage. Ignore the trailing garbage and finish. */
|
||||||
the input buffer, which also assures space for gzungetc() */
|
if (state->direct == 0) {
|
||||||
state->raw = state->pos;
|
strm->avail_in = 0;
|
||||||
state->next = state->out;
|
state->eof = 1;
|
||||||
|
state->x.have = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* doing raw i/o, copy any leftover input to output -- this assumes that
|
||||||
|
the output buffer is larger than the input buffer, which also assures
|
||||||
|
space for gzungetc() */
|
||||||
|
state->x.next = state->out;
|
||||||
if (strm->avail_in) {
|
if (strm->avail_in) {
|
||||||
memcpy(state->next + state->have, strm->next_in, strm->avail_in);
|
memcpy(state->x.next, strm->next_in, strm->avail_in);
|
||||||
state->have += strm->avail_in;
|
state->x.have = strm->avail_in;
|
||||||
strm->avail_in = 0;
|
strm->avail_in = 0;
|
||||||
}
|
}
|
||||||
state->how = COPY;
|
state->how = COPY;
|
||||||
|
@ -222,19 +164,15 @@ local int gz_head(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Decompress from input to the provided next_out and avail_out in the state.
|
/* Decompress from input to the provided next_out and avail_out in the state.
|
||||||
If the end of the compressed data is reached, then verify the gzip trailer
|
On return, state->x.have and state->x.next point to the just decompressed
|
||||||
check value and length (modulo 2^32). state->have and state->next are set
|
data. If the gzip stream completes, state->how is reset to LOOK to look for
|
||||||
to point to the just decompressed data, and the crc is updated. If the
|
the next gzip stream or raw data, once state->x.have is depleted. Returns 0
|
||||||
trailer is verified, state->how is reset to LOOK to look for the next gzip
|
on success, -1 on failure. */
|
||||||
stream or raw data, once state->have is depleted. Returns 0 on success, -1
|
|
||||||
on failure. Failures may include invalid compressed data or a failed gzip
|
|
||||||
trailer verification. */
|
|
||||||
local int gz_decomp(state)
|
local int gz_decomp(state)
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = Z_OK;
|
||||||
unsigned had;
|
unsigned had;
|
||||||
unsigned long crc, len;
|
|
||||||
z_streamp strm = &(state->strm);
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
/* fill output buffer up to end of deflate stream */
|
/* fill output buffer up to end of deflate stream */
|
||||||
|
@ -244,15 +182,15 @@ local int gz_decomp(state)
|
||||||
if (strm->avail_in == 0 && gz_avail(state) == -1)
|
if (strm->avail_in == 0 && gz_avail(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (strm->avail_in == 0) {
|
if (strm->avail_in == 0) {
|
||||||
gz_error(state, Z_DATA_ERROR, "unexpected end of file");
|
gz_error(state, Z_BUF_ERROR, "unexpected end of file");
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decompress and handle errors */
|
/* decompress and handle errors */
|
||||||
ret = inflate(strm, Z_NO_FLUSH);
|
ret = inflate(strm, Z_NO_FLUSH);
|
||||||
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
|
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
|
||||||
gz_error(state, Z_STREAM_ERROR,
|
gz_error(state, Z_STREAM_ERROR,
|
||||||
"internal error: inflate stream corrupt");
|
"internal error: inflate stream corrupt");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ret == Z_MEM_ERROR) {
|
if (ret == Z_MEM_ERROR) {
|
||||||
|
@ -261,67 +199,55 @@ local int gz_decomp(state)
|
||||||
}
|
}
|
||||||
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
|
if (ret == Z_DATA_ERROR) { /* deflate stream invalid */
|
||||||
gz_error(state, Z_DATA_ERROR,
|
gz_error(state, Z_DATA_ERROR,
|
||||||
strm->msg == NULL ? "compressed data error" : strm->msg);
|
strm->msg == NULL ? "compressed data error" : strm->msg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (strm->avail_out && ret != Z_STREAM_END);
|
} while (strm->avail_out && ret != Z_STREAM_END);
|
||||||
|
|
||||||
/* update available output and crc check value */
|
/* update available output */
|
||||||
state->have = had - strm->avail_out;
|
state->x.have = had - strm->avail_out;
|
||||||
state->next = strm->next_out - state->have;
|
state->x.next = strm->next_out - state->x.have;
|
||||||
strm->adler = crc32(strm->adler, state->next, state->have);
|
|
||||||
|
|
||||||
/* check gzip trailer if at end of deflate stream */
|
/* if the gzip stream completed successfully, look for another */
|
||||||
if (ret == Z_STREAM_END) {
|
if (ret == Z_STREAM_END)
|
||||||
if (gz_next4(state, &crc) == -1 || gz_next4(state, &len) == -1) {
|
state->how = LOOK;
|
||||||
gz_error(state, Z_DATA_ERROR, "unexpected end of file");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (crc != strm->adler) {
|
|
||||||
gz_error(state, Z_DATA_ERROR, "incorrect data check");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (len != (strm->total_out & 0xffffffffL)) {
|
|
||||||
gz_error(state, Z_DATA_ERROR, "incorrect length check");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
state->how = LOOK; /* ready for next stream, once have is 0 (leave
|
|
||||||
state->direct unchanged to remember how) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* good decompression */
|
/* good decompression */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make data and put in the output buffer. Assumes that state->have == 0.
|
/* Fetch data and put it in the output buffer. Assumes state->x.have is 0.
|
||||||
Data is either copied from the input file or decompressed from the input
|
Data is either copied from the input file or decompressed from the input
|
||||||
file depending on state->how. If state->how is LOOK, then a gzip header is
|
file depending on state->how. If state->how is LOOK, then a gzip header is
|
||||||
looked for (and skipped if found) to determine wither to copy or decompress.
|
looked for to determine whether to copy or decompress. Returns -1 on error,
|
||||||
Returns -1 on error, otherwise 0. gz_make() will leave state->have as COPY
|
otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the
|
||||||
or GZIP unless the end of the input file has been reached and all data has
|
end of the input file has been reached and all data has been processed. */
|
||||||
been processed. */
|
local int gz_fetch(state)
|
||||||
local int gz_make(state)
|
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
{
|
{
|
||||||
z_streamp strm = &(state->strm);
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
if (state->how == LOOK) { /* look for gzip header */
|
do {
|
||||||
if (gz_head(state) == -1)
|
switch(state->how) {
|
||||||
return -1;
|
case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */
|
||||||
if (state->have) /* got some data from gz_head() */
|
if (gz_look(state) == -1)
|
||||||
|
return -1;
|
||||||
|
if (state->how == LOOK)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case COPY: /* -> COPY */
|
||||||
|
if (gz_load(state, state->out, state->size << 1, &(state->x.have))
|
||||||
|
== -1)
|
||||||
|
return -1;
|
||||||
|
state->x.next = state->out;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */
|
||||||
if (state->how == COPY) { /* straight copy */
|
strm->avail_out = state->size << 1;
|
||||||
if (gz_load(state, state->out, state->size << 1, &(state->have)) == -1)
|
strm->next_out = state->out;
|
||||||
return -1;
|
if (gz_decomp(state) == -1)
|
||||||
state->next = state->out;
|
return -1;
|
||||||
}
|
}
|
||||||
else if (state->how == GZIP) { /* decompress */
|
} while (state->x.have == 0 && (!state->eof || strm->avail_in));
|
||||||
strm->avail_out = state->size << 1;
|
|
||||||
strm->next_out = state->out;
|
|
||||||
if (gz_decomp(state) == -1)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,12 +261,12 @@ local int gz_skip(state, len)
|
||||||
/* skip over len bytes or reach end-of-file, whichever comes first */
|
/* skip over len bytes or reach end-of-file, whichever comes first */
|
||||||
while (len)
|
while (len)
|
||||||
/* skip over whatever is in output buffer */
|
/* skip over whatever is in output buffer */
|
||||||
if (state->have) {
|
if (state->x.have) {
|
||||||
n = GT_OFF(state->have) || (z_off64_t)state->have > len ?
|
n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
|
||||||
(unsigned)len : state->have;
|
(unsigned)len : state->x.have;
|
||||||
state->have -= n;
|
state->x.have -= n;
|
||||||
state->next += n;
|
state->x.next += n;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
len -= n;
|
len -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,7 +277,7 @@ local int gz_skip(state, len)
|
||||||
/* need more data to skip -- load up output buffer */
|
/* need more data to skip -- load up output buffer */
|
||||||
else {
|
else {
|
||||||
/* get more output, looking for header if required */
|
/* get more output, looking for header if required */
|
||||||
if (gz_make(state) == -1)
|
if (gz_fetch(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -373,14 +299,15 @@ int ZEXPORT gzread(file, buf, len)
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
strm = &(state->strm);
|
strm = &(state->strm);
|
||||||
|
|
||||||
/* check that we're reading and that there's no error */
|
/* check that we're reading and that there's no (serious) error */
|
||||||
if (state->mode != GZ_READ || state->err != Z_OK)
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* since an int is returned, make sure len fits in one, otherwise return
|
/* since an int is returned, make sure len fits in one, otherwise return
|
||||||
with an error (this avoids the flaw in the interface) */
|
with an error (this avoids the flaw in the interface) */
|
||||||
if ((int)len < 0) {
|
if ((int)len < 0) {
|
||||||
gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
|
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,24 +326,26 @@ int ZEXPORT gzread(file, buf, len)
|
||||||
got = 0;
|
got = 0;
|
||||||
do {
|
do {
|
||||||
/* first just try copying data from the output buffer */
|
/* first just try copying data from the output buffer */
|
||||||
if (state->have) {
|
if (state->x.have) {
|
||||||
n = state->have > len ? len : state->have;
|
n = state->x.have > len ? len : state->x.have;
|
||||||
memcpy(buf, state->next, n);
|
memcpy(buf, state->x.next, n);
|
||||||
state->next += n;
|
state->x.next += n;
|
||||||
state->have -= n;
|
state->x.have -= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* output buffer empty -- return if we're at the end of the input */
|
/* output buffer empty -- return if we're at the end of the input */
|
||||||
else if (state->eof && strm->avail_in == 0)
|
else if (state->eof && strm->avail_in == 0) {
|
||||||
|
state->past = 1; /* tried to read past end */
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* need output data -- for small len or new stream load up our output
|
/* need output data -- for small len or new stream load up our output
|
||||||
buffer */
|
buffer */
|
||||||
else if (state->how == LOOK || len < (state->size << 1)) {
|
else if (state->how == LOOK || len < (state->size << 1)) {
|
||||||
/* get more output, looking for header if required */
|
/* get more output, looking for header if required */
|
||||||
if (gz_make(state) == -1)
|
if (gz_fetch(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
continue; /* no progress yet -- go back to memcpy() above */
|
continue; /* no progress yet -- go back to copy above */
|
||||||
/* the copy above assures that we will leave with space in the
|
/* the copy above assures that we will leave with space in the
|
||||||
output buffer, allowing at least one gzungetc() to succeed */
|
output buffer, allowing at least one gzungetc() to succeed */
|
||||||
}
|
}
|
||||||
|
@ -433,15 +362,15 @@ int ZEXPORT gzread(file, buf, len)
|
||||||
strm->next_out = buf;
|
strm->next_out = buf;
|
||||||
if (gz_decomp(state) == -1)
|
if (gz_decomp(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
n = state->have;
|
n = state->x.have;
|
||||||
state->have = 0;
|
state->x.have = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update progress */
|
/* update progress */
|
||||||
len -= n;
|
len -= n;
|
||||||
buf = (char *)buf + n;
|
buf = (char *)buf + n;
|
||||||
got += n;
|
got += n;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
} while (len);
|
} while (len);
|
||||||
|
|
||||||
/* return number of bytes read into user buffer (will fit in int) */
|
/* return number of bytes read into user buffer (will fit in int) */
|
||||||
|
@ -449,6 +378,7 @@ int ZEXPORT gzread(file, buf, len)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
#undef gzgetc
|
||||||
int ZEXPORT gzgetc(file)
|
int ZEXPORT gzgetc(file)
|
||||||
gzFile file;
|
gzFile file;
|
||||||
{
|
{
|
||||||
|
@ -461,15 +391,16 @@ int ZEXPORT gzgetc(file)
|
||||||
return -1;
|
return -1;
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
|
|
||||||
/* check that we're reading and that there's no error */
|
/* check that we're reading and that there's no (serious) error */
|
||||||
if (state->mode != GZ_READ || state->err != Z_OK)
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* try output buffer (no need to check for skip request) */
|
/* try output buffer (no need to check for skip request) */
|
||||||
if (state->have) {
|
if (state->x.have) {
|
||||||
state->have--;
|
state->x.have--;
|
||||||
state->pos++;
|
state->x.pos++;
|
||||||
return *(state->next)++;
|
return *(state->x.next)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* nothing there -- try gzread() */
|
/* nothing there -- try gzread() */
|
||||||
|
@ -477,6 +408,12 @@ int ZEXPORT gzgetc(file)
|
||||||
return ret < 1 ? -1 : buf[0];
|
return ret < 1 ? -1 : buf[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZEXPORT gzgetc_(file)
|
||||||
|
gzFile file;
|
||||||
|
{
|
||||||
|
return gzgetc(file);
|
||||||
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
int ZEXPORT gzungetc(c, file)
|
int ZEXPORT gzungetc(c, file)
|
||||||
int c;
|
int c;
|
||||||
|
@ -489,8 +426,9 @@ int ZEXPORT gzungetc(c, file)
|
||||||
return -1;
|
return -1;
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
|
|
||||||
/* check that we're reading and that there's no error */
|
/* check that we're reading and that there's no (serious) error */
|
||||||
if (state->mode != GZ_READ || state->err != Z_OK)
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* process a skip request */
|
/* process a skip request */
|
||||||
|
@ -505,32 +443,34 @@ int ZEXPORT gzungetc(c, file)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* if output buffer empty, put byte at end (allows more pushing) */
|
/* if output buffer empty, put byte at end (allows more pushing) */
|
||||||
if (state->have == 0) {
|
if (state->x.have == 0) {
|
||||||
state->have = 1;
|
state->x.have = 1;
|
||||||
state->next = state->out + (state->size << 1) - 1;
|
state->x.next = state->out + (state->size << 1) - 1;
|
||||||
state->next[0] = c;
|
state->x.next[0] = c;
|
||||||
state->pos--;
|
state->x.pos--;
|
||||||
|
state->past = 0;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if no room, give up (must have already done a gzungetc()) */
|
/* if no room, give up (must have already done a gzungetc()) */
|
||||||
if (state->have == (state->size << 1)) {
|
if (state->x.have == (state->size << 1)) {
|
||||||
gz_error(state, Z_BUF_ERROR, "out of room to push characters");
|
gz_error(state, Z_DATA_ERROR, "out of room to push characters");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* slide output data if needed and insert byte before existing data */
|
/* slide output data if needed and insert byte before existing data */
|
||||||
if (state->next == state->out) {
|
if (state->x.next == state->out) {
|
||||||
unsigned char *src = state->out + state->have;
|
unsigned char *src = state->out + state->x.have;
|
||||||
unsigned char *dest = state->out + (state->size << 1);
|
unsigned char *dest = state->out + (state->size << 1);
|
||||||
while (src > state->out)
|
while (src > state->out)
|
||||||
*--dest = *--src;
|
*--dest = *--src;
|
||||||
state->next = dest;
|
state->x.next = dest;
|
||||||
}
|
}
|
||||||
state->have++;
|
state->x.have++;
|
||||||
state->next--;
|
state->x.next--;
|
||||||
state->next[0] = c;
|
state->x.next[0] = c;
|
||||||
state->pos--;
|
state->x.pos--;
|
||||||
|
state->past = 0;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -550,8 +490,9 @@ char * ZEXPORT gzgets(file, buf, len)
|
||||||
return NULL;
|
return NULL;
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
|
|
||||||
/* check that we're reading and that there's no error */
|
/* check that we're reading and that there's no (serious) error */
|
||||||
if (state->mode != GZ_READ || state->err != Z_OK)
|
if (state->mode != GZ_READ ||
|
||||||
|
(state->err != Z_OK && state->err != Z_BUF_ERROR))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* process a skip request */
|
/* process a skip request */
|
||||||
|
@ -568,32 +509,31 @@ char * ZEXPORT gzgets(file, buf, len)
|
||||||
left = (unsigned)len - 1;
|
left = (unsigned)len - 1;
|
||||||
if (left) do {
|
if (left) do {
|
||||||
/* assure that something is in the output buffer */
|
/* assure that something is in the output buffer */
|
||||||
if (state->have == 0) {
|
if (state->x.have == 0 && gz_fetch(state) == -1)
|
||||||
if (gz_make(state) == -1)
|
return NULL; /* error */
|
||||||
return NULL; /* error */
|
if (state->x.have == 0) { /* end of file */
|
||||||
if (state->have == 0) { /* end of file */
|
state->past = 1; /* read past end */
|
||||||
if (buf == str) /* got bupkus */
|
break; /* return what we have */
|
||||||
return NULL;
|
|
||||||
break; /* got something -- return it */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* look for end-of-line in current output buffer */
|
/* look for end-of-line in current output buffer */
|
||||||
n = state->have > left ? left : state->have;
|
n = state->x.have > left ? left : state->x.have;
|
||||||
eol = memchr(state->next, '\n', n);
|
eol = memchr(state->x.next, '\n', n);
|
||||||
if (eol != NULL)
|
if (eol != NULL)
|
||||||
n = (unsigned)(eol - state->next) + 1;
|
n = (unsigned)(eol - state->x.next) + 1;
|
||||||
|
|
||||||
/* copy through end-of-line, or remainder if not found */
|
/* copy through end-of-line, or remainder if not found */
|
||||||
memcpy(buf, state->next, n);
|
memcpy(buf, state->x.next, n);
|
||||||
state->have -= n;
|
state->x.have -= n;
|
||||||
state->next += n;
|
state->x.next += n;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
left -= n;
|
left -= n;
|
||||||
buf += n;
|
buf += n;
|
||||||
} while (left && eol == NULL);
|
} while (left && eol == NULL);
|
||||||
|
|
||||||
/* found end-of-line or out of space -- terminate string and return it */
|
/* return terminated string, or if nothing, end of file */
|
||||||
|
if (buf == str)
|
||||||
|
return NULL;
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
@ -609,16 +549,12 @@ int ZEXPORT gzdirect(file)
|
||||||
return 0;
|
return 0;
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
|
|
||||||
/* check that we're reading */
|
|
||||||
if (state->mode != GZ_READ)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* if the state is not known, but we can find out, then do so (this is
|
/* if the state is not known, but we can find out, then do so (this is
|
||||||
mainly for right after a gzopen() or gzdopen()) */
|
mainly for right after a gzopen() or gzdopen()) */
|
||||||
if (state->how == LOOK && state->have == 0)
|
if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
|
||||||
(void)gz_head(state);
|
(void)gz_look(state);
|
||||||
|
|
||||||
/* return 1 if reading direct, 0 if decompressing a gzip stream */
|
/* return 1 if transparent, 0 if processing a gzip stream */
|
||||||
return state->direct;
|
return state->direct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -626,7 +562,7 @@ int ZEXPORT gzdirect(file)
|
||||||
int ZEXPORT gzclose_r(file)
|
int ZEXPORT gzclose_r(file)
|
||||||
gzFile file;
|
gzFile file;
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, err;
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
|
|
||||||
/* get internal structure */
|
/* get internal structure */
|
||||||
|
@ -644,9 +580,10 @@ int ZEXPORT gzclose_r(file)
|
||||||
free(state->out);
|
free(state->out);
|
||||||
free(state->in);
|
free(state->in);
|
||||||
}
|
}
|
||||||
|
err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
|
||||||
gz_error(state, Z_OK, NULL);
|
gz_error(state, Z_OK, NULL);
|
||||||
free(state->path);
|
free(state->path);
|
||||||
ret = close(state->fd);
|
ret = close(state->fd);
|
||||||
free(state);
|
free(state);
|
||||||
return ret ? Z_ERRNO : Z_OK;
|
return ret ? Z_ERRNO : err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* gzwrite.c -- zlib functions for writing gzip files
|
/* gzwrite.c -- zlib functions for writing gzip files
|
||||||
* Copyright (C) 2004, 2005, 2010 Mark Adler
|
* Copyright (C) 2004, 2005, 2010, 2011, 2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -18,44 +18,55 @@ local int gz_init(state)
|
||||||
int ret;
|
int ret;
|
||||||
z_streamp strm = &(state->strm);
|
z_streamp strm = &(state->strm);
|
||||||
|
|
||||||
/* allocate input and output buffers */
|
/* allocate input buffer */
|
||||||
state->in = malloc(state->want);
|
state->in = malloc(state->want);
|
||||||
state->out = malloc(state->want);
|
if (state->in == NULL) {
|
||||||
if (state->in == NULL || state->out == NULL) {
|
|
||||||
if (state->out != NULL)
|
|
||||||
free(state->out);
|
|
||||||
if (state->in != NULL)
|
|
||||||
free(state->in);
|
|
||||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate deflate memory, set up for gzip compression */
|
/* only need output buffer and deflate state if compressing */
|
||||||
strm->zalloc = Z_NULL;
|
if (!state->direct) {
|
||||||
strm->zfree = Z_NULL;
|
/* allocate output buffer */
|
||||||
strm->opaque = Z_NULL;
|
state->out = malloc(state->want);
|
||||||
ret = deflateInit2(strm, state->level, Z_DEFLATED,
|
if (state->out == NULL) {
|
||||||
15 + 16, 8, state->strategy);
|
free(state->in);
|
||||||
if (ret != Z_OK) {
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
free(state->in);
|
return -1;
|
||||||
gz_error(state, Z_MEM_ERROR, "out of memory");
|
}
|
||||||
return -1;
|
|
||||||
|
/* allocate deflate memory, set up for gzip compression */
|
||||||
|
strm->zalloc = Z_NULL;
|
||||||
|
strm->zfree = Z_NULL;
|
||||||
|
strm->opaque = Z_NULL;
|
||||||
|
ret = deflateInit2(strm, state->level, Z_DEFLATED,
|
||||||
|
MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
|
||||||
|
if (ret != Z_OK) {
|
||||||
|
free(state->out);
|
||||||
|
free(state->in);
|
||||||
|
gz_error(state, Z_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mark state as initialized */
|
/* mark state as initialized */
|
||||||
state->size = state->want;
|
state->size = state->want;
|
||||||
|
|
||||||
/* initialize write buffer */
|
/* initialize write buffer if compressing */
|
||||||
strm->avail_out = state->size;
|
if (!state->direct) {
|
||||||
strm->next_out = state->out;
|
strm->avail_out = state->size;
|
||||||
state->next = strm->next_out;
|
strm->next_out = state->out;
|
||||||
|
state->x.next = strm->next_out;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compress whatever is at avail_in and next_in and write to the output file.
|
/* Compress whatever is at avail_in and next_in and write to the output file.
|
||||||
Return -1 if there is an error writing to the output file, otherwise 0.
|
Return -1 if there is an error writing to the output file, otherwise 0.
|
||||||
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
|
flush is assumed to be a valid deflate() flush value. If flush is Z_FINISH,
|
||||||
then the deflate() state is reset to start a new gzip stream. */
|
then the deflate() state is reset to start a new gzip stream. If gz->direct
|
||||||
|
is true, then simply write to the output file without compressing, and
|
||||||
|
ignore flush. */
|
||||||
local int gz_comp(state, flush)
|
local int gz_comp(state, flush)
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
int flush;
|
int flush;
|
||||||
|
@ -68,6 +79,17 @@ local int gz_comp(state, flush)
|
||||||
if (state->size == 0 && gz_init(state) == -1)
|
if (state->size == 0 && gz_init(state) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* write directly if requested */
|
||||||
|
if (state->direct) {
|
||||||
|
got = write(state->fd, strm->next_in, strm->avail_in);
|
||||||
|
if (got < 0 || (unsigned)got != strm->avail_in) {
|
||||||
|
gz_error(state, Z_ERRNO, zstrerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
strm->avail_in = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* run deflate() on provided input until it produces no more output */
|
/* run deflate() on provided input until it produces no more output */
|
||||||
ret = Z_OK;
|
ret = Z_OK;
|
||||||
do {
|
do {
|
||||||
|
@ -75,8 +97,8 @@ local int gz_comp(state, flush)
|
||||||
doing Z_FINISH then don't write until we get to Z_STREAM_END */
|
doing Z_FINISH then don't write until we get to Z_STREAM_END */
|
||||||
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
|
if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
|
||||||
(flush != Z_FINISH || ret == Z_STREAM_END))) {
|
(flush != Z_FINISH || ret == Z_STREAM_END))) {
|
||||||
have = (unsigned)(strm->next_out - state->next);
|
have = (unsigned)(strm->next_out - state->x.next);
|
||||||
if (have && ((got = write(state->fd, state->next, have)) < 0 ||
|
if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
|
||||||
(unsigned)got != have)) {
|
(unsigned)got != have)) {
|
||||||
gz_error(state, Z_ERRNO, zstrerror());
|
gz_error(state, Z_ERRNO, zstrerror());
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -85,7 +107,7 @@ local int gz_comp(state, flush)
|
||||||
strm->avail_out = state->size;
|
strm->avail_out = state->size;
|
||||||
strm->next_out = state->out;
|
strm->next_out = state->out;
|
||||||
}
|
}
|
||||||
state->next = strm->next_out;
|
state->x.next = strm->next_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compress */
|
/* compress */
|
||||||
|
@ -131,7 +153,7 @@ local int gz_zero(state, len)
|
||||||
}
|
}
|
||||||
strm->avail_in = n;
|
strm->avail_in = n;
|
||||||
strm->next_in = state->in;
|
strm->next_in = state->in;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
len -= n;
|
len -= n;
|
||||||
|
@ -163,7 +185,7 @@ int ZEXPORT gzwrite(file, buf, len)
|
||||||
/* since an int is returned, make sure len fits in one, otherwise return
|
/* since an int is returned, make sure len fits in one, otherwise return
|
||||||
with an error (this avoids the flaw in the interface) */
|
with an error (this avoids the flaw in the interface) */
|
||||||
if ((int)len < 0) {
|
if ((int)len < 0) {
|
||||||
gz_error(state, Z_BUF_ERROR, "requested length does not fit in int");
|
gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,7 +215,7 @@ int ZEXPORT gzwrite(file, buf, len)
|
||||||
n = len;
|
n = len;
|
||||||
memcpy(strm->next_in + strm->avail_in, buf, n);
|
memcpy(strm->next_in + strm->avail_in, buf, n);
|
||||||
strm->avail_in += n;
|
strm->avail_in += n;
|
||||||
state->pos += n;
|
state->x.pos += n;
|
||||||
buf = (char *)buf + n;
|
buf = (char *)buf + n;
|
||||||
len -= n;
|
len -= n;
|
||||||
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
|
if (len && gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
|
@ -208,7 +230,7 @@ int ZEXPORT gzwrite(file, buf, len)
|
||||||
/* directly compress user buffer to file */
|
/* directly compress user buffer to file */
|
||||||
strm->avail_in = len;
|
strm->avail_in = len;
|
||||||
strm->next_in = (voidp)buf;
|
strm->next_in = (voidp)buf;
|
||||||
state->pos += len;
|
state->x.pos += len;
|
||||||
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
if (gz_comp(state, Z_NO_FLUSH) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -249,15 +271,15 @@ int ZEXPORT gzputc(file, c)
|
||||||
if (strm->avail_in == 0)
|
if (strm->avail_in == 0)
|
||||||
strm->next_in = state->in;
|
strm->next_in = state->in;
|
||||||
strm->next_in[strm->avail_in++] = c;
|
strm->next_in[strm->avail_in++] = c;
|
||||||
state->pos++;
|
state->x.pos++;
|
||||||
return c;
|
return c & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no room in buffer or not initialized, use gz_write() */
|
/* no room in buffer or not initialized, use gz_write() */
|
||||||
buf[0] = c;
|
buf[0] = c;
|
||||||
if (gzwrite(file, buf, 1) != 1)
|
if (gzwrite(file, buf, 1) != 1)
|
||||||
return -1;
|
return -1;
|
||||||
return c;
|
return c & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
@ -274,7 +296,7 @@ int ZEXPORT gzputs(file, str)
|
||||||
return ret == 0 && len != 0 ? -1 : ret;
|
return ret == 0 && len != 0 ? -1 : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STDC
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
|
@ -316,19 +338,19 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
#ifdef NO_vsnprintf
|
#ifdef NO_vsnprintf
|
||||||
# ifdef HAS_vsprintf_void
|
# ifdef HAS_vsprintf_void
|
||||||
(void)vsprintf(state->in, format, va);
|
(void)vsprintf((char *)(state->in), format, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
for (len = 0; len < size; len++)
|
for (len = 0; len < size; len++)
|
||||||
if (state->in[len] == 0) break;
|
if (state->in[len] == 0) break;
|
||||||
# else
|
# else
|
||||||
len = vsprintf(state->in, format, va);
|
len = vsprintf((char *)(state->in), format, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# ifdef HAS_vsnprintf_void
|
# ifdef HAS_vsnprintf_void
|
||||||
(void)vsnprintf(state->in, size, format, va);
|
(void)vsnprintf((char *)(state->in), size, format, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
len = strlen(state->in);
|
len = strlen((char *)(state->in));
|
||||||
# else
|
# else
|
||||||
len = vsnprintf((char *)(state->in), size, format, va);
|
len = vsnprintf((char *)(state->in), size, format, va);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
|
@ -342,11 +364,11 @@ int ZEXPORTVA gzprintf (gzFile file, const char *format, ...)
|
||||||
/* update buffer and position, defer compression until needed */
|
/* update buffer and position, defer compression until needed */
|
||||||
strm->avail_in = (unsigned)len;
|
strm->avail_in = (unsigned)len;
|
||||||
strm->next_in = state->in;
|
strm->next_in = state->in;
|
||||||
state->pos += len;
|
state->x.pos += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !STDC */
|
#else /* !STDC && !Z_HAVE_STDARG_H */
|
||||||
|
|
||||||
/* -- see zlib.h -- */
|
/* -- see zlib.h -- */
|
||||||
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
|
@ -366,6 +388,10 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
state = (gz_statep)file;
|
state = (gz_statep)file;
|
||||||
strm = &(state->strm);
|
strm = &(state->strm);
|
||||||
|
|
||||||
|
/* check that can really pass pointer in ints */
|
||||||
|
if (sizeof(int) != sizeof(void *))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* check that we're writing and that there's no error */
|
/* check that we're writing and that there's no error */
|
||||||
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
if (state->mode != GZ_WRITE || state->err != Z_OK)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -390,22 +416,23 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
state->in[size - 1] = 0;
|
state->in[size - 1] = 0;
|
||||||
#ifdef NO_snprintf
|
#ifdef NO_snprintf
|
||||||
# ifdef HAS_sprintf_void
|
# ifdef HAS_sprintf_void
|
||||||
sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
for (len = 0; len < size; len++)
|
for (len = 0; len < size; len++)
|
||||||
if (state->in[len] == 0) break;
|
if (state->in[len] == 0) break;
|
||||||
# else
|
# else
|
||||||
len = sprintf(state->in, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# ifdef HAS_snprintf_void
|
# ifdef HAS_snprintf_void
|
||||||
snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
||||||
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
||||||
len = strlen(state->in);
|
len = strlen((char *)(state->in));
|
||||||
# else
|
# else
|
||||||
len = snprintf(state->in, size, format, a1, a2, a3, a4, a5, a6, a7, a8,
|
len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
|
||||||
a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
|
a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
|
||||||
|
a19, a20);
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -416,7 +443,7 @@ int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
|
||||||
/* update buffer and position, defer compression until needed */
|
/* update buffer and position, defer compression until needed */
|
||||||
strm->avail_in = (unsigned)len;
|
strm->avail_in = (unsigned)len;
|
||||||
strm->next_in = state->in;
|
strm->next_in = state->in;
|
||||||
state->pos += len;
|
state->x.pos += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +527,7 @@ int ZEXPORT gzsetparams(file, level, strategy)
|
||||||
int ZEXPORT gzclose_w(file)
|
int ZEXPORT gzclose_w(file)
|
||||||
gzFile file;
|
gzFile file;
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = Z_OK;
|
||||||
gz_statep state;
|
gz_statep state;
|
||||||
|
|
||||||
/* get internal structure */
|
/* get internal structure */
|
||||||
|
@ -515,17 +542,24 @@ int ZEXPORT gzclose_w(file)
|
||||||
/* check for seek request */
|
/* check for seek request */
|
||||||
if (state->seek) {
|
if (state->seek) {
|
||||||
state->seek = 0;
|
state->seek = 0;
|
||||||
ret += gz_zero(state, state->skip);
|
if (gz_zero(state, state->skip) == -1)
|
||||||
|
ret = state->err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush, free memory, and close file */
|
/* flush, free memory, and close file */
|
||||||
ret += gz_comp(state, Z_FINISH);
|
if (state->size) {
|
||||||
(void)deflateEnd(&(state->strm));
|
if (gz_comp(state, Z_FINISH) == -1)
|
||||||
free(state->out);
|
ret = state->err;
|
||||||
free(state->in);
|
if (!state->direct) {
|
||||||
|
(void)deflateEnd(&(state->strm));
|
||||||
|
free(state->out);
|
||||||
|
}
|
||||||
|
free(state->in);
|
||||||
|
}
|
||||||
gz_error(state, Z_OK, NULL);
|
gz_error(state, Z_OK, NULL);
|
||||||
free(state->path);
|
free(state->path);
|
||||||
ret += close(state->fd);
|
if (close(state->fd) == -1)
|
||||||
|
ret = Z_ERRNO;
|
||||||
free(state);
|
free(state);
|
||||||
return ret ? Z_ERRNO : Z_OK;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* infback.c -- inflate using a call-back interface
|
/* infback.c -- inflate using a call-back interface
|
||||||
* Copyright (C) 1995-2009 Mark Adler
|
* Copyright (C) 1995-2011 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -42,10 +42,19 @@ int stream_size;
|
||||||
return Z_STREAM_ERROR;
|
return Z_STREAM_ERROR;
|
||||||
strm->msg = Z_NULL; /* in case we return an error */
|
strm->msg = Z_NULL; /* in case we return an error */
|
||||||
if (strm->zalloc == (alloc_func)0) {
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
strm->zalloc = zcalloc;
|
strm->zalloc = zcalloc;
|
||||||
strm->opaque = (voidpf)0;
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
|
state = (struct inflate_state FAR *)ZALLOC(strm, 1,
|
||||||
sizeof(struct inflate_state));
|
sizeof(struct inflate_state));
|
||||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||||
|
@ -394,7 +403,6 @@ void FAR *out_desc;
|
||||||
PULLBYTE();
|
PULLBYTE();
|
||||||
}
|
}
|
||||||
if (here.val < 16) {
|
if (here.val < 16) {
|
||||||
NEEDBITS(here.bits);
|
|
||||||
DROPBITS(here.bits);
|
DROPBITS(here.bits);
|
||||||
state->lens[state->have++] = here.val;
|
state->lens[state->have++] = here.val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inffast.c -- fast decoding
|
/* inffast.c -- fast decoding
|
||||||
* Copyright (C) 1995-2008 Mark Adler
|
* Copyright (C) 1995-2008, 2010 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@
|
||||||
requires strm->avail_out >= 258 for each loop to avoid checking for
|
requires strm->avail_out >= 258 for each loop to avoid checking for
|
||||||
output space.
|
output space.
|
||||||
*/
|
*/
|
||||||
void inflate_fast(strm, start)
|
void ZLIB_INTERNAL inflate_fast(strm, start)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
unsigned start; /* inflate()'s starting value for strm->avail_out */
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inffast.h -- header to use inffast.c
|
/* inffast.h -- header to use inffast.c
|
||||||
* Copyright (C) 1995-2003 Mark Adler
|
* Copyright (C) 1995-2003, 2010 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -8,4 +8,4 @@
|
||||||
subject to change. Applications should only use zlib.h.
|
subject to change. Applications should only use zlib.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void inflate_fast OF((z_streamp strm, unsigned start));
|
void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
* Generated automatically by makefixed().
|
* Generated automatically by makefixed().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* WARNING: this file should *not* be used by applications. It
|
/* WARNING: this file should *not* be used by applications.
|
||||||
is part of the implementation of the compression library and
|
It is part of the implementation of this library and is
|
||||||
is subject to change. Applications should only use zlib.h.
|
subject to change. Applications should only use zlib.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const code lenfix[512] = {
|
static const code lenfix[512] = {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inflate.c -- zlib decompression
|
/* inflate.c -- zlib decompression
|
||||||
* Copyright (C) 1995-2010 Mark Adler
|
* Copyright (C) 1995-2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ local int updatewindow OF((z_streamp strm, unsigned out));
|
||||||
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
|
local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
|
||||||
unsigned len));
|
unsigned len));
|
||||||
|
|
||||||
int ZEXPORT inflateReset(strm)
|
int ZEXPORT inflateResetKeep(strm)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
|
@ -109,15 +109,13 @@ z_streamp strm;
|
||||||
state = (struct inflate_state FAR *)strm->state;
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
strm->total_in = strm->total_out = state->total = 0;
|
strm->total_in = strm->total_out = state->total = 0;
|
||||||
strm->msg = Z_NULL;
|
strm->msg = Z_NULL;
|
||||||
strm->adler = 1; /* to support ill-conceived Java test suite */
|
if (state->wrap) /* to support ill-conceived Java test suite */
|
||||||
|
strm->adler = state->wrap & 1;
|
||||||
state->mode = HEAD;
|
state->mode = HEAD;
|
||||||
state->last = 0;
|
state->last = 0;
|
||||||
state->havedict = 0;
|
state->havedict = 0;
|
||||||
state->dmax = 32768U;
|
state->dmax = 32768U;
|
||||||
state->head = Z_NULL;
|
state->head = Z_NULL;
|
||||||
state->wsize = 0;
|
|
||||||
state->whave = 0;
|
|
||||||
state->wnext = 0;
|
|
||||||
state->hold = 0;
|
state->hold = 0;
|
||||||
state->bits = 0;
|
state->bits = 0;
|
||||||
state->lencode = state->distcode = state->next = state->codes;
|
state->lencode = state->distcode = state->next = state->codes;
|
||||||
|
@ -127,6 +125,19 @@ z_streamp strm;
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ZEXPORT inflateReset(strm)
|
||||||
|
z_streamp strm;
|
||||||
|
{
|
||||||
|
struct inflate_state FAR *state;
|
||||||
|
|
||||||
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
state = (struct inflate_state FAR *)strm->state;
|
||||||
|
state->wsize = 0;
|
||||||
|
state->whave = 0;
|
||||||
|
state->wnext = 0;
|
||||||
|
return inflateResetKeep(strm);
|
||||||
|
}
|
||||||
|
|
||||||
int ZEXPORT inflateReset2(strm, windowBits)
|
int ZEXPORT inflateReset2(strm, windowBits)
|
||||||
z_streamp strm;
|
z_streamp strm;
|
||||||
int windowBits;
|
int windowBits;
|
||||||
|
@ -180,10 +191,19 @@ int stream_size;
|
||||||
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL) return Z_STREAM_ERROR;
|
||||||
strm->msg = Z_NULL; /* in case we return an error */
|
strm->msg = Z_NULL; /* in case we return an error */
|
||||||
if (strm->zalloc == (alloc_func)0) {
|
if (strm->zalloc == (alloc_func)0) {
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
strm->zalloc = zcalloc;
|
strm->zalloc = zcalloc;
|
||||||
strm->opaque = (voidpf)0;
|
strm->opaque = (voidpf)0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (strm->zfree == (free_func)0) strm->zfree = zcfree;
|
if (strm->zfree == (free_func)0)
|
||||||
|
#ifdef Z_SOLO
|
||||||
|
return Z_STREAM_ERROR;
|
||||||
|
#else
|
||||||
|
strm->zfree = zcfree;
|
||||||
|
#endif
|
||||||
state = (struct inflate_state FAR *)
|
state = (struct inflate_state FAR *)
|
||||||
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
ZALLOC(strm, 1, sizeof(struct inflate_state));
|
||||||
if (state == Z_NULL) return Z_MEM_ERROR;
|
if (state == Z_NULL) return Z_MEM_ERROR;
|
||||||
|
@ -321,8 +341,8 @@ void makefixed()
|
||||||
low = 0;
|
low = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((low % 7) == 0) printf("\n ");
|
if ((low % 7) == 0) printf("\n ");
|
||||||
printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
|
printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
|
||||||
state.lencode[low].val);
|
state.lencode[low].bits, state.lencode[low].val);
|
||||||
if (++low == size) break;
|
if (++low == size) break;
|
||||||
putchar(',');
|
putchar(',');
|
||||||
}
|
}
|
||||||
|
@ -499,11 +519,6 @@ unsigned out;
|
||||||
bits -= bits & 7; \
|
bits -= bits & 7; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Reverse the bytes in a 32-bit value */
|
|
||||||
#define REVERSE(q) \
|
|
||||||
((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
|
||||||
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
inflate() uses a state machine to process as much input data and generate as
|
inflate() uses a state machine to process as much input data and generate as
|
||||||
much output data as possible before returning. The state machine is
|
much output data as possible before returning. The state machine is
|
||||||
|
@ -797,7 +812,7 @@ int flush;
|
||||||
#endif
|
#endif
|
||||||
case DICTID:
|
case DICTID:
|
||||||
NEEDBITS(32);
|
NEEDBITS(32);
|
||||||
strm->adler = state->check = REVERSE(hold);
|
strm->adler = state->check = ZSWAP32(hold);
|
||||||
INITBITS();
|
INITBITS();
|
||||||
state->mode = DICT;
|
state->mode = DICT;
|
||||||
case DICT:
|
case DICT:
|
||||||
|
@ -925,7 +940,6 @@ int flush;
|
||||||
PULLBYTE();
|
PULLBYTE();
|
||||||
}
|
}
|
||||||
if (here.val < 16) {
|
if (here.val < 16) {
|
||||||
NEEDBITS(here.bits);
|
|
||||||
DROPBITS(here.bits);
|
DROPBITS(here.bits);
|
||||||
state->lens[state->have++] = here.val;
|
state->lens[state->have++] = here.val;
|
||||||
}
|
}
|
||||||
|
@ -1170,7 +1184,7 @@ int flush;
|
||||||
#ifdef GUNZIP
|
#ifdef GUNZIP
|
||||||
state->flags ? hold :
|
state->flags ? hold :
|
||||||
#endif
|
#endif
|
||||||
REVERSE(hold)) != state->check) {
|
ZSWAP32(hold)) != state->check) {
|
||||||
strm->msg = (char *)"incorrect data check";
|
strm->msg = (char *)"incorrect data check";
|
||||||
state->mode = BAD;
|
state->mode = BAD;
|
||||||
break;
|
break;
|
||||||
|
@ -1214,7 +1228,8 @@ int flush;
|
||||||
*/
|
*/
|
||||||
inf_leave:
|
inf_leave:
|
||||||
RESTORE();
|
RESTORE();
|
||||||
if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
|
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
|
||||||
|
(state->mode < CHECK || flush != Z_FINISH)))
|
||||||
if (updatewindow(strm, out)) {
|
if (updatewindow(strm, out)) {
|
||||||
state->mode = MEM;
|
state->mode = MEM;
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
|
@ -1255,7 +1270,10 @@ const Bytef *dictionary;
|
||||||
uInt dictLength;
|
uInt dictLength;
|
||||||
{
|
{
|
||||||
struct inflate_state FAR *state;
|
struct inflate_state FAR *state;
|
||||||
unsigned long id;
|
unsigned long dictid;
|
||||||
|
unsigned char *next;
|
||||||
|
unsigned avail;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* check state */
|
/* check state */
|
||||||
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
|
||||||
|
@ -1263,29 +1281,27 @@ uInt dictLength;
|
||||||
if (state->wrap != 0 && state->mode != DICT)
|
if (state->wrap != 0 && state->mode != DICT)
|
||||||
return Z_STREAM_ERROR;
|
return Z_STREAM_ERROR;
|
||||||
|
|
||||||
/* check for correct dictionary id */
|
/* check for correct dictionary identifier */
|
||||||
if (state->mode == DICT) {
|
if (state->mode == DICT) {
|
||||||
id = adler32(0L, Z_NULL, 0);
|
dictid = adler32(0L, Z_NULL, 0);
|
||||||
id = adler32(id, dictionary, dictLength);
|
dictid = adler32(dictid, dictionary, dictLength);
|
||||||
if (id != state->check)
|
if (dictid != state->check)
|
||||||
return Z_DATA_ERROR;
|
return Z_DATA_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy dictionary to window */
|
/* copy dictionary to window using updatewindow(), which will amend the
|
||||||
if (updatewindow(strm, strm->avail_out)) {
|
existing dictionary if appropriate */
|
||||||
|
next = strm->next_out;
|
||||||
|
avail = strm->avail_out;
|
||||||
|
strm->next_out = (Bytef *)dictionary + dictLength;
|
||||||
|
strm->avail_out = 0;
|
||||||
|
ret = updatewindow(strm, dictLength);
|
||||||
|
strm->avail_out = avail;
|
||||||
|
strm->next_out = next;
|
||||||
|
if (ret) {
|
||||||
state->mode = MEM;
|
state->mode = MEM;
|
||||||
return Z_MEM_ERROR;
|
return Z_MEM_ERROR;
|
||||||
}
|
}
|
||||||
if (dictLength > state->wsize) {
|
|
||||||
zmemcpy(state->window, dictionary + dictLength - state->wsize,
|
|
||||||
state->wsize);
|
|
||||||
state->whave = state->wsize;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
zmemcpy(state->window + state->wsize - dictLength, dictionary,
|
|
||||||
dictLength);
|
|
||||||
state->whave = dictLength;
|
|
||||||
}
|
|
||||||
state->havedict = 1;
|
state->havedict = 1;
|
||||||
Tracev((stderr, "inflate: dictionary set\n"));
|
Tracev((stderr, "inflate: dictionary set\n"));
|
||||||
return Z_OK;
|
return Z_OK;
|
||||||
|
@ -1433,8 +1449,8 @@ z_streamp source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy state */
|
/* copy state */
|
||||||
zmemcpy(dest, source, sizeof(z_stream));
|
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
|
||||||
zmemcpy(copy, state, sizeof(struct inflate_state));
|
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
|
||||||
if (state->lencode >= state->codes &&
|
if (state->lencode >= state->codes &&
|
||||||
state->lencode <= state->codes + ENOUGH - 1) {
|
state->lencode <= state->codes + ENOUGH - 1) {
|
||||||
copy->lencode = copy->codes + (state->lencode - state->codes);
|
copy->lencode = copy->codes + (state->lencode - state->codes);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inftrees.c -- generate Huffman trees for efficient decoding
|
/* inftrees.c -- generate Huffman trees for efficient decoding
|
||||||
* Copyright (C) 1995-2010 Mark Adler
|
* Copyright (C) 1995-2012 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
#define MAXBITS 15
|
#define MAXBITS 15
|
||||||
|
|
||||||
const char inflate_copyright[] =
|
const char inflate_copyright[] =
|
||||||
" inflate 1.2.4 Copyright 1995-2010 Mark Adler ";
|
" inflate 1.2.7 Copyright 1995-2012 Mark Adler ";
|
||||||
/*
|
/*
|
||||||
If you use the zlib library in a product, an acknowledgment is welcome
|
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
|
in the documentation of your product. If for some reason you cannot
|
||||||
|
@ -29,7 +29,7 @@ const char inflate_copyright[] =
|
||||||
table index bits. It will differ if the request is greater than the
|
table index bits. It will differ if the request is greater than the
|
||||||
longest code or if it is less than the shortest code.
|
longest code or if it is less than the shortest code.
|
||||||
*/
|
*/
|
||||||
int inflate_table(type, lens, codes, table, bits, work)
|
int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
|
||||||
codetype type;
|
codetype type;
|
||||||
unsigned short FAR *lens;
|
unsigned short FAR *lens;
|
||||||
unsigned codes;
|
unsigned codes;
|
||||||
|
@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
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 */
|
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,
|
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, 64, 195};
|
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 78, 68};
|
||||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
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,
|
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,
|
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||||
|
@ -289,38 +289,14 @@ unsigned short FAR *work;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* fill in remaining table entry if code is incomplete (guaranteed to have
|
||||||
Fill in rest of table for incomplete codes. This loop is similar to the
|
at most one remaining entry, since if the code is incomplete, the
|
||||||
loop above in incrementing huff for table indices. It is assumed that
|
maximum code length that was allowed to get this far is one bit) */
|
||||||
len is equal to curr + drop, so there is no loop needed to increment
|
if (huff != 0) {
|
||||||
through high index bits. When the current sub-table is filled, the loop
|
here.op = (unsigned char)64; /* invalid code marker */
|
||||||
drops back to the root table to fill in any remaining entries there.
|
here.bits = (unsigned char)(len - drop);
|
||||||
*/
|
here.val = (unsigned short)0;
|
||||||
here.op = (unsigned char)64; /* invalid code marker */
|
next[huff] = here;
|
||||||
here.bits = (unsigned char)(len - drop);
|
|
||||||
here.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;
|
|
||||||
here.bits = (unsigned char)len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* put invalid code marker in table */
|
|
||||||
next[huff >> drop] = here;
|
|
||||||
|
|
||||||
/* 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 */
|
/* set return parameters */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* inftrees.h -- header to use inftrees.c
|
/* inftrees.h -- header to use inftrees.c
|
||||||
* Copyright (C) 1995-2005 Mark Adler
|
* Copyright (C) 1995-2005, 2010 Mark Adler
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -57,6 +57,6 @@ typedef enum {
|
||||||
DISTS
|
DISTS
|
||||||
} codetype;
|
} codetype;
|
||||||
|
|
||||||
extern int inflate_table OF((codetype type, unsigned short FAR *lens,
|
int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
|
||||||
unsigned codes, code FAR * FAR *table,
|
unsigned codes, code FAR * FAR *table,
|
||||||
unsigned FAR *bits, unsigned short FAR *work));
|
unsigned FAR *bits, unsigned short FAR *work));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* trees.c -- output deflated data using Huffman coding
|
/* trees.c -- output deflated data using Huffman coding
|
||||||
* Copyright (C) 1995-2009 Jean-loup Gailly
|
* Copyright (C) 1995-2012 Jean-loup Gailly
|
||||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
@ -74,11 +74,6 @@ local const uch bl_order[BL_CODES]
|
||||||
* probability, to avoid transmitting the lengths for unused bit length codes.
|
* probability, to avoid transmitting the lengths for unused bit length codes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define Buf_size (8 * 2*sizeof(char))
|
|
||||||
/* Number of bits used within bi_buf. (bi_buf might be implemented on
|
|
||||||
* more than 16 bits on some systems.)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Local data. These are initialized only once.
|
* Local data. These are initialized only once.
|
||||||
*/
|
*/
|
||||||
|
@ -351,13 +346,14 @@ void gen_trees_header()
|
||||||
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
|
static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
|
fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
|
||||||
for (i = 0; i < DIST_CODE_LEN; i++) {
|
for (i = 0; i < DIST_CODE_LEN; i++) {
|
||||||
fprintf(header, "%2u%s", _dist_code[i],
|
fprintf(header, "%2u%s", _dist_code[i],
|
||||||
SEPARATOR(i, DIST_CODE_LEN-1, 20));
|
SEPARATOR(i, DIST_CODE_LEN-1, 20));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
fprintf(header,
|
||||||
|
"const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
|
||||||
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
|
for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
|
||||||
fprintf(header, "%2u%s", _length_code[i],
|
fprintf(header, "%2u%s", _length_code[i],
|
||||||
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
|
SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
|
||||||
|
@ -382,7 +378,7 @@ void gen_trees_header()
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Initialize the tree data structures for a new zlib stream.
|
* Initialize the tree data structures for a new zlib stream.
|
||||||
*/
|
*/
|
||||||
void _tr_init(s)
|
void ZLIB_INTERNAL _tr_init(s)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
{
|
{
|
||||||
tr_static_init();
|
tr_static_init();
|
||||||
|
@ -398,7 +394,6 @@ void _tr_init(s)
|
||||||
|
|
||||||
s->bi_buf = 0;
|
s->bi_buf = 0;
|
||||||
s->bi_valid = 0;
|
s->bi_valid = 0;
|
||||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
s->compressed_len = 0L;
|
s->compressed_len = 0L;
|
||||||
s->bits_sent = 0L;
|
s->bits_sent = 0L;
|
||||||
|
@ -867,7 +862,7 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send a stored block
|
* Send a stored block
|
||||||
*/
|
*/
|
||||||
void _tr_stored_block(s, buf, stored_len, last)
|
void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
charf *buf; /* input block */
|
charf *buf; /* input block */
|
||||||
ulg stored_len; /* length of input block */
|
ulg stored_len; /* length of input block */
|
||||||
|
@ -881,18 +876,20 @@ void _tr_stored_block(s, buf, stored_len, last)
|
||||||
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===========================================================================
|
||||||
|
* Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
|
||||||
|
*/
|
||||||
|
void ZLIB_INTERNAL _tr_flush_bits(s)
|
||||||
|
deflate_state *s;
|
||||||
|
{
|
||||||
|
bi_flush(s);
|
||||||
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Send one empty static block to give enough lookahead for inflate.
|
* Send one empty static block to give enough lookahead for inflate.
|
||||||
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
* This takes 10 bits, of which 7 may remain in the bit buffer.
|
||||||
* The current inflate code requires 9 bits of lookahead. If the
|
|
||||||
* last two codes for the previous block (real code plus EOB) were coded
|
|
||||||
* on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
|
|
||||||
* the last real code. In this case we send two empty static blocks instead
|
|
||||||
* of one. (There are no problems if the previous block is stored or fixed.)
|
|
||||||
* To simplify the code, we assume the worst case of last real code encoded
|
|
||||||
* on one bit only.
|
|
||||||
*/
|
*/
|
||||||
void _tr_align(s)
|
void ZLIB_INTERNAL _tr_align(s)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
{
|
{
|
||||||
send_bits(s, STATIC_TREES<<1, 3);
|
send_bits(s, STATIC_TREES<<1, 3);
|
||||||
|
@ -901,27 +898,13 @@ void _tr_align(s)
|
||||||
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
|
||||||
#endif
|
#endif
|
||||||
bi_flush(s);
|
bi_flush(s);
|
||||||
/* Of the 10 bits for the empty block, we have already sent
|
|
||||||
* (10 - bi_valid) bits. The lookahead for the last real code (before
|
|
||||||
* the EOB of the previous block) was thus at least one plus the length
|
|
||||||
* of the EOB plus what we have just sent of the empty static block.
|
|
||||||
*/
|
|
||||||
if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
|
|
||||||
send_bits(s, STATIC_TREES<<1, 3);
|
|
||||||
send_code(s, END_BLOCK, static_ltree);
|
|
||||||
#ifdef DEBUG
|
|
||||||
s->compressed_len += 10L;
|
|
||||||
#endif
|
|
||||||
bi_flush(s);
|
|
||||||
}
|
|
||||||
s->last_eob_len = 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
* Determine the best encoding for the current block: dynamic trees, static
|
* Determine the best encoding for the current block: dynamic trees, static
|
||||||
* trees or store, and output the encoded block to the zip file.
|
* trees or store, and output the encoded block to the zip file.
|
||||||
*/
|
*/
|
||||||
void _tr_flush_block(s, buf, stored_len, last)
|
void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
charf *buf; /* input block, or NULL if too old */
|
charf *buf; /* input block, or NULL if too old */
|
||||||
ulg stored_len; /* length of input block */
|
ulg stored_len; /* length of input block */
|
||||||
|
@ -1022,7 +1005,7 @@ void _tr_flush_block(s, buf, stored_len, last)
|
||||||
* Save the match info and tally the frequency counts. Return true if
|
* Save the match info and tally the frequency counts. Return true if
|
||||||
* the current block must be flushed.
|
* the current block must be flushed.
|
||||||
*/
|
*/
|
||||||
int _tr_tally (s, dist, lc)
|
int ZLIB_INTERNAL _tr_tally (s, dist, lc)
|
||||||
deflate_state *s;
|
deflate_state *s;
|
||||||
unsigned dist; /* distance of matched string */
|
unsigned dist; /* distance of matched string */
|
||||||
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
|
||||||
|
@ -1117,7 +1100,6 @@ local void compress_block(s, ltree, dtree)
|
||||||
} while (lx < s->last_lit);
|
} while (lx < s->last_lit);
|
||||||
|
|
||||||
send_code(s, END_BLOCK, ltree);
|
send_code(s, END_BLOCK, ltree);
|
||||||
s->last_eob_len = ltree[END_BLOCK].Len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -1225,7 +1207,6 @@ local void copy_block(s, buf, len, header)
|
||||||
int header; /* true if block header must be written */
|
int header; /* true if block header must be written */
|
||||||
{
|
{
|
||||||
bi_windup(s); /* align on byte boundary */
|
bi_windup(s); /* align on byte boundary */
|
||||||
s->last_eob_len = 8; /* enough lookahead for inflate */
|
|
||||||
|
|
||||||
if (header) {
|
if (header) {
|
||||||
put_short(s, (ush)len);
|
put_short(s, (ush)len);
|
||||||
|
|
|
@ -70,7 +70,7 @@ local const ct_data static_dtree[D_CODES] = {
|
||||||
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
|
||||||
};
|
};
|
||||||
|
|
||||||
const uch _dist_code[DIST_CODE_LEN] = {
|
const uch ZLIB_INTERNAL _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,
|
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,
|
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,
|
10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||||
|
@ -99,7 +99,7 @@ const uch _dist_code[DIST_CODE_LEN] = {
|
||||||
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]= {
|
const uch ZLIB_INTERNAL _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,
|
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,
|
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,
|
17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* zconf.h -- configuration of the zlib compression library
|
/* zconf.h -- configuration of the zlib compression library
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
* Copyright (C) 1995-2012 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
||||||
* this permanently in zconf.h using "./configure --zprefix".
|
* this permanently in zconf.h using "./configure --zprefix".
|
||||||
*/
|
*/
|
||||||
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
|
||||||
|
# define Z_PREFIX_SET
|
||||||
|
|
||||||
/* all linked symbols */
|
/* all linked symbols */
|
||||||
# define _dist_code z__dist_code
|
# define _dist_code z__dist_code
|
||||||
|
@ -27,9 +28,11 @@
|
||||||
# define adler32 z_adler32
|
# define adler32 z_adler32
|
||||||
# define adler32_combine z_adler32_combine
|
# define adler32_combine z_adler32_combine
|
||||||
# define adler32_combine64 z_adler32_combine64
|
# define adler32_combine64 z_adler32_combine64
|
||||||
# define compress z_compress
|
# ifndef Z_SOLO
|
||||||
# define compress2 z_compress2
|
# define compress z_compress
|
||||||
# define compressBound z_compressBound
|
# define compress2 z_compress2
|
||||||
|
# define compressBound z_compressBound
|
||||||
|
# endif
|
||||||
# define crc32 z_crc32
|
# define crc32 z_crc32
|
||||||
# define crc32_combine z_crc32_combine
|
# define crc32_combine z_crc32_combine
|
||||||
# define crc32_combine64 z_crc32_combine64
|
# define crc32_combine64 z_crc32_combine64
|
||||||
|
@ -40,44 +43,52 @@
|
||||||
# define deflateInit2_ z_deflateInit2_
|
# define deflateInit2_ z_deflateInit2_
|
||||||
# define deflateInit_ z_deflateInit_
|
# define deflateInit_ z_deflateInit_
|
||||||
# define deflateParams z_deflateParams
|
# define deflateParams z_deflateParams
|
||||||
|
# define deflatePending z_deflatePending
|
||||||
# define deflatePrime z_deflatePrime
|
# define deflatePrime z_deflatePrime
|
||||||
# define deflateReset z_deflateReset
|
# define deflateReset z_deflateReset
|
||||||
|
# define deflateResetKeep z_deflateResetKeep
|
||||||
# define deflateSetDictionary z_deflateSetDictionary
|
# define deflateSetDictionary z_deflateSetDictionary
|
||||||
# define deflateSetHeader z_deflateSetHeader
|
# define deflateSetHeader z_deflateSetHeader
|
||||||
# define deflateTune z_deflateTune
|
# define deflateTune z_deflateTune
|
||||||
# define deflate_copyright z_deflate_copyright
|
# define deflate_copyright z_deflate_copyright
|
||||||
# define get_crc_table z_get_crc_table
|
# define get_crc_table z_get_crc_table
|
||||||
# define gz_error z_gz_error
|
# ifndef Z_SOLO
|
||||||
# define gz_intmax z_gz_intmax
|
# define gz_error z_gz_error
|
||||||
# define gz_strwinerror z_gz_strwinerror
|
# define gz_intmax z_gz_intmax
|
||||||
# define gzbuffer z_gzbuffer
|
# define gz_strwinerror z_gz_strwinerror
|
||||||
# define gzclearerr z_gzclearerr
|
# define gzbuffer z_gzbuffer
|
||||||
# define gzclose z_gzclose
|
# define gzclearerr z_gzclearerr
|
||||||
# define gzclose_r z_gzclose_r
|
# define gzclose z_gzclose
|
||||||
# define gzclose_w z_gzclose_w
|
# define gzclose_r z_gzclose_r
|
||||||
# define gzdirect z_gzdirect
|
# define gzclose_w z_gzclose_w
|
||||||
# define gzdopen z_gzdopen
|
# define gzdirect z_gzdirect
|
||||||
# define gzeof z_gzeof
|
# define gzdopen z_gzdopen
|
||||||
# define gzerror z_gzerror
|
# define gzeof z_gzeof
|
||||||
# define gzflush z_gzflush
|
# define gzerror z_gzerror
|
||||||
# define gzgetc z_gzgetc
|
# define gzflush z_gzflush
|
||||||
# define gzgets z_gzgets
|
# define gzgetc z_gzgetc
|
||||||
# define gzoffset z_gzoffset
|
# define gzgetc_ z_gzgetc_
|
||||||
# define gzoffset64 z_gzoffset64
|
# define gzgets z_gzgets
|
||||||
# define gzopen z_gzopen
|
# define gzoffset z_gzoffset
|
||||||
# define gzopen64 z_gzopen64
|
# define gzoffset64 z_gzoffset64
|
||||||
# define gzprintf z_gzprintf
|
# define gzopen z_gzopen
|
||||||
# define gzputc z_gzputc
|
# define gzopen64 z_gzopen64
|
||||||
# define gzputs z_gzputs
|
# ifdef _WIN32
|
||||||
# define gzread z_gzread
|
# define gzopen_w z_gzopen_w
|
||||||
# define gzrewind z_gzrewind
|
# endif
|
||||||
# define gzseek z_gzseek
|
# define gzprintf z_gzprintf
|
||||||
# define gzseek64 z_gzseek64
|
# define gzputc z_gzputc
|
||||||
# define gzsetparams z_gzsetparams
|
# define gzputs z_gzputs
|
||||||
# define gztell z_gztell
|
# define gzread z_gzread
|
||||||
# define gztell64 z_gztell64
|
# define gzrewind z_gzrewind
|
||||||
# define gzungetc z_gzungetc
|
# define gzseek z_gzseek
|
||||||
# define gzwrite z_gzwrite
|
# define gzseek64 z_gzseek64
|
||||||
|
# define gzsetparams z_gzsetparams
|
||||||
|
# define gztell z_gztell
|
||||||
|
# define gztell64 z_gztell64
|
||||||
|
# define gzungetc z_gzungetc
|
||||||
|
# define gzwrite z_gzwrite
|
||||||
|
# endif
|
||||||
# define inflate z_inflate
|
# define inflate z_inflate
|
||||||
# define inflateBack z_inflateBack
|
# define inflateBack z_inflateBack
|
||||||
# define inflateBackEnd z_inflateBackEnd
|
# define inflateBackEnd z_inflateBackEnd
|
||||||
|
@ -95,13 +106,18 @@
|
||||||
# define inflateSync z_inflateSync
|
# define inflateSync z_inflateSync
|
||||||
# define inflateSyncPoint z_inflateSyncPoint
|
# define inflateSyncPoint z_inflateSyncPoint
|
||||||
# define inflateUndermine z_inflateUndermine
|
# define inflateUndermine z_inflateUndermine
|
||||||
|
# define inflateResetKeep z_inflateResetKeep
|
||||||
# define inflate_copyright z_inflate_copyright
|
# define inflate_copyright z_inflate_copyright
|
||||||
# define inflate_fast z_inflate_fast
|
# define inflate_fast z_inflate_fast
|
||||||
# define inflate_table z_inflate_table
|
# define inflate_table z_inflate_table
|
||||||
# define uncompress z_uncompress
|
# ifndef Z_SOLO
|
||||||
|
# define uncompress z_uncompress
|
||||||
|
# endif
|
||||||
# define zError z_zError
|
# define zError z_zError
|
||||||
# define zcalloc z_zcalloc
|
# ifndef Z_SOLO
|
||||||
# define zcfree z_zcfree
|
# define zcalloc z_zcalloc
|
||||||
|
# define zcfree z_zcfree
|
||||||
|
# endif
|
||||||
# define zlibCompileFlags z_zlibCompileFlags
|
# define zlibCompileFlags z_zlibCompileFlags
|
||||||
# define zlibVersion z_zlibVersion
|
# define zlibVersion z_zlibVersion
|
||||||
|
|
||||||
|
@ -111,7 +127,9 @@
|
||||||
# define alloc_func z_alloc_func
|
# define alloc_func z_alloc_func
|
||||||
# define charf z_charf
|
# define charf z_charf
|
||||||
# define free_func z_free_func
|
# define free_func z_free_func
|
||||||
# define gzFile z_gzFile
|
# ifndef Z_SOLO
|
||||||
|
# define gzFile z_gzFile
|
||||||
|
# endif
|
||||||
# define gz_header z_gz_header
|
# define gz_header z_gz_header
|
||||||
# define gz_headerp z_gz_headerp
|
# define gz_headerp z_gz_headerp
|
||||||
# define in_func z_in_func
|
# define in_func z_in_func
|
||||||
|
@ -197,6 +215,12 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ZLIB_CONST) && !defined(z_const)
|
||||||
|
# define z_const const
|
||||||
|
#else
|
||||||
|
# define z_const
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Some Mac compilers merge all .h files incorrectly: */
|
/* Some Mac compilers merge all .h files incorrectly: */
|
||||||
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
|
||||||
# define NO_DUMMY_DECL
|
# define NO_DUMMY_DECL
|
||||||
|
@ -243,6 +267,14 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_ARG /* function prototypes for stdarg */
|
||||||
|
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
|
# define Z_ARG(args) args
|
||||||
|
# else
|
||||||
|
# define Z_ARG(args) ()
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The following definitions for FAR are needed only for MSDOS mixed
|
/* The following definitions for FAR are needed only for MSDOS mixed
|
||||||
* model programming (small or medium model with some far allocations).
|
* model programming (small or medium model with some far allocations).
|
||||||
* This was tested only with MSC; for other MSDOS compilers you may have
|
* This was tested only with MSC; for other MSDOS compilers you may have
|
||||||
|
@ -315,10 +347,6 @@
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_VISIBILITY_PRAGMA
|
|
||||||
# define ZEXTERN __attribute__((visibility ("default"))) extern
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ZEXTERN
|
#ifndef ZEXTERN
|
||||||
# define ZEXTERN extern
|
# define ZEXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
@ -360,40 +388,102 @@ typedef uLong FAR uLongf;
|
||||||
typedef Byte *voidp;
|
typedef Byte *voidp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ./configure may #define Z_U4 here */
|
||||||
|
|
||||||
|
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
|
||||||
|
# include <limits.h>
|
||||||
|
# if (UINT_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned
|
||||||
|
# else
|
||||||
|
# if (ULONG_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned long
|
||||||
|
# else
|
||||||
|
# if (USHRT_MAX == 0xffffffffUL)
|
||||||
|
# define Z_U4 unsigned short
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef Z_U4
|
||||||
|
typedef Z_U4 z_crc_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long z_crc_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
|
||||||
# define Z_HAVE_UNISTD_H
|
# define Z_HAVE_UNISTD_H
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Z_HAVE_UNISTD_H
|
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
|
||||||
# include <sys/types.h> /* for off_t */
|
# define Z_HAVE_STDARG_H
|
||||||
# include <unistd.h> /* for SEEK_* and off_t */
|
#endif
|
||||||
# ifdef VMS
|
|
||||||
# include <unixio.h> /* for off_t */
|
#ifdef STDC
|
||||||
# endif
|
# ifndef Z_SOLO
|
||||||
# ifndef z_off_t
|
# include <sys/types.h> /* for off_t */
|
||||||
# define z_off_t off_t
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
#ifdef _WIN32
|
||||||
# include <sys/types.h>
|
# include <stddef.h> /* for wchar_t */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SEEK_SET
|
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
|
||||||
|
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
|
||||||
|
* though the former does not conform to the LFS document), but considering
|
||||||
|
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
|
||||||
|
* equivalently requesting no 64-bit operations
|
||||||
|
*/
|
||||||
|
#if defined(LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
|
||||||
|
# undef _LARGEFILE64_SOURCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
|
||||||
|
# define Z_HAVE_UNISTD_H
|
||||||
|
#endif
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
# if defined(Z_HAVE_UNISTD_H) || defined(LARGEFILE64_SOURCE)
|
||||||
|
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
|
||||||
|
# ifdef VMS
|
||||||
|
# include <unixio.h> /* for off_t */
|
||||||
|
# endif
|
||||||
|
# ifndef z_off_t
|
||||||
|
# define z_off_t off_t
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
|
||||||
|
# define Z_LFS64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
|
||||||
|
# define Z_LARGE64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
|
||||||
|
# define Z_WANT64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SEEK_SET) && !defined(Z_SOLO)
|
||||||
# define SEEK_SET 0 /* Seek from beginning of file. */
|
# define SEEK_SET 0 /* Seek from beginning of file. */
|
||||||
# define SEEK_CUR 1 /* Seek from current position. */
|
# define SEEK_CUR 1 /* Seek from current position. */
|
||||||
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef z_off_t
|
#ifndef z_off_t
|
||||||
# define z_off_t long
|
# define z_off_t long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__OS400__)
|
#if !defined(_WIN32) && defined(Z_LARGE64)
|
||||||
# define NO_vsnprintf
|
# define z_off64_t off64_t
|
||||||
#endif
|
#else
|
||||||
|
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
|
||||||
#if defined(__MVS__)
|
# define z_off64_t __int64
|
||||||
# define NO_vsnprintf
|
# else
|
||||||
|
# define z_off64_t z_off_t
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MVS linker does not support external names larger than 8 bytes */
|
/* MVS linker does not support external names larger than 8 bytes */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||||
version 1.2.4, Mar 14th, 2010
|
version 1.2.7, May 2nd, 2012
|
||||||
|
|
||||||
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied
|
This software is provided 'as-is', without any express or implied
|
||||||
warranty. In no event will the authors be held liable for any damages
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
@ -24,8 +24,8 @@
|
||||||
|
|
||||||
|
|
||||||
The data format used by the zlib library is described by RFCs (Request for
|
The data format used by the zlib library is described by RFCs (Request for
|
||||||
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
|
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
|
||||||
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZLIB_H
|
#ifndef ZLIB_H
|
||||||
|
@ -37,11 +37,11 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ZLIB_VERSION "1.2.4"
|
#define ZLIB_VERSION "1.2.7"
|
||||||
#define ZLIB_VERNUM 0x1240
|
#define ZLIB_VERNUM 0x1270
|
||||||
#define ZLIB_VER_MAJOR 1
|
#define ZLIB_VER_MAJOR 1
|
||||||
#define ZLIB_VER_MINOR 2
|
#define ZLIB_VER_MINOR 2
|
||||||
#define ZLIB_VER_REVISION 4
|
#define ZLIB_VER_REVISION 7
|
||||||
#define ZLIB_VER_SUBREVISION 0
|
#define ZLIB_VER_SUBREVISION 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
|
||||||
struct internal_state;
|
struct internal_state;
|
||||||
|
|
||||||
typedef struct z_stream_s {
|
typedef struct z_stream_s {
|
||||||
Bytef *next_in; /* next input byte */
|
z_const Bytef *next_in; /* next input byte */
|
||||||
uInt avail_in; /* number of bytes available at next_in */
|
uInt avail_in; /* number of bytes available at next_in */
|
||||||
uLong total_in; /* total nb of input bytes read so far */
|
uLong total_in; /* total number of input bytes read so far */
|
||||||
|
|
||||||
Bytef *next_out; /* next output byte should be put there */
|
Bytef *next_out; /* next output byte should be put there */
|
||||||
uInt avail_out; /* remaining free space at next_out */
|
uInt avail_out; /* remaining free space at next_out */
|
||||||
uLong total_out; /* total nb of bytes output so far */
|
uLong total_out; /* total number of bytes output so far */
|
||||||
|
|
||||||
char *msg; /* last error message, NULL if no error */
|
z_const char *msg; /* last error message, NULL if no error */
|
||||||
struct internal_state FAR *state; /* not visible by applications */
|
struct internal_state FAR *state; /* not visible by applications */
|
||||||
|
|
||||||
alloc_func zalloc; /* used to allocate the internal state */
|
alloc_func zalloc; /* used to allocate the internal state */
|
||||||
|
@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
|
||||||
|
|
||||||
Z_FINISH can be used immediately after deflateInit if all the compression
|
Z_FINISH can be used immediately after deflateInit if all the compression
|
||||||
is to be done in a single step. In this case, avail_out must be at least the
|
is to be done in a single step. In this case, avail_out must be at least the
|
||||||
value returned by deflateBound (see below). If deflate does not return
|
value returned by deflateBound (see below). Then deflate is guaranteed to
|
||||||
Z_STREAM_END, then it must be called again as described above.
|
return Z_STREAM_END. If not enough output space is provided, deflate will
|
||||||
|
not return Z_STREAM_END, and it must be called again as described above.
|
||||||
|
|
||||||
deflate() sets strm->adler to the adler32 checksum of all input read
|
deflate() sets strm->adler to the adler32 checksum of all input read
|
||||||
so far (that is, total_in bytes).
|
so far (that is, total_in bytes).
|
||||||
|
@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||||
error. However if all decompression is to be performed in a single step (a
|
error. However if all decompression is to be performed in a single step (a
|
||||||
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
single call of inflate), the parameter flush should be set to Z_FINISH. In
|
||||||
this case all pending input is processed and all pending output is flushed;
|
this case all pending input is processed and all pending output is flushed;
|
||||||
avail_out must be large enough to hold all the uncompressed data. (The size
|
avail_out must be large enough to hold all of the uncompressed data for the
|
||||||
of the uncompressed data may have been saved by the compressor for this
|
operation to complete. (The size of the uncompressed data may have been
|
||||||
purpose.) The next operation on this stream must be inflateEnd to deallocate
|
saved by the compressor for this purpose.) The use of Z_FINISH is not
|
||||||
the decompression state. The use of Z_FINISH is never required, but can be
|
required to perform an inflation in one step. However it may be used to
|
||||||
used to inform inflate that a faster approach may be used for the single
|
inform inflate that a faster approach can be used for the single inflate()
|
||||||
inflate() call.
|
call. Z_FINISH also informs inflate to not maintain a sliding window if the
|
||||||
|
stream completes, which reduces inflate's memory footprint. If the stream
|
||||||
|
does not complete, either because not all of the stream is provided or not
|
||||||
|
enough output space is provided, then a sliding window will be allocated and
|
||||||
|
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
|
||||||
|
been used.
|
||||||
|
|
||||||
In this implementation, inflate() always flushes as much output as
|
In this implementation, inflate() always flushes as much output as
|
||||||
possible to the output buffer, and always uses the faster approach on the
|
possible to the output buffer, and always uses the faster approach on the
|
||||||
first call. So the only effect of the flush parameter in this implementation
|
first call. So the effects of the flush parameter in this implementation are
|
||||||
is on the return value of inflate(), as noted below, or when it returns early
|
on the return value of inflate() as noted below, when inflate() returns early
|
||||||
because Z_BLOCK or Z_TREES is used.
|
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
|
||||||
|
memory for a sliding window when Z_FINISH is used.
|
||||||
|
|
||||||
If a preset dictionary is needed after this call (see inflateSetDictionary
|
If a preset dictionary is needed after this call (see inflateSetDictionary
|
||||||
below), inflate sets strm->adler to the adler32 checksum of the dictionary
|
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
|
||||||
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
|
||||||
strm->adler to the adler32 checksum of all output produced so far (that is,
|
strm->adler to the Adler-32 checksum of all output produced so far (that is,
|
||||||
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
|
||||||
below. At the end of the stream, inflate() checks that its computed adler32
|
below. At the end of the stream, inflate() checks that its computed adler32
|
||||||
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
checksum is equal to that saved by the compressor and returns Z_STREAM_END
|
||||||
|
@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
|
||||||
initializing with inflateInit2(). Any information contained in the gzip
|
initializing with inflateInit2(). Any information contained in the gzip
|
||||||
header is not retained, so applications that need that information should
|
header is not retained, so applications that need that information should
|
||||||
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
instead use raw inflate, see inflateInit2() below, or inflateBack() and
|
||||||
perform their own processing of the gzip header and trailer.
|
perform their own processing of the gzip header and trailer. When processing
|
||||||
|
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
|
||||||
|
producted so far. The CRC-32 is checked against the gzip trailer.
|
||||||
|
|
||||||
inflate() returns Z_OK if some progress has been made (more input processed
|
inflate() returns Z_OK if some progress has been made (more input processed
|
||||||
or more output produced), Z_STREAM_END if the end of the compressed data has
|
or more output produced), Z_STREAM_END if the end of the compressed data has
|
||||||
|
@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||||
uInt dictLength));
|
uInt dictLength));
|
||||||
/*
|
/*
|
||||||
Initializes the compression dictionary from the given byte sequence
|
Initializes the compression dictionary from the given byte sequence
|
||||||
without producing any compressed output. This function must be called
|
without producing any compressed output. When using the zlib format, this
|
||||||
immediately after deflateInit, deflateInit2 or deflateReset, before any call
|
function must be called immediately after deflateInit, deflateInit2 or
|
||||||
of deflate. The compressor and decompressor must use exactly the same
|
deflateReset, and before any call of deflate. When doing raw deflate, this
|
||||||
dictionary (see inflateSetDictionary).
|
function must be called either before any call of deflate, or immediately
|
||||||
|
after the completion of a deflate block, i.e. after all input has been
|
||||||
|
consumed and all output has been delivered when using any of the flush
|
||||||
|
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
|
||||||
|
compressor and decompressor must use exactly the same dictionary (see
|
||||||
|
inflateSetDictionary).
|
||||||
|
|
||||||
The dictionary should consist of strings (byte sequences) that are likely
|
The dictionary should consist of strings (byte sequences) that are likely
|
||||||
to be encountered later in the data to be compressed, with the most commonly
|
to be encountered later in the data to be compressed, with the most commonly
|
||||||
|
@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
|
||||||
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
|
||||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||||
inconsistent (for example if deflate has already been called for this stream
|
inconsistent (for example if deflate has already been called for this stream
|
||||||
or if the compression method is bsort). deflateSetDictionary does not
|
or if not at a block boundary for raw deflate). deflateSetDictionary does
|
||||||
perform any compression: this will be done by deflate().
|
not perform any compression: this will be done by deflate().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
|
||||||
|
@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
|
||||||
deflation of sourceLen bytes. It must be called after deflateInit() or
|
deflation of sourceLen bytes. It must be called after deflateInit() or
|
||||||
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
deflateInit2(), and after deflateSetHeader(), if used. This would be used
|
||||||
to allocate an output buffer for deflation in a single pass, and so would be
|
to allocate an output buffer for deflation in a single pass, and so would be
|
||||||
called before deflate().
|
called before deflate(). If that first deflate() call is provided the
|
||||||
|
sourceLen input bytes, an output buffer allocated to the size returned by
|
||||||
|
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
|
||||||
|
to return Z_STREAM_END. Note that it is possible for the compressed size to
|
||||||
|
be larger than the value returned by deflateBound() if flush options other
|
||||||
|
than Z_FINISH or Z_NO_FLUSH are used.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
|
||||||
|
unsigned *pending,
|
||||||
|
int *bits));
|
||||||
|
/*
|
||||||
|
deflatePending() returns the number of bytes and bits of output that have
|
||||||
|
been generated, but not yet provided in the available output. The bytes not
|
||||||
|
provided would be due to the available output space having being consumed.
|
||||||
|
The number of bits of output not provided are between 0 and 7, where they
|
||||||
|
await more bits to join them in order to fill out a full byte. If pending
|
||||||
|
or bits are Z_NULL, then those values are not set.
|
||||||
|
|
||||||
|
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
|
||||||
|
stream state was inconsistent.
|
||||||
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||||
int bits,
|
int bits,
|
||||||
int value));
|
int value));
|
||||||
|
@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
|
||||||
than or equal to 16, and that many of the least significant bits of value
|
than or equal to 16, and that many of the least significant bits of value
|
||||||
will be inserted in the output.
|
will be inserted in the output.
|
||||||
|
|
||||||
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
|
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
|
||||||
stream state was inconsistent.
|
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
|
||||||
|
source stream state was inconsistent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
|
||||||
|
@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||||
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
|
||||||
can be determined from the adler32 value returned by that call of inflate.
|
can be determined from the adler32 value returned by that call of inflate.
|
||||||
The compressor and decompressor must use exactly the same dictionary (see
|
The compressor and decompressor must use exactly the same dictionary (see
|
||||||
deflateSetDictionary). For raw inflate, this function can be called
|
deflateSetDictionary). For raw inflate, this function can be called at any
|
||||||
immediately after inflateInit2() or inflateReset() and before any call of
|
time to set the dictionary. If the provided dictionary is smaller than the
|
||||||
inflate() to set the dictionary. The application must insure that the
|
window and there is already data in the window, then the provided dictionary
|
||||||
dictionary that was used for compression is provided.
|
will amend what's there. The application must insure that the dictionary
|
||||||
|
that was used for compression is provided.
|
||||||
|
|
||||||
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
|
||||||
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
|
||||||
|
@ -805,17 +841,21 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
|
||||||
/*
|
/*
|
||||||
Skips invalid compressed data until a full flush point (see above the
|
Skips invalid compressed data until a possible full flush point (see above
|
||||||
description of deflate with Z_FULL_FLUSH) can be found, or until all
|
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
|
||||||
available input is skipped. No output is provided.
|
available input is skipped. No output is provided.
|
||||||
|
|
||||||
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
|
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
|
||||||
if no more input was provided, Z_DATA_ERROR if no flush point has been
|
All full flush points have this pattern, but not all occurences of this
|
||||||
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
|
pattern are full flush points.
|
||||||
success case, the application may save the current current value of total_in
|
|
||||||
which indicates where valid compressed data was found. In the error case,
|
inflateSync returns Z_OK if a possible full flush point has been found,
|
||||||
the application may repeatedly call inflateSync, providing more input each
|
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
|
||||||
time, until success or end of the input data.
|
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
|
||||||
|
In the success case, the application may save the current current value of
|
||||||
|
total_in which indicates where valid compressed data was found. In the
|
||||||
|
error case, the application may repeatedly call inflateSync, providing more
|
||||||
|
input each time, until success or end of the input data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
|
||||||
|
@ -962,7 +1002,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
|
||||||
See inflateBack() for the usage of these routines.
|
See inflateBack() for the usage of these routines.
|
||||||
|
|
||||||
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
|
||||||
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
|
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
|
||||||
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
allocated, or Z_VERSION_ERROR if the version of the library does not match
|
||||||
the version of the header file.
|
the version of the header file.
|
||||||
*/
|
*/
|
||||||
|
@ -1088,6 +1128,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
|
||||||
27-31: 0 (reserved)
|
27-31: 0 (reserved)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
|
||||||
/* utility functions */
|
/* utility functions */
|
||||||
|
|
||||||
|
@ -1149,10 +1190,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||||
|
|
||||||
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
|
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
|
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 or incomplete.
|
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
|
||||||
|
the case where there is not enough room, uncompress() will fill the output
|
||||||
|
buffer with the uncompressed data up to that point.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* gzip file access functions */
|
/* gzip file access functions */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1162,7 +1204,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
|
||||||
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
wrapper, documented in RFC 1952, wrapped around a deflate stream.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef voidp gzFile; /* opaque gzip file descriptor */
|
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||||
|
@ -1172,13 +1214,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
|
||||||
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
|
||||||
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
|
||||||
for fixed code compression as in "wb9F". (See the description of
|
for fixed code compression as in "wb9F". (See the description of
|
||||||
deflateInit2 for more information about the strategy parameter.) Also "a"
|
deflateInit2 for more information about the strategy parameter.) 'T' will
|
||||||
can be used instead of "w" to request that the gzip stream that will be
|
request transparent writing or appending with no compression and not using
|
||||||
written be appended to the file. "+" will result in an error, since reading
|
the gzip format.
|
||||||
and writing to the same gzip file is not supported.
|
|
||||||
|
"a" can be used instead of "w" to request that the gzip stream that will
|
||||||
|
be written be appended to the file. "+" will result in an error, since
|
||||||
|
reading and writing to the same gzip file is not supported. The addition of
|
||||||
|
"x" when writing will create the file exclusively, which fails if the file
|
||||||
|
already exists. On systems that support it, the addition of "e" when
|
||||||
|
reading or writing will set the flag to close the file on an execve() call.
|
||||||
|
|
||||||
|
These functions, as well as gzip, will read and decode a sequence of gzip
|
||||||
|
streams in a file. The append function of gzopen() can be used to create
|
||||||
|
such a file. (Also see gzflush() for another way to do this.) When
|
||||||
|
appending, gzopen does not test whether the file begins with a gzip stream,
|
||||||
|
nor does it look for the end of the gzip streams to begin appending. gzopen
|
||||||
|
will simply append a gzip stream to the existing file.
|
||||||
|
|
||||||
gzopen can be used to read a file which is not in gzip format; in this
|
gzopen can be used to read a file which is not in gzip format; in this
|
||||||
case gzread will directly read from the file without decompression.
|
case gzread will directly read from the file without decompression. When
|
||||||
|
reading, this will be detected automatically by looking for the magic two-
|
||||||
|
byte gzip header.
|
||||||
|
|
||||||
gzopen returns NULL if the file could not be opened, if there was
|
gzopen returns NULL if the file could not be opened, if there was
|
||||||
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
insufficient memory to allocate the gzFile state, or if an invalid mode was
|
||||||
|
@ -1197,7 +1254,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
|
||||||
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
|
||||||
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
|
||||||
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
mode);. The duplicated descriptor should be saved to avoid a leak, since
|
||||||
gzdopen does not close fd if it fails.
|
gzdopen does not close fd if it fails. If you are using fileno() to get the
|
||||||
|
file descriptor from a FILE *, then you will have to use dup() to avoid
|
||||||
|
double-close()ing the file descriptor. Both gzclose() and fclose() will
|
||||||
|
close the associated file descriptor, so they need to have different file
|
||||||
|
descriptors.
|
||||||
|
|
||||||
gzdopen returns NULL if there was insufficient memory to allocate the
|
gzdopen returns NULL if there was insufficient memory to allocate the
|
||||||
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
|
||||||
|
@ -1235,14 +1296,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
|
||||||
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
|
||||||
/*
|
/*
|
||||||
Reads the given number of uncompressed bytes from the compressed file. If
|
Reads the given number of uncompressed bytes from the compressed file. If
|
||||||
the input file was not in gzip format, gzread copies the given number of
|
the input file is not in gzip format, gzread copies the given number of
|
||||||
bytes into the buffer.
|
bytes into the buffer directly from the file.
|
||||||
|
|
||||||
After reaching the end of a gzip stream in the input, gzread will continue
|
After reaching the end of a gzip stream in the input, gzread will continue
|
||||||
to read, looking for another gzip stream, or failing that, reading the rest
|
to read, looking for another gzip stream. Any number of gzip streams may be
|
||||||
of the input file directly without decompression. The entire input file
|
concatenated in the input file, and will all be decompressed by gzread().
|
||||||
will be read if gzread is called until it returns less than the requested
|
If something other than a gzip stream is encountered after a gzip stream,
|
||||||
len.
|
that remaining trailing garbage is ignored (and no error is returned).
|
||||||
|
|
||||||
|
gzread can be used to read a gzip file that is being concurrently written.
|
||||||
|
Upon reaching the end of the input, gzread will return with the available
|
||||||
|
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
|
||||||
|
gzclearerr can be used to clear the end of file indicator in order to permit
|
||||||
|
gzread to be tried again. Z_OK indicates that a gzip stream was completed
|
||||||
|
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
|
||||||
|
middle of a gzip stream. Note that gzread does not return -1 in the event
|
||||||
|
of an incomplete gzip stream. This error is deferred until gzclose(), which
|
||||||
|
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
|
||||||
|
stream. Alternatively, gzerror can be used before gzclose to detect this
|
||||||
|
case.
|
||||||
|
|
||||||
gzread returns the number of uncompressed bytes actually read, less than
|
gzread returns the number of uncompressed bytes actually read, less than
|
||||||
len for end of file, or -1 for error.
|
len for end of file, or -1 for error.
|
||||||
|
@ -1256,7 +1329,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
|
||||||
error.
|
error.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
|
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
|
||||||
/*
|
/*
|
||||||
Converts, formats, and writes the arguments to the compressed file under
|
Converts, formats, and writes the arguments to the compressed file under
|
||||||
control of the format string, as in fprintf. gzprintf returns the number of
|
control of the format string, as in fprintf. gzprintf returns the number of
|
||||||
|
@ -1301,7 +1374,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
|
||||||
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
|
||||||
/*
|
/*
|
||||||
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
Reads one byte from the compressed file. gzgetc returns this byte or -1
|
||||||
in case of end of file or error.
|
in case of end of file or error. This is implemented as a macro for speed.
|
||||||
|
As such, it does not do all of the checking the other functions do. I.e.
|
||||||
|
it does not check to see if file is NULL, nor whether the structure file
|
||||||
|
points to has been clobbered or not.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
|
||||||
|
@ -1397,9 +1473,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
|
||||||
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||||
/*
|
/*
|
||||||
Returns true (1) if file is being copied directly while reading, or false
|
Returns true (1) if file is being copied directly while reading, or false
|
||||||
(0) if file is a gzip stream being decompressed. This state can change from
|
(0) if file is a gzip stream being decompressed.
|
||||||
false to true while reading the input file if the end of a gzip stream is
|
|
||||||
reached, but is followed by data that is not another gzip stream.
|
|
||||||
|
|
||||||
If the input file is empty, gzdirect() will return true, since the input
|
If the input file is empty, gzdirect() will return true, since the input
|
||||||
does not contain a gzip stream.
|
does not contain a gzip stream.
|
||||||
|
@ -1408,6 +1482,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
|
||||||
cause buffers to be allocated to allow reading the file to determine if it
|
cause buffers to be allocated to allow reading the file to determine if it
|
||||||
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
is a gzip file. Therefore if gzbuffer() is used, it should be called before
|
||||||
gzdirect().
|
gzdirect().
|
||||||
|
|
||||||
|
When writing, gzdirect() returns true (1) if transparent writing was
|
||||||
|
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
|
||||||
|
gzdirect() is not needed when writing. Transparent writing must be
|
||||||
|
explicitly requested, so the application already knows the answer. When
|
||||||
|
linking statically, using gzdirect() will include all of the zlib code for
|
||||||
|
gzip file reading and decompression, which may not be desired.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||||
|
@ -1419,7 +1500,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
|
||||||
must not be called more than once on the same allocation.
|
must not be called more than once on the same allocation.
|
||||||
|
|
||||||
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
|
||||||
file operation error, or Z_OK on success.
|
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
|
||||||
|
last read ended in the middle of a gzip stream, or Z_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
|
||||||
|
@ -1457,6 +1539,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
|
||||||
file that is being written concurrently.
|
file that is being written concurrently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
||||||
/* checksum functions */
|
/* checksum functions */
|
||||||
|
|
||||||
|
@ -1492,16 +1575,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
|
||||||
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
|
||||||
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
|
||||||
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
|
||||||
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
|
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
|
||||||
|
that the z_off_t type (like off_t) is a signed integer. If len2 is
|
||||||
|
negative, the result has no meaning or utility.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
|
||||||
/*
|
/*
|
||||||
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
Update a running CRC-32 with the bytes buf[0..len-1] and return the
|
||||||
updated CRC-32. If buf is Z_NULL, this function returns the required
|
updated CRC-32. If buf is Z_NULL, this function returns the required
|
||||||
initial value for the for the crc. Pre- and post-conditioning (one's
|
initial value for the crc. Pre- and post-conditioning (one's complement) is
|
||||||
complement) is performed within this function so it shouldn't be done by the
|
performed within this function so it shouldn't be done by the application.
|
||||||
application.
|
|
||||||
|
|
||||||
Usage example:
|
Usage example:
|
||||||
|
|
||||||
|
@ -1544,41 +1628,81 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
const char *version,
|
const char *version,
|
||||||
int stream_size));
|
int stream_size));
|
||||||
#define deflateInit(strm, level) \
|
#define deflateInit(strm, level) \
|
||||||
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
|
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define inflateInit(strm) \
|
#define inflateInit(strm) \
|
||||||
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
|
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
|
||||||
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
|
||||||
(strategy), ZLIB_VERSION, sizeof(z_stream))
|
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
#define inflateInit2(strm, windowBits) \
|
#define inflateInit2(strm, windowBits) \
|
||||||
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
|
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
|
||||||
|
(int)sizeof(z_stream))
|
||||||
#define inflateBackInit(strm, windowBits, window) \
|
#define inflateBackInit(strm, windowBits, window) \
|
||||||
inflateBackInit_((strm), (windowBits), (window), \
|
inflateBackInit_((strm), (windowBits), (window), \
|
||||||
ZLIB_VERSION, sizeof(z_stream))
|
ZLIB_VERSION, (int)sizeof(z_stream))
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
#ifndef Z_SOLO
|
||||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
|
||||||
ZEXTERN off64_t ZEXPORT gzseek64 OF((gzFile, off64_t, int));
|
/* gzgetc() macro and its supporting function and exposed data structure. Note
|
||||||
ZEXTERN off64_t ZEXPORT gztell64 OF((gzFile));
|
* that the real internal state is much larger than the exposed structure.
|
||||||
ZEXTERN off64_t ZEXPORT gzoffset64 OF((gzFile));
|
* This abbreviated structure exposes just enough for the gzgetc() macro. The
|
||||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off64_t));
|
* user should not mess with these exposed elements, since their names or
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off64_t));
|
* behavior could change in the future, perhaps even capriciously. They can
|
||||||
|
* only be used by the gzgetc() macro. You have been warned.
|
||||||
|
*/
|
||||||
|
struct gzFile_s {
|
||||||
|
unsigned have;
|
||||||
|
unsigned char *next;
|
||||||
|
z_off64_t pos;
|
||||||
|
};
|
||||||
|
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
|
||||||
|
#ifdef Z_PREFIX_SET
|
||||||
|
# undef z_gzgetc
|
||||||
|
# define z_gzgetc(g) \
|
||||||
|
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||||
|
#else
|
||||||
|
# define gzgetc(g) \
|
||||||
|
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS == 64
|
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
|
||||||
# define gzopen gzopen64
|
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
|
||||||
# define gzseek gzseek64
|
* both are true, the application gets the *64 functions, and the regular
|
||||||
# define gztell gztell64
|
* functions are changed to 64 bits) -- in case these are set on systems
|
||||||
# define gzoffset gzoffset64
|
* without large file support, _LFS64_LARGEFILE must also be true
|
||||||
# define adler32_combine adler32_combine64
|
*/
|
||||||
# define crc32_combine crc32_combine64
|
#ifdef Z_LARGE64
|
||||||
# ifndef _LARGEFILE64_SOURCE
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
|
||||||
|
ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
|
||||||
|
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
|
||||||
|
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
|
||||||
|
# ifdef Z_PREFIX_SET
|
||||||
|
# define z_gzopen z_gzopen64
|
||||||
|
# define z_gzseek z_gzseek64
|
||||||
|
# define z_gztell z_gztell64
|
||||||
|
# define z_gzoffset z_gzoffset64
|
||||||
|
# define z_adler32_combine z_adler32_combine64
|
||||||
|
# define z_crc32_combine z_crc32_combine64
|
||||||
|
# else
|
||||||
|
# define gzopen gzopen64
|
||||||
|
# define gzseek gzseek64
|
||||||
|
# define gztell gztell64
|
||||||
|
# define gzoffset gzoffset64
|
||||||
|
# define adler32_combine adler32_combine64
|
||||||
|
# define crc32_combine crc32_combine64
|
||||||
|
# endif
|
||||||
|
# ifndef Z_LARGE64
|
||||||
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
|
||||||
ZEXTERN off_t ZEXPORT gzseek64 OF((gzFile, off_t, int));
|
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
|
||||||
ZEXTERN off_t ZEXPORT gztell64 OF((gzFile));
|
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
|
||||||
ZEXTERN off_t ZEXPORT gzoffset64 OF((gzFile));
|
ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
|
||||||
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, off_t));
|
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, off_t));
|
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
|
ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
|
||||||
|
@ -1589,14 +1713,29 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
|
||||||
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else /* Z_SOLO */
|
||||||
|
|
||||||
|
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
|
||||||
|
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
||||||
|
/* hack for buggy compilers */
|
||||||
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
|
||||||
struct internal_state {int dummy;}; /* hack for buggy compilers */
|
struct internal_state {int dummy;};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* undocumented functions */
|
||||||
ZEXTERN const char * ZEXPORT zError OF((int));
|
ZEXTERN const char * ZEXPORT zError OF((int));
|
||||||
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
|
||||||
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
|
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
|
||||||
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
|
||||||
|
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
|
||||||
|
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
|
||||||
|
#if defined(_WIN32) && !defined(Z_SOLO)
|
||||||
|
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
|
||||||
|
const char *mode));
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
/* zutil.c -- target dependent utility functions for the compression library
|
/* zutil.c -- target dependent utility functions for the compression library
|
||||||
* Copyright (C) 1995-2005 Jean-loup Gailly.
|
* Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* @(#) $Id$ */
|
/* @(#) $Id$ */
|
||||||
|
|
||||||
#include "zutil.h"
|
#include "zutil.h"
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
# include "gzguts.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_DUMMY_DECL
|
#ifndef NO_DUMMY_DECL
|
||||||
struct internal_state {int dummy;}; /* for buggy compilers */
|
struct internal_state {int dummy;}; /* for buggy compilers */
|
||||||
|
@ -85,27 +88,27 @@ uLong ZEXPORT zlibCompileFlags()
|
||||||
#ifdef FASTEST
|
#ifdef FASTEST
|
||||||
flags += 1L << 21;
|
flags += 1L << 21;
|
||||||
#endif
|
#endif
|
||||||
#ifdef STDC
|
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
|
||||||
# ifdef NO_vsnprintf
|
# ifdef NO_vsnprintf
|
||||||
flags += 1L << 25;
|
flags += 1L << 25;
|
||||||
# ifdef HAS_vsprintf_void
|
# ifdef HAS_vsprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# ifdef HAS_vsnprintf_void
|
# ifdef HAS_vsnprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
flags += 1L << 24;
|
flags += 1L << 24;
|
||||||
# ifdef NO_snprintf
|
# ifdef NO_snprintf
|
||||||
flags += 1L << 25;
|
flags += 1L << 25;
|
||||||
# ifdef HAS_sprintf_void
|
# ifdef HAS_sprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# else
|
# else
|
||||||
# ifdef HAS_snprintf_void
|
# ifdef HAS_snprintf_void
|
||||||
flags += 1L << 26;
|
flags += 1L << 26;
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -117,9 +120,9 @@ uLong ZEXPORT zlibCompileFlags()
|
||||||
# ifndef verbose
|
# ifndef verbose
|
||||||
# define verbose 0
|
# define verbose 0
|
||||||
# endif
|
# endif
|
||||||
int z_verbose = verbose;
|
int ZLIB_INTERNAL z_verbose = verbose;
|
||||||
|
|
||||||
void z_error (m)
|
void ZLIB_INTERNAL z_error (m)
|
||||||
char *m;
|
char *m;
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s\n", m);
|
fprintf(stderr, "%s\n", m);
|
||||||
|
@ -146,7 +149,7 @@ const char * ZEXPORT zError(err)
|
||||||
|
|
||||||
#ifndef HAVE_MEMCPY
|
#ifndef HAVE_MEMCPY
|
||||||
|
|
||||||
void zmemcpy(dest, source, len)
|
void ZLIB_INTERNAL zmemcpy(dest, source, len)
|
||||||
Bytef* dest;
|
Bytef* dest;
|
||||||
const Bytef* source;
|
const Bytef* source;
|
||||||
uInt len;
|
uInt len;
|
||||||
|
@ -157,7 +160,7 @@ void zmemcpy(dest, source, len)
|
||||||
} while (--len != 0);
|
} while (--len != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int zmemcmp(s1, s2, len)
|
int ZLIB_INTERNAL zmemcmp(s1, s2, len)
|
||||||
const Bytef* s1;
|
const Bytef* s1;
|
||||||
const Bytef* s2;
|
const Bytef* s2;
|
||||||
uInt len;
|
uInt len;
|
||||||
|
@ -170,7 +173,7 @@ int zmemcmp(s1, s2, len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zmemzero(dest, len)
|
void ZLIB_INTERNAL zmemzero(dest, len)
|
||||||
Bytef* dest;
|
Bytef* dest;
|
||||||
uInt len;
|
uInt len;
|
||||||
{
|
{
|
||||||
|
@ -181,6 +184,7 @@ void zmemzero(dest, len)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
|
|
||||||
#ifdef SYS16BIT
|
#ifdef SYS16BIT
|
||||||
|
|
||||||
|
@ -213,7 +217,7 @@ local ptr_table table[MAX_PTR];
|
||||||
* a protected system like OS/2. Use Microsoft C instead.
|
* a protected system like OS/2. Use Microsoft C instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||||
{
|
{
|
||||||
voidpf buf = opaque; /* just to make some compilers happy */
|
voidpf buf = opaque; /* just to make some compilers happy */
|
||||||
ulg bsize = (ulg)items*size;
|
ulg bsize = (ulg)items*size;
|
||||||
|
@ -237,7 +241,7 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zcfree (voidpf opaque, voidpf ptr)
|
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
if (*(ush*)&ptr != 0) { /* object < 64K */
|
if (*(ush*)&ptr != 0) { /* object < 64K */
|
||||||
|
@ -272,13 +276,13 @@ void zcfree (voidpf opaque, voidpf ptr)
|
||||||
# define _hfree hfree
|
# define _hfree hfree
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
|
voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
|
||||||
{
|
{
|
||||||
if (opaque) opaque = 0; /* to make compiler happy */
|
if (opaque) opaque = 0; /* to make compiler happy */
|
||||||
return _halloc((long)items, size);
|
return _halloc((long)items, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zcfree (voidpf opaque, voidpf ptr)
|
void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
|
||||||
{
|
{
|
||||||
if (opaque) opaque = 0; /* to make compiler happy */
|
if (opaque) opaque = 0; /* to make compiler happy */
|
||||||
_hfree(ptr);
|
_hfree(ptr);
|
||||||
|
@ -297,7 +301,7 @@ extern voidp calloc OF((uInt items, uInt size));
|
||||||
extern void free OF((voidpf ptr));
|
extern void free OF((voidpf ptr));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
voidpf zcalloc (opaque, items, size)
|
voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
|
||||||
voidpf opaque;
|
voidpf opaque;
|
||||||
unsigned items;
|
unsigned items;
|
||||||
unsigned size;
|
unsigned size;
|
||||||
|
@ -307,7 +311,7 @@ voidpf zcalloc (opaque, items, size)
|
||||||
(voidpf)calloc(items, size);
|
(voidpf)calloc(items, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zcfree (opaque, ptr)
|
void ZLIB_INTERNAL zcfree (opaque, ptr)
|
||||||
voidpf opaque;
|
voidpf opaque;
|
||||||
voidpf ptr;
|
voidpf ptr;
|
||||||
{
|
{
|
||||||
|
@ -316,3 +320,5 @@ void zcfree (opaque, ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MY_ZCALLOC */
|
#endif /* MY_ZCALLOC */
|
||||||
|
|
||||||
|
#endif /* !Z_SOLO */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* zutil.h -- internal interface and configuration of the compression library
|
/* zutil.h -- internal interface and configuration of the compression library
|
||||||
* Copyright (C) 1995-2010 Jean-loup Gailly.
|
* Copyright (C) 1995-2012 Jean-loup Gailly.
|
||||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -13,10 +13,15 @@
|
||||||
#ifndef ZUTIL_H
|
#ifndef ZUTIL_H
|
||||||
#define ZUTIL_H
|
#define ZUTIL_H
|
||||||
|
|
||||||
#define ZLIB_INTERNAL
|
#ifdef HAVE_HIDDEN
|
||||||
|
# define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
|
||||||
|
#else
|
||||||
|
# define ZLIB_INTERNAL
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#ifdef STDC
|
#if defined(STDC) && !defined(Z_SOLO)
|
||||||
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
# if !(defined(_WIN32_WCE) && defined(_MSC_VER))
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
# endif
|
# endif
|
||||||
|
@ -24,17 +29,8 @@
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(UNDER_CE) && defined(NO_ERRNO_H)
|
#ifdef Z_SOLO
|
||||||
# define zseterrno(ERR) SetLastError((DWORD)(ERR))
|
typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */
|
||||||
# define zerrno() ((int)GetLastError())
|
|
||||||
#else
|
|
||||||
# ifdef NO_ERRNO_H
|
|
||||||
extern int errno;
|
|
||||||
# else
|
|
||||||
# include <errno.h>
|
|
||||||
# endif
|
|
||||||
# define zseterrno(ERR) do { errno = (ERR); } while (0)
|
|
||||||
# define zerrno() errno
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef local
|
#ifndef local
|
||||||
|
@ -86,16 +82,18 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
|
||||||
# define OS_CODE 0x00
|
# define OS_CODE 0x00
|
||||||
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
# ifndef Z_SOLO
|
||||||
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
# if defined(__TURBOC__) || defined(__BORLANDC__)
|
||||||
/* Allow compilation with ANSI keywords only enabled */
|
# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
|
||||||
void _Cdecl farfree( void *block );
|
/* Allow compilation with ANSI keywords only enabled */
|
||||||
void *_Cdecl farmalloc( unsigned long nbytes );
|
void _Cdecl farfree( void *block );
|
||||||
# else
|
void *_Cdecl farmalloc( unsigned long nbytes );
|
||||||
# include <alloc.h>
|
# else
|
||||||
|
# include <alloc.h>
|
||||||
|
# endif
|
||||||
|
# else /* MSC or DJGPP */
|
||||||
|
# include <malloc.h>
|
||||||
# endif
|
# endif
|
||||||
# else /* MSC or DJGPP */
|
|
||||||
# include <malloc.h>
|
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -115,18 +113,20 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
#ifdef OS2
|
#ifdef OS2
|
||||||
# define OS_CODE 0x06
|
# define OS_CODE 0x06
|
||||||
# ifdef M_I86
|
# if defined(M_I86) && !defined(Z_SOLO)
|
||||||
# include <malloc.h>
|
# include <malloc.h>
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
#if defined(MACOS) || defined(TARGET_OS_MAC)
|
||||||
# define OS_CODE 0x07
|
# define OS_CODE 0x07
|
||||||
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
# ifndef Z_SOLO
|
||||||
# include <unix.h> /* for fdopen */
|
# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
|
||||||
# else
|
# include <unix.h> /* for fdopen */
|
||||||
# ifndef fdopen
|
# else
|
||||||
# define fdopen(fd,mode) NULL /* No fdopen() */
|
# ifndef fdopen
|
||||||
|
# define fdopen(fd,mode) NULL /* No fdopen() */
|
||||||
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,16 +161,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__) && !defined(MSDOS)
|
||||||
#pragma warn -8004
|
#pragma warn -8004
|
||||||
#pragma warn -8008
|
#pragma warn -8008
|
||||||
#pragma warn -8066
|
#pragma warn -8066
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
/* provide prototypes for these when building zlib without LFS */
|
||||||
# define z_off64_t off64_t
|
#if !defined(_WIN32) && (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
|
||||||
#else
|
ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
# define z_off64_t z_off_t
|
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* common defaults */
|
/* common defaults */
|
||||||
|
@ -181,52 +181,11 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
|
|
||||||
#ifndef F_OPEN
|
#ifndef F_OPEN
|
||||||
# define F_OPEN(name, mode) fopen((name), (mode))
|
# define F_OPEN(name, mode) fopen((name), (mode))
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LARGEFILE64_SOURCE
|
|
||||||
# define F_OPEN64(name, mode) fopen64((name), (mode))
|
|
||||||
#else
|
|
||||||
# define F_OPEN64(name, mode) fopen((name), (mode))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* functions */
|
/* functions */
|
||||||
|
|
||||||
#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
|
#if defined(pyr) || defined(Z_SOLO)
|
||||||
# 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)
|
|
||||||
# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
|
|
||||||
# define vsnprintf _vsnprintf
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# ifdef __SASC
|
|
||||||
# define NO_vsnprintf
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifdef VMS
|
|
||||||
# define NO_vsnprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(pyr)
|
|
||||||
# define NO_MEMCPY
|
# define NO_MEMCPY
|
||||||
#endif
|
#endif
|
||||||
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
|
||||||
|
@ -250,16 +209,16 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
# define zmemzero(dest, len) memset(dest, 0, len)
|
# define zmemzero(dest, len) memset(dest, 0, len)
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
|
||||||
extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
|
||||||
extern void zmemzero OF((Bytef* dest, uInt len));
|
void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Diagnostic functions */
|
/* Diagnostic functions */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
extern int z_verbose;
|
extern int ZLIB_INTERNAL z_verbose;
|
||||||
extern void z_error OF((char *m));
|
extern void ZLIB_INTERNAL z_error OF((char *m));
|
||||||
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
|
||||||
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
# define Trace(x) {if (z_verbose>=0) fprintf x ;}
|
||||||
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
# define Tracev(x) {if (z_verbose>0) fprintf x ;}
|
||||||
|
@ -275,13 +234,19 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
|
||||||
# define Tracecv(c,x)
|
# define Tracecv(c,x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef Z_SOLO
|
||||||
voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
|
voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
|
||||||
void zcfree OF((voidpf opaque, voidpf ptr));
|
unsigned size));
|
||||||
|
void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr));
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ZALLOC(strm, items, size) \
|
#define ZALLOC(strm, items, size) \
|
||||||
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
(*((strm)->zalloc))((strm)->opaque, (items), (size))
|
||||||
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
|
||||||
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
|
||||||
|
|
||||||
|
/* Reverse the bytes in a 32-bit value */
|
||||||
|
#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
|
||||||
|
(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
|
||||||
|
|
||||||
#endif /* ZUTIL_H */
|
#endif /* ZUTIL_H */
|
||||||
|
|
|
@ -214,10 +214,10 @@ Name = Kiosk Demo Disc 2.02
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97128
|
Serial = SCUS-97128
|
||||||
Name = Drakan - The Ancients' Gates
|
Name = Drakan - The Ancients' Gates // aka "Drakan 2"
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
EETimingHack = 1 //flickery textures
|
EETimingHack = 1 // flickery textures
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97129
|
Serial = SCUS-97129
|
||||||
Name = Okage - Shadow King
|
Name = Okage - Shadow King
|
||||||
|
@ -349,7 +349,7 @@ Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97169
|
Serial = SCUS-97169
|
||||||
Name = Drakan - The Ancients' Gates [Demo]
|
Name = Drakan - The Ancients' Gates [Demo] // aka "Drakan 2 [Demo]"
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97170
|
Serial = SCUS-97170
|
||||||
|
@ -840,7 +840,7 @@ Serial = SCUS-97328
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97329
|
Serial = SCUS-97329
|
||||||
|
@ -1169,7 +1169,7 @@ Region = NTSC-U
|
||||||
Serial = SCUS-97436
|
Serial = SCUS-97436
|
||||||
Name = Gran Turismo 4 [Online Public Beta]
|
Name = Gran Turismo 4 [Online Public Beta]
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCUS-97437
|
Serial = SCUS-97437
|
||||||
|
@ -3670,7 +3670,7 @@ Name = Gravenville - Ghost Master
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-20467
|
Serial = SLUS-20467
|
||||||
Name = Tomb Raider - The Angel of Darkness
|
Name = Tomb Raider - The Angel of Darkness // aka "TRAOD"
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
OPHFlagHack = 1
|
OPHFlagHack = 1
|
||||||
|
@ -3755,6 +3755,9 @@ Serial = SLUS-20484
|
||||||
Name = Devil May Cry 2 [Disc1of2]
|
Name = Devil May Cry 2 [Disc1of2]
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=Note that this disc has the same CRC as SLPM-65232, the NTSC-J disc.
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-20485
|
Serial = SLUS-20485
|
||||||
Name = Dino Stalker
|
Name = Dino Stalker
|
||||||
|
@ -5887,8 +5890,8 @@ Compat = 4
|
||||||
//patch=0,EE,003a9538,word,03e00008
|
//patch=0,EE,003a9538,word,03e00008
|
||||||
//patch=0,EE,003a953c,word,00000000
|
//patch=0,EE,003a953c,word,00000000
|
||||||
|
|
||||||
//patch=0,EE,003a9460,word,03e00008
|
patch=0,EE,003a9460,word,03e00008
|
||||||
//patch=0,EE,003a9464,word,00000000
|
patch=0,EE,003a9464,word,00000000
|
||||||
|
|
||||||
[/patches]
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -5949,7 +5952,7 @@ Name = Samurai Showdown V
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-20973
|
Serial = SLUS-20973
|
||||||
Name = Champions - Return to Arms
|
Name = Champions - Return to Arms // aka "Champions of Norrath 2"
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 4
|
Compat = 4
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -9559,6 +9562,12 @@ Region = NTSC-U
|
||||||
Compat = 5
|
Compat = 5
|
||||||
VuClipFlagHack = 1
|
VuClipFlagHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
Serial = SLUS-21782B
|
||||||
|
Name = Shin Megami Tensei - Persona 4
|
||||||
|
Region = NTSC-U
|
||||||
|
Compat = 5
|
||||||
|
VuClipFlagHack = 1
|
||||||
|
---------------------------------------------
|
||||||
Serial = SLUS-21783
|
Serial = SLUS-21783
|
||||||
Name = Space Chimps
|
Name = Space Chimps
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
|
@ -10658,6 +10667,7 @@ Region = NTSC-U
|
||||||
Serial = SLUS-29101
|
Serial = SLUS-29101
|
||||||
Name = Crash Twinsanity & Spyro - A Hero's Tail [Demo]
|
Name = Crash Twinsanity & Spyro - A Hero's Tail [Demo]
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
|
XgKickHack = 1 //Fixes bad Geometry
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-29104
|
Serial = SLUS-29104
|
||||||
Name = Galactic Wrestling - Featuring Ultimate Muscle [Demo]
|
Name = Galactic Wrestling - Featuring Ultimate Muscle [Demo]
|
||||||
|
@ -10708,7 +10718,7 @@ Name = Konami Preview Disc
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLUS-29126
|
Serial = SLUS-29126
|
||||||
Name = Champions - Return to Arms [Demo]
|
Name = Champions - Return to Arms [Demo] // aka "Champions of Norrath 2 [Demo]"
|
||||||
Region = NTSC-U
|
Region = NTSC-U
|
||||||
Compat = 4
|
Compat = 4
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -10908,7 +10918,7 @@ Region = NTSC-U
|
||||||
Serial = PAPX-90512
|
Serial = PAPX-90512
|
||||||
Name = Gran Turismo 4 - Toyota Prius [Trial]
|
Name = Gran Turismo 4 - Toyota Prius [Trial]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = PBPX-95503
|
Serial = PBPX-95503
|
||||||
|
@ -10932,39 +10942,39 @@ Serial = PBPX-95524
|
||||||
Name = Gran Turismo 4 - Prologue
|
Name = Gran Turismo 4 - Prologue
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
[patches = CA6243B9]
|
//[patches = CA6243B9]
|
||||||
|
//
|
||||||
|
// comment=patches by Nachbrenner
|
||||||
|
|
||||||
comment=patches by Nachbrenner
|
// //fix IPU DMA
|
||||||
|
// patch=1,EE,00166814,word,00000000
|
||||||
//fix IPU DMA
|
// patch=1,EE,003a36b8,word,00000000
|
||||||
patch=1,EE,00166814,word,00000000
|
// patch=1,EE,003a36f4,word,00000000
|
||||||
patch=1,EE,003a36b8,word,00000000
|
// //Skip Videos
|
||||||
patch=1,EE,003a36f4,word,00000000
|
// patch=1,EE,001e3718,word,03e00008
|
||||||
//Skip Videos
|
// patch=1,EE,001e371c,word,00000000
|
||||||
patch=1,EE,001e3718,word,03e00008
|
//
|
||||||
patch=1,EE,001e371c,word,00000000
|
//[/patches]
|
||||||
|
|
||||||
[/patches]
|
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = PCPX-96649
|
Serial = PCPX-96649
|
||||||
Name = Gran Turismo 4 [Demo]
|
Name = Gran Turismo 4 [Demo]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 4
|
Compat = 4
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
[patches = E906EA37]
|
//[patches = E906EA37]
|
||||||
|
//
|
||||||
comment=patches by mdr61
|
// comment=patches by mdr61
|
||||||
|
//
|
||||||
//Timelimit counter stop
|
// //Timelimit counter stop
|
||||||
patch=0,EE,002EF740,word,00000000
|
// patch=0,EE,002EF740,word,00000000
|
||||||
//Pause counter stop
|
// //Pause counter stop
|
||||||
patch=0,EE,002C7394,word,00000000
|
// patch=0,EE,002C7394,word,00000000
|
||||||
patch=0,EE,002F1F40,word,00000000
|
// patch=0,EE,002F1F40,word,00000000
|
||||||
|
//
|
||||||
[/patches]
|
//[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-10001
|
Serial = SCAJ-10001
|
||||||
Name = Makai Senki Disgaea
|
Name = Makai Senki Disgaea
|
||||||
|
@ -11178,7 +11188,7 @@ Name = Chain Drive
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-20044
|
Serial = SCAJ-20044
|
||||||
Name = Tomb Raider - The Angel of Darkness
|
Name = Tomb Raider - The Angel of Darkness // aka "TRAOD"
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
OPHFlagHack = 1
|
OPHFlagHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -11249,7 +11259,7 @@ Region = NTSC-Unk
|
||||||
Serial = SCAJ-20066
|
Serial = SCAJ-20066
|
||||||
Name = Gran Turismo 4 - Prologue
|
Name = Gran Turismo 4 - Prologue
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-20067
|
Serial = SCAJ-20067
|
||||||
|
@ -11619,6 +11629,7 @@ Region = NTSC-Unk
|
||||||
Serial = SCAJ-20161
|
Serial = SCAJ-20161
|
||||||
Name = Siren 2
|
Name = Siren 2
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-20162
|
Serial = SCAJ-20162
|
||||||
Name = Rogue Galaxy
|
Name = Rogue Galaxy
|
||||||
|
@ -11643,6 +11654,7 @@ Region = NTSC-Unk
|
||||||
Serial = SCAJ-20167
|
Serial = SCAJ-20167
|
||||||
Name = Siren 2
|
Name = Siren 2
|
||||||
Region = NTSC-Ch-J
|
Region = NTSC-Ch-J
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-20168
|
Serial = SCAJ-20168
|
||||||
Name = Rule of Rose
|
Name = Rule of Rose
|
||||||
|
@ -11825,28 +11837,28 @@ Region = NTSC-Unk
|
||||||
Serial = SCAJ-30006
|
Serial = SCAJ-30006
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-30007
|
Serial = SCAJ-30007
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
[patches = 7ABDBB5E]
|
//[patches = 7ABDBB5E]
|
||||||
|
//
|
||||||
comment=patches by nachbrenner
|
// comment=patches by nachbrenner
|
||||||
|
//
|
||||||
//skip Videos
|
// //skip Videos
|
||||||
patch=1,EE,00100D84,word,24100001
|
// patch=1,EE,00100D84,word,24100001
|
||||||
|
//
|
||||||
[/patches]
|
//[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-30008
|
Serial = SCAJ-30008
|
||||||
Name = Gran Turismo 4 [PlayStation 2 The Best]
|
Name = Gran Turismo 4 [PlayStation 2 The Best]
|
||||||
Region = NTSC-Unk
|
Region = NTSC-Unk
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCAJ-30010
|
Serial = SCAJ-30010
|
||||||
|
@ -11923,7 +11935,7 @@ VIF1StallHack = 1 //HUD
|
||||||
Serial = SCKA-20022
|
Serial = SCKA-20022
|
||||||
Name = Gran Turismo 4 Prologue
|
Name = Gran Turismo 4 Prologue
|
||||||
Region = NTSC-K
|
Region = NTSC-K
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCKA-20023
|
Serial = SCKA-20023
|
||||||
|
@ -12075,6 +12087,7 @@ Region = NTSC-K
|
||||||
Serial = SCKA-20069
|
Serial = SCKA-20069
|
||||||
Name = Siren 2
|
Name = Siren 2
|
||||||
Region = NTSC-K
|
Region = NTSC-K
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCKA-20070
|
Serial = SCKA-20070
|
||||||
Name = Ace Combat Zero - The Belkan War
|
Name = Ace Combat Zero - The Belkan War
|
||||||
|
@ -12172,7 +12185,7 @@ Region = NTSC-K
|
||||||
Serial = SCKA-30001
|
Serial = SCKA-30001
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = NTSC-K
|
Region = NTSC-K
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCKA-30002
|
Serial = SCKA-30002
|
||||||
|
@ -12584,7 +12597,7 @@ Region = NTSC-J
|
||||||
Serial = SCPS-15055
|
Serial = SCPS-15055
|
||||||
Name = Gran Turismo 4 - Prologue
|
Name = Gran Turismo 4 - Prologue
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-15056
|
Serial = SCPS-15056
|
||||||
|
@ -12797,6 +12810,7 @@ Serial = SCPS-15106
|
||||||
Name = Siren 2
|
Name = Siren 2
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 4
|
Compat = 4
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-15107
|
Serial = SCPS-15107
|
||||||
Name = Gunparade Orchestra - Midori no Shou [Limited Edition]
|
Name = Gunparade Orchestra - Midori no Shou [Limited Edition]
|
||||||
|
@ -12863,7 +12877,7 @@ Serial = SCPS-17001
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-17002
|
Serial = SCPS-17002
|
||||||
|
@ -12991,7 +13005,7 @@ Region = NTSC-J
|
||||||
Serial = SCPS-19252
|
Serial = SCPS-19252
|
||||||
Name = Gran Turismo 4 [PlayStation 2 The Best]
|
Name = Gran Turismo 4 [PlayStation 2 The Best]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-19253
|
Serial = SCPS-19253
|
||||||
|
@ -13013,7 +13027,7 @@ Region = NTSC-J
|
||||||
Serial = SCPS-19304
|
Serial = SCPS-19304
|
||||||
Name = Gran Turismo 4 - Prologue [PlayStation 2 The Best]
|
Name = Gran Turismo 4 - Prologue [PlayStation 2 The Best]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-19305
|
Serial = SCPS-19305
|
||||||
|
@ -13099,6 +13113,7 @@ Region = NTSC-J
|
||||||
Serial = SCPS-19326
|
Serial = SCPS-19326
|
||||||
Name = Siren 2 [PlayStation 2 The Best]
|
Name = Siren 2 [PlayStation 2 The Best]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCPS-19327
|
Serial = SCPS-19327
|
||||||
Name = Ape Escape 3 [PlayStation 2 the Best - Reprint]
|
Name = Ape Escape 3 [PlayStation 2 the Best - Reprint]
|
||||||
|
@ -16447,7 +16462,7 @@ Serial = SLPM-62623
|
||||||
Name = Elemental Gerad
|
Name = Elemental Gerad
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 5
|
Compat = 5
|
||||||
XgKickHack = 1
|
XgKickHack = 1 //Fixes chocolate coloured characters
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLPM-62624
|
Serial = SLPM-62624
|
||||||
Name = Indoor Helicopter Adventure 2
|
Name = Indoor Helicopter Adventure 2
|
||||||
|
@ -16997,10 +17012,6 @@ Name = Guilty Gear X Plus "By Your Side"
|
||||||
Region = NTSC-K
|
Region = NTSC-K
|
||||||
Compat = 5
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLPM-64549
|
|
||||||
Name = Shikigame no Shiro
|
|
||||||
Region = NTSC-K
|
|
||||||
---------------------------------------------
|
|
||||||
Serial = SLPM-65001
|
Serial = SLPM-65001
|
||||||
Name = Kessen
|
Name = Kessen
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
|
@ -17701,6 +17712,9 @@ Serial = SLPM-65232
|
||||||
Name = Devil May Cry 2 [Dante Disc]
|
Name = Devil May Cry 2 [Dante Disc]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=Note that this disc has the same CRC as SLUS-20484, the NTSC-U disc.
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLPM-65233
|
Serial = SLPM-65233
|
||||||
Name = Devil May Cry 2 [Lucia Disc]
|
Name = Devil May Cry 2 [Lucia Disc]
|
||||||
|
@ -19908,11 +19922,6 @@ Serial = SLPM-65844
|
||||||
Name = Air [Best]
|
Name = Air [Best]
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLPM-65845
|
|
||||||
Name = Baldur's Gate - Dark Alliance II
|
|
||||||
Region = NTSC-J
|
|
||||||
Compat = 4
|
|
||||||
---------------------------------------------
|
|
||||||
Serial = SLPM-65846
|
Serial = SLPM-65846
|
||||||
Name = Lord of the Rings, The - Uchitsu Kuni Daisanki
|
Name = Lord of the Rings, The - Uchitsu Kuni Daisanki
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
|
@ -26568,7 +26577,7 @@ Name = True Love Story - Summer Days and Yet
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLPS-25246
|
Serial = SLPS-25246
|
||||||
Name = Tomb Raider - The Angel of Darkness
|
Name = Tomb Raider - The Angel of Darkness // aka "TRAOD"
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
OPHFlagHack = 1
|
OPHFlagHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -29397,7 +29406,7 @@ Region = NTSC-J
|
||||||
Serial = TCPS-10111
|
Serial = TCPS-10111
|
||||||
Name = Eremental Gerad
|
Name = Eremental Gerad
|
||||||
Region = NTSC-J
|
Region = NTSC-J
|
||||||
XgKickHack = 1
|
XgKickHack = 1 //Fixes chocolate coloured characters
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = TCPS-10113
|
Serial = TCPS-10113
|
||||||
Name = Mushihime-sama
|
Name = Mushihime-sama
|
||||||
|
@ -29571,9 +29580,19 @@ Region = PAL-E
|
||||||
Compat = 5
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-50006
|
Serial = SCES-50006
|
||||||
Name = Drakan - The Ancients' Gates
|
Name = Drakan - The Ancients' Gates // aka "Drakan 2"
|
||||||
Region = PAL-Unk
|
Region = PAL-M5
|
||||||
EETimingHack = 1 //flickery textures
|
Compat = 5
|
||||||
|
EETimingHack = 1 // flickery textures
|
||||||
|
[patches]
|
||||||
|
comment=This gamedisc supports multiple languages.
|
||||||
|
comment=Language selection is done through the BIOS configuration.
|
||||||
|
comment=Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
|
||||||
|
patch=1,EE,001C2274,word,3C013F7F // 3C013F80
|
||||||
|
// Fix by pgert that reduces displaycrap which arises with Resolution Scaling
|
||||||
|
// around the Health & Mana bars. Improvement someone?
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-50009
|
Serial = SCES-50009
|
||||||
Name = Wild Wild Racing
|
Name = Wild Wild Racing
|
||||||
|
@ -30105,7 +30124,7 @@ Serial = SCES-51719
|
||||||
Name = Gran Turismo 4
|
Name = Gran Turismo 4
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-51725
|
Serial = SCES-51725
|
||||||
|
@ -30288,7 +30307,7 @@ Serial = SCES-52438
|
||||||
Name = Gran Turismo 4 - Prologue
|
Name = Gran Turismo 4 - Prologue
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
eeClampMode = 3 // Text in races works
|
//eeClampMode = 3 // Text in races works
|
||||||
vuClampMode = 2 // Text in GT mode works
|
vuClampMode = 2 // Text in GT mode works
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-52456
|
Serial = SCES-52456
|
||||||
|
@ -30336,8 +30355,17 @@ Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-52677
|
Serial = SCES-52677
|
||||||
Name = Network Access Disc & Hardware - Online Arena
|
Name = Network Access Disc & Hardware - Online Arena
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk // Portuguese * Dutch * Italian * German * Spanish * French * English * Japanese
|
||||||
Compat = 4
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages and widescreen.
|
||||||
|
comment=- Language & widescreen selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
comment=-
|
||||||
|
comment=- Using GSdx, this gamedisc crashes in gamemenu with SW-mode,
|
||||||
|
comment=- and have no 3D display with HW-mode.
|
||||||
|
comment=- Playable by toggling between HW-mode (in menu) and SW-mode (in game).
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-52748
|
Serial = SCES-52748
|
||||||
Name = EyeToy - Play 2
|
Name = EyeToy - Play 2
|
||||||
|
@ -30468,7 +30496,7 @@ Serial = SCES-53247
|
||||||
Name = WRC - World Rally Championship - Rally Evolved
|
Name = WRC - World Rally Championship - Rally Evolved
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 4
|
Compat = 4
|
||||||
XgKickHack = 1 //Most of the ingame SPS gets fixed with it.
|
XgKickHack = 1 //SPS.
|
||||||
[patches = cbbc2e7f]
|
[patches = cbbc2e7f]
|
||||||
comment=patches by Nachbrenner
|
comment=patches by Nachbrenner
|
||||||
//fix delay slot violation
|
//fix delay slot violation
|
||||||
|
@ -30639,6 +30667,7 @@ Serial = SCES-53851
|
||||||
Name = Forbidden Siren 2
|
Name = Forbidden Siren 2
|
||||||
Region = PAL-M5
|
Region = PAL-M5
|
||||||
Compat = 4
|
Compat = 4
|
||||||
|
XgKickHack = 1 //SPS.
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SCES-53879
|
Serial = SCES-53879
|
||||||
Name = Buzz! The Big Quiz
|
Name = Buzz! The Big Quiz
|
||||||
|
@ -31145,14 +31174,6 @@ Serial = SLED-53745
|
||||||
Name = Total Overdose [Demo]
|
Name = Total Overdose [Demo]
|
||||||
Region = PAL-M5
|
Region = PAL-M5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLED-53745
|
|
||||||
Name = Total Overdose [Demo]
|
|
||||||
Region = PAL-M5
|
|
||||||
---------------------------------------------
|
|
||||||
Serial = SLED-53745
|
|
||||||
Name = Total Overdose [Demo]
|
|
||||||
Region = PAL-M5
|
|
||||||
---------------------------------------------
|
|
||||||
Serial = SLED-53845
|
Serial = SLED-53845
|
||||||
Name = Matrix - Path of Neo [Demo]
|
Name = Matrix - Path of Neo [Demo]
|
||||||
Region = PAL-E
|
Region = PAL-E
|
||||||
|
@ -31697,8 +31718,13 @@ Compat = 4
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-50211
|
Serial = SLES-50211
|
||||||
Name = Gauntlet - Dark Legacy
|
Name = Gauntlet - Dark Legacy
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk // English * French * German
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-50212
|
Serial = SLES-50212
|
||||||
Name = Paris-Dakar Rally
|
Name = Paris-Dakar Rally
|
||||||
|
@ -32926,6 +32952,12 @@ Serial = SLES-50821
|
||||||
Name = Project Zero
|
Name = Project Zero
|
||||||
Region = PAL-M5
|
Region = PAL-M5
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc only lets you choose language once,
|
||||||
|
comment=- whereafter it stores that setting in the memcard.
|
||||||
|
comment=- To change the language you actually have to erase
|
||||||
|
comment=- the memcard content for the game.
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-50822
|
Serial = SLES-50822
|
||||||
Name = Shadow Hearts
|
Name = Shadow Hearts
|
||||||
|
@ -33801,10 +33833,16 @@ Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-51227
|
Serial = SLES-51227
|
||||||
Name = Tomb Raider - Angel of Darkness
|
Name = Tomb Raider - Angel of Darkness // aka "TRAOD"
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
OPHFlagHack = 1
|
OPHFlagHack = 1
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages and widescreen.
|
||||||
|
comment=- Language & widescreen selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
comment=- Full boot is recommended anyway for this gamedisc to avoid textproblems.
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-51229
|
Serial = SLES-51229
|
||||||
Name = Virtua Cop - Elite Edition
|
Name = Virtua Cop - Elite Edition
|
||||||
|
@ -35655,6 +35693,12 @@ Compat = 3
|
||||||
Serial = SLES-52149
|
Serial = SLES-52149
|
||||||
Name = Tom Clancy's Splinter Cell - Pandora Tomorrow
|
Name = Tom Clancy's Splinter Cell - Pandora Tomorrow
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52150
|
Serial = SLES-52150
|
||||||
Name = Legacy of Kain - Defiance
|
Name = Legacy of Kain - Defiance
|
||||||
|
@ -35720,6 +35764,11 @@ Name = Baldur's Gate - Dark Alliance 2
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 4
|
Compat = 4
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
Serial = SLPM-65845
|
||||||
|
Name = Baldur's Gate - Dark Alliance II
|
||||||
|
Region = NTSC-J
|
||||||
|
Compat = 4
|
||||||
|
---------------------------------------------
|
||||||
Serial = SLES-52190
|
Serial = SLES-52190
|
||||||
Name = RPM Tuning
|
Name = RPM Tuning
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
@ -35849,14 +35898,17 @@ Compat = 4
|
||||||
Serial = SLES-52278
|
Serial = SLES-52278
|
||||||
Name = Mafia
|
Name = Mafia
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
EETimingHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52279
|
Serial = SLES-52279
|
||||||
Name = Mafia
|
Name = Mafia
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
EETimingHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52280
|
Serial = SLES-52280
|
||||||
Name = Mafia
|
Name = Mafia
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
EETimingHack = 1
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52282
|
Serial = SLES-52282
|
||||||
Name = Mafia
|
Name = Mafia
|
||||||
|
@ -35949,7 +36001,7 @@ Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52325
|
Serial = SLES-52325
|
||||||
Name = Champions of Norrath - Realms of EverQuest
|
Name = Champions of Norrath - Realms of EverQuest
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk // English * French * German
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52326
|
Serial = SLES-52326
|
||||||
Name = Spawn - Armageddon
|
Name = Spawn - Armageddon
|
||||||
|
@ -36305,10 +36357,10 @@ Compat = 4
|
||||||
//comment=Patches By Nachbrenner
|
//comment=Patches By Nachbrenner
|
||||||
|
|
||||||
//fix IPU busy! ingame
|
//fix IPU busy! ingame
|
||||||
//patch=0,EE,003a9a88,word,03e00008
|
patch=0,EE,003a9a88,word,03e00008
|
||||||
//patch=0,EE,003a9a8c,word,00000000
|
patch=0,EE,003a9a8c,word,00000000
|
||||||
//patch=0,EE,003a9b60,word,03e00008
|
patch=0,EE,003a9b60,word,03e00008
|
||||||
//patch=0,EE,003a9b64,word,00000000
|
patch=0,EE,003a9b64,word,00000000
|
||||||
|
|
||||||
[/patches]
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -36472,6 +36524,7 @@ Serial = SLES-52568
|
||||||
Name = Crash Twinsanity
|
Name = Crash Twinsanity
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
XgKickHack = 1 //Fixes bad Geometry
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-52569
|
Serial = SLES-52569
|
||||||
Name = Spyro - A Hero's Tail
|
Name = Spyro - A Hero's Tail
|
||||||
|
@ -37525,8 +37578,13 @@ Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53007
|
Serial = SLES-53007
|
||||||
Name = Tom Clancy's Splinter Cell - Chaos Theory
|
Name = Tom Clancy's Splinter Cell - Chaos Theory
|
||||||
Region = PAL-M5
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53011
|
Serial = SLES-53011
|
||||||
Name = Gallop Racer 2
|
Name = Gallop Racer 2
|
||||||
|
@ -37632,7 +37690,7 @@ Compat = 5
|
||||||
eeRoundMode = 0
|
eeRoundMode = 0
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53039
|
Serial = SLES-53039
|
||||||
Name = Champions - Return to Arms
|
Name = Champions - Return to Arms // aka "Champions of Norrath 2"
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
Compat = 4
|
Compat = 4
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
@ -37910,7 +37968,12 @@ Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53154
|
Serial = SLES-53154
|
||||||
Name = Bard's Tale
|
Name = Bard's Tale
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk // English * Spanish * Italian * French * German * Japanese * Korean * Chinese
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53155
|
Serial = SLES-53155
|
||||||
Name = Star Wars - Episode III - Revenge of the Sith
|
Name = Star Wars - Episode III - Revenge of the Sith
|
||||||
|
@ -38887,7 +38950,13 @@ Region = PAL-E
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53667
|
Serial = SLES-53667
|
||||||
Name = Gauntlet - Seven Sorrows
|
Name = Gauntlet - Seven Sorrows
|
||||||
Region = PAL-Unk
|
Region = PAL-M5
|
||||||
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53668
|
Serial = SLES-53668
|
||||||
Name = Micro Machines v4
|
Name = Micro Machines v4
|
||||||
|
@ -39224,6 +39293,12 @@ Compat = 5
|
||||||
Serial = SLES-53826
|
Serial = SLES-53826
|
||||||
Name = Tom Clancy's Splinter Cell - Double Agent
|
Name = Tom Clancy's Splinter Cell - Double Agent
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53827
|
Serial = SLES-53827
|
||||||
Name = Tom Clancy's Splinter Cell - Double Agent
|
Name = Tom Clancy's Splinter Cell - Double Agent
|
||||||
|
@ -39308,7 +39383,7 @@ Serial = SLES-53866
|
||||||
Name = Over the Hedge
|
Name = Over the Hedge
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53866
|
Serial = SLES-53867
|
||||||
Name = Ski Alpin 2006
|
Name = Ski Alpin 2006
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
vuClampMode = 2
|
vuClampMode = 2
|
||||||
|
@ -39385,9 +39460,14 @@ Name = 50cent - Bulletproof
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53908
|
Serial = SLES-53908
|
||||||
Name = Tomb Raider - Legends
|
Name = Tomb Raider - Legend
|
||||||
Region = PAL-Unk
|
Region = PAL-Unk // English * French * German * Italian * Spanish * Japanese * Portugese * Polish
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-53909
|
Serial = SLES-53909
|
||||||
Name = Full Spectrum Warrior - Ten Hammers
|
Name = Full Spectrum Warrior - Ten Hammers
|
||||||
|
@ -39957,17 +40037,17 @@ Region = PAL-R
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-54185
|
Serial = SLES-54185
|
||||||
Name = Dirge of Cerberus - Final Fantasy VII
|
Name = Dirge of Cerberus - Final Fantasy VII
|
||||||
Region = PAL-E
|
Region = PAL-Unk
|
||||||
Compat = 5
|
Compat = 5
|
||||||
[patches = 33F7D21A]
|
[patches = 33F7D21A]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
//comment=patches by nachbrenner
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
//override sceScfGetLanguage
|
|
||||||
//patch=0,EE,002486d8,word,24020000 //japanese
|
// Override sceScfGetLanguage patches by nachbrenner:
|
||||||
//patch=0,EE,002486d8,word,24020001 //english
|
// patch=0,EE,002486d8,word,24020000 // japanese
|
||||||
//patch=0,EE,002486d8,word,24020004 //german
|
// patch=0,EE,002486d8,word,24020001 // english
|
||||||
|
// patch=0,EE,002486d8,word,24020004 // german
|
||||||
[/patches]
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-54186
|
Serial = SLES-54186
|
||||||
|
@ -40861,7 +40941,13 @@ Region = PAL-M11
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-54674
|
Serial = SLES-54674
|
||||||
Name = Lara Croft Tomb Raider - Anniversary
|
Name = Lara Croft Tomb Raider - Anniversary
|
||||||
Region = PAL-M5
|
Region = PAL-Unk // English * French * German * Italian * Spanish * Japanese * Portugese * Polish * Russian * Czech
|
||||||
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-54675
|
Serial = SLES-54675
|
||||||
Name = Street Warrior
|
Name = Street Warrior
|
||||||
|
@ -41694,8 +41780,13 @@ Region = PAL-M5
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-55442
|
Serial = SLES-55442
|
||||||
Name = Tomb Raider Underworld
|
Name = Tomb Raider Underworld
|
||||||
Region = PAL-M5
|
Region = PAL-Unk // English * French * German * Italian * Spanish * Japanese * Portugese * Polish * Russian * Czech * Dutch
|
||||||
Compat = 5
|
Compat = 5
|
||||||
|
[patches]
|
||||||
|
comment=- This gamedisc supports multiple languages.
|
||||||
|
comment=- Language selection is done through the BIOS configuration.
|
||||||
|
comment=- Implementation requires full boot - "Boot CDVD (full)".
|
||||||
|
[/patches]
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
Serial = SLES-55443
|
Serial = SLES-55443
|
||||||
Name = Mana Khemia - Alchemists of Al-Revis
|
Name = Mana Khemia - Alchemists of Al-Revis
|
||||||
|
|
|
@ -72,9 +72,15 @@ then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Launch PCSX2
|
# Launch PCSX2
|
||||||
if [ -x pcsx2 ]
|
if [ -x "pcsx2" ]
|
||||||
then
|
then
|
||||||
./pcsx2 $@
|
./pcsx2 $@
|
||||||
|
elif [ -x "pcsx2-dev" ]
|
||||||
|
then
|
||||||
|
./pcsx2-dev $@
|
||||||
|
elif [ -x "pcsx2-dbg" ]
|
||||||
|
then
|
||||||
|
./pcsx2-dbg $@
|
||||||
else
|
else
|
||||||
echo "Error PCSX2 not found"
|
echo "Error PCSX2 not found"
|
||||||
echo "Maybe the script was directly 'called'"
|
echo "Maybe the script was directly 'called'"
|
||||||
|
|
|
@ -9,8 +9,6 @@ if(AIO_INCLUDE_DIR AND AIO_LIBRARIES)
|
||||||
set(AIO_FIND_QUIETLY TRUE)
|
set(AIO_FIND_QUIETLY TRUE)
|
||||||
endif(AIO_INCLUDE_DIR AND AIO_LIBRARIES)
|
endif(AIO_INCLUDE_DIR AND AIO_LIBRARIES)
|
||||||
|
|
||||||
INCLUDE(CheckCXXSymbolExists)
|
|
||||||
|
|
||||||
# include dir
|
# include dir
|
||||||
find_path(AIO_INCLUDE_DIR libaio.h)
|
find_path(AIO_INCLUDE_DIR libaio.h)
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,9 @@ find_package(Subversion)
|
||||||
# Warning do not put any double-quote for the argument...
|
# Warning do not put any double-quote for the argument...
|
||||||
# set(wxWidgets_CONFIG_OPTIONS --unicode=yes --debug=yes) # In case someone want to debug inside wx
|
# set(wxWidgets_CONFIG_OPTIONS --unicode=yes --debug=yes) # In case someone want to debug inside wx
|
||||||
#
|
#
|
||||||
# Fedora uses an extra non-standard option ...
|
# Fedora uses an extra non-standard option ... Arch must be the first option.
|
||||||
if(Fedora)
|
if(Fedora)
|
||||||
set(wxWidgets_CONFIG_OPTIONS --unicode=yes --arch i686)
|
set(wxWidgets_CONFIG_OPTIONS --arch i686 --unicode=yes)
|
||||||
else()
|
else()
|
||||||
set(wxWidgets_CONFIG_OPTIONS --unicode=yes)
|
set(wxWidgets_CONFIG_OPTIONS --unicode=yes)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
# Dependency message print
|
# Dependency message print
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
set(msg_dep_common_libs "check these libraries -> wxWidgets (>=2.8.10), sparsehash (>=1.5)")
|
set(msg_dep_common_libs "check these libraries -> wxWidgets (>=2.8.10), sparsehash (>=1.5), aio")
|
||||||
set(msg_dep_pcsx2 "check these libraries -> wxWidgets (>=2.8.10), gtk2 (>=2.16), zlib (>=1.2.4), pcsx2 common libs")
|
set(msg_dep_pcsx2 "check these libraries -> wxWidgets (>=2.8.10), gtk2 (>=2.16), zlib (>=1.2.4), pcsx2 common libs")
|
||||||
set(msg_dep_cdvdiso "check these libraries -> bzip2 (>=1.0.5), gtk2 (>=2.16)")
|
set(msg_dep_cdvdiso "check these libraries -> bzip2 (>=1.0.5), gtk2 (>=2.16)")
|
||||||
set(msg_dep_zerogs "check these libraries -> glew (>=1.6), opengl, X11, nvidia-cg-toolkit (>=2.1)")
|
set(msg_dep_zerogs "check these libraries -> glew (>=1.6), opengl, X11, nvidia-cg-toolkit (>=2.1)")
|
||||||
|
|
|
@ -192,7 +192,7 @@
|
||||||
<ClInclude Include="..\..\include\Utilities\RwMutex.h" />
|
<ClInclude Include="..\..\include\Utilities\RwMutex.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\3rdparty\wxWidgets\build\msw\wx_base.vcxproj">
|
<ProjectReference Include="..\..\..\3rdparty\wxWidgets\build\msw\wx_base_vs11.vcxproj">
|
||||||
<Project>{48ad7e0a-25b1-4974-a1e3-03f8c438d34f}</Project>
|
<Project>{48ad7e0a-25b1-4974-a1e3-03f8c438d34f}</Project>
|
||||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
|
|
@ -144,20 +144,18 @@ struct PluginConf
|
||||||
int ReadInt(const std::string& item, int defval)
|
int ReadInt(const std::string& item, int defval)
|
||||||
{
|
{
|
||||||
int value = defval;
|
int value = defval;
|
||||||
int err = 0;
|
|
||||||
std::string buf = item + " = %d\n";
|
std::string buf = item + " = %d\n";
|
||||||
|
|
||||||
if (ConfFile) err=fscanf(ConfFile, buf.c_str(), &value);
|
if (ConfFile) fscanf(ConfFile, buf.c_str(), &value);
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteInt(std::string item, int value)
|
void WriteInt(std::string item, int value)
|
||||||
{
|
{
|
||||||
int err = 0;
|
|
||||||
std::string buf = item + " = %d\n";
|
std::string buf = item + " = %d\n";
|
||||||
|
|
||||||
if (ConfFile) err=fprintf(ConfFile, buf.c_str(), value);
|
if (ConfFile) fprintf(ConfFile, buf.c_str(), value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1058,6 +1058,14 @@ typedef struct _PS2E_ComponentAPI_Mcd
|
||||||
//
|
//
|
||||||
void (PS2E_CALLBACK* McdGetSizeInfo)( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways );
|
void (PS2E_CALLBACK* McdGetSizeInfo)( PS2E_THISPTR thisptr, uint port, uint slot, PS2E_McdSizeInfo* outways );
|
||||||
|
|
||||||
|
// McdIsPSX
|
||||||
|
// Checks if the memorycard is a PSX one from the Mcd provider.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// False: PS2, True: PSX
|
||||||
|
//
|
||||||
|
bool (PS2E_CALLBACK* McdIsPSX)( PS2E_THISPTR thisptr, uint port, uint slot );
|
||||||
|
|
||||||
// McdRead
|
// McdRead
|
||||||
// Requests that a block of data be loaded from the memorycard into the specified dest
|
// Requests that a block of data be loaded from the memorycard into the specified dest
|
||||||
// buffer (which is allocated by the caller). Bytes read should match the requested
|
// buffer (which is allocated by the caller). Bytes read should match the requested
|
||||||
|
|
|
@ -136,6 +136,8 @@ echo "Copy the subversion repository to a temporary directory"
|
||||||
rm -fr $NEW_DIR
|
rm -fr $NEW_DIR
|
||||||
cp -r $ROOT_DIR $NEW_DIR
|
cp -r $ROOT_DIR $NEW_DIR
|
||||||
|
|
||||||
|
echo "Remove .svn directories"
|
||||||
|
find $NEW_DIR -name ".svn" -type d -exec rm -fr {} \; 2> /dev/null
|
||||||
echo "Remove windows files (useless & potential copyright issues)"
|
echo "Remove windows files (useless & potential copyright issues)"
|
||||||
# => pcsx2/windows
|
# => pcsx2/windows
|
||||||
# Copyright header must be updated
|
# Copyright header must be updated
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my @res = qw/convert interlace merge shadeboost tfx/;
|
||||||
|
my $path = "plugins/GSdx/res";
|
||||||
|
|
||||||
|
foreach my $r (@res) {
|
||||||
|
glsl2h($path, $r);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub glsl2h {
|
||||||
|
my $path = shift;
|
||||||
|
my $glsl = shift;
|
||||||
|
|
||||||
|
open(my $GLSL, "<$path/${glsl}.glsl");
|
||||||
|
open(my $H, ">$path/${glsl}.h");
|
||||||
|
|
||||||
|
my $header = <<EOS;
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2011-2013 Gregory hainaut
|
||||||
|
* Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This file was generated by glsl2h.pl script
|
||||||
|
*
|
||||||
|
* 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, 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
extern const char* ${glsl}_glsl =
|
||||||
|
EOS
|
||||||
|
|
||||||
|
print $H $header;
|
||||||
|
|
||||||
|
my $line;
|
||||||
|
while(defined($line = <$GLSL>)) {
|
||||||
|
chomp $line;
|
||||||
|
$line =~ s/%/\\%/g;
|
||||||
|
$line =~ s/"/\\"/g;
|
||||||
|
print $H "\t\"$line\\n\"\n";
|
||||||
|
}
|
||||||
|
print $H "\t;\n";
|
||||||
|
}
|
|
@ -1209,12 +1209,12 @@ static void cdvdWrite04(u8 rt) { // NCOMMAND
|
||||||
default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break;
|
default: cdvd.ReadMode = CDVD_MODE_2048; cdvd.BlockSize = 2048; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDVD_LOG( "CdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
|
CDVD_LOG( "CdRead > startSector=%d, seekTo=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
|
||||||
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
|
cdvd.Sector, cdvd.SeekToSector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
|
||||||
|
|
||||||
if( EmuConfig.CdvdVerboseReads )
|
if( EmuConfig.CdvdVerboseReads )
|
||||||
Console.WriteLn( Color_Gray, L"CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx",
|
Console.WriteLn( Color_Gray, L"CdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx",
|
||||||
cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed);
|
cdvd.SeekToSector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed);
|
||||||
|
|
||||||
cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM );
|
cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM );
|
||||||
CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) );
|
CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) );
|
||||||
|
@ -1293,12 +1293,12 @@ static void cdvdWrite04(u8 rt) { // NCOMMAND
|
||||||
cdvd.ReadMode = CDVD_MODE_2048;
|
cdvd.ReadMode = CDVD_MODE_2048;
|
||||||
cdvd.BlockSize = 2064; // Why oh why was it 2064
|
cdvd.BlockSize = 2064; // Why oh why was it 2064
|
||||||
|
|
||||||
CDVD_LOG( "DvdRead > startSector=%d, nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
|
CDVD_LOG( "DvdRead > startSector=%d, seekTo=%d nSectors=%d, RetryCnt=%x, Speed=%x(%x), ReadMode=%x(%x) (1074=%x)",
|
||||||
cdvd.Sector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
|
cdvd.Sector, cdvd.SeekToSector, cdvd.nSectors, cdvd.RetryCnt, cdvd.Speed, cdvd.Param[9], cdvd.ReadMode, cdvd.Param[10], psxHu32(0x1074));
|
||||||
|
|
||||||
if( EmuConfig.CdvdVerboseReads )
|
if( EmuConfig.CdvdVerboseReads )
|
||||||
Console.WriteLn( Color_Gray, L"DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx",
|
Console.WriteLn( Color_Gray, L"DvdRead: Reading Sector %d(%d Blocks of Size %d) at Speed=%dx",
|
||||||
cdvd.Sector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed);
|
cdvd.SeekToSector, cdvd.nSectors,cdvd.BlockSize,cdvd.Speed);
|
||||||
|
|
||||||
cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM );
|
cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM );
|
||||||
CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) );
|
CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) );
|
||||||
|
|
|
@ -113,6 +113,9 @@ static int CheckDiskTypeFS(int baseType)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef PCSX2_DEVBUILD
|
||||||
|
return CDVD_TYPE_PS2DVD; // need this hack for some homebrew (SMS)
|
||||||
|
#endif
|
||||||
return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all.
|
return CDVD_TYPE_ILLEGAL; // << Only for discs which aren't ps2 at all.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +148,11 @@ static int FindDiskType(int mType)
|
||||||
{
|
{
|
||||||
//const cdVolDesc& volDesc = (cdVolDesc&)bleh;
|
//const cdVolDesc& volDesc = (cdVolDesc&)bleh;
|
||||||
//if(volDesc.rootToc.tocSize == 2048)
|
//if(volDesc.rootToc.tocSize == 2048)
|
||||||
if(*(u16*)(bleh+166) == 2048)
|
|
||||||
|
//Horrible hack! in CD images position 166 and 171 have block size but not DVD's
|
||||||
|
//It's not always 2048 however (can be 4096)
|
||||||
|
//Test Impossible Mission if thia is changed.
|
||||||
|
if(*(u16*)(bleh+166) == *(u16*)(bleh+171))
|
||||||
iCDType = CDVD_TYPE_DETCTCD;
|
iCDType = CDVD_TYPE_DETCTCD;
|
||||||
else
|
else
|
||||||
iCDType = CDVD_TYPE_DETCTDVDS;
|
iCDType = CDVD_TYPE_DETCTDVDS;
|
||||||
|
|
|
@ -109,6 +109,15 @@ void __fastcall WriteFIFO_VIF1(const mem128_t *value)
|
||||||
}
|
}
|
||||||
else vif1Regs.stat.VPS = VPS_IDLE;
|
else vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
|
|
||||||
|
if( gifRegs.stat.APATH == 2 && gifUnit.gifPath[1].isDone())
|
||||||
|
{
|
||||||
|
gifRegs.stat.APATH = 0;
|
||||||
|
gifRegs.stat.OPH = 0;
|
||||||
|
vif1Regs.stat.VGW = false; //Let vif continue if it's stuck on a flush
|
||||||
|
|
||||||
|
if(gifUnit.checkPaths(1,0,1)) gifUnit.Execute(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
pxAssertDev( ret, "vif stall code not implemented" );
|
pxAssertDev( ret, "vif stall code not implemented" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,4 +128,16 @@ void __fastcall WriteFIFO_GIF(const mem128_t *value)
|
||||||
|
|
||||||
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
||||||
|
|
||||||
|
if( gifRegs.stat.APATH == 3 )
|
||||||
|
{
|
||||||
|
gifRegs.stat.APATH = 0;
|
||||||
|
gifRegs.stat.OPH = 0;
|
||||||
|
|
||||||
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
|
{
|
||||||
|
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ static __fi void gsCSRwrite( const tGS_CSR& csr )
|
||||||
}
|
}
|
||||||
else CSRreg.SIGNAL = false;
|
else CSRreg.SIGNAL = false;
|
||||||
gifUnit.gsSIGNAL.queued = false;
|
gifUnit.gsSIGNAL.queued = false;
|
||||||
gifUnit.Execute(false); // Resume paused transfers
|
gifUnit.Execute(false, true); // Resume paused transfers
|
||||||
}
|
}
|
||||||
|
|
||||||
if(csr.FINISH) CSRreg.FINISH = false;
|
if(csr.FINISH) CSRreg.FINISH = false;
|
||||||
|
|
|
@ -50,7 +50,17 @@ void incGifChAddr(u32 qwc) {
|
||||||
__fi void gifInterrupt()
|
__fi void gifInterrupt()
|
||||||
{
|
{
|
||||||
GIF_LOG("gifInterrupt caught!");
|
GIF_LOG("gifInterrupt caught!");
|
||||||
//Required for Path3 Masking timing!
|
if( gifRegs.stat.APATH == 3 )
|
||||||
|
{
|
||||||
|
gifRegs.stat.APATH = 0;
|
||||||
|
gifRegs.stat.OPH = 0;
|
||||||
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
|
{
|
||||||
|
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//Required for Path3 Masking timing!
|
||||||
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
{
|
{
|
||||||
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
||||||
|
@ -102,7 +112,7 @@ __fi void gifInterrupt()
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 WRITERING_DMA(u32 *pMem, u32 qwc) {
|
static u32 WRITERING_DMA(u32 *pMem, u32 qwc) {
|
||||||
//qwc = min(qwc, 1024u);
|
if(gifRegs.stat.IMT) qwc = std::min(qwc, 1024u);
|
||||||
uint size = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)pMem, qwc*16) / 16;
|
uint size = gifUnit.TransferGSPacketData(GIF_TRANS_DMA, (u8*)pMem, qwc*16) / 16;
|
||||||
incGifChAddr(size);
|
incGifChAddr(size);
|
||||||
return size;
|
return size;
|
||||||
|
@ -350,7 +360,7 @@ static __fi bool mfifoGIFchain()
|
||||||
if (gifch.qwc == 0) return true;
|
if (gifch.qwc == 0) return true;
|
||||||
|
|
||||||
if (gifch.madr >= dmacRegs.rbor.ADDR &&
|
if (gifch.madr >= dmacRegs.rbor.ADDR &&
|
||||||
gifch.madr <=(dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
|
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
// if(gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge GIF");
|
// if(gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge GIF");
|
||||||
|
@ -380,6 +390,32 @@ static u32 qwctag(u32 mask) {
|
||||||
return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK));
|
return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mfifoGifMaskMem(int id)
|
||||||
|
{
|
||||||
|
switch (id) {
|
||||||
|
//These five transfer data following the tag, need to check its within the buffer (Front Mission 4)
|
||||||
|
case TAG_CNT:
|
||||||
|
case TAG_NEXT:
|
||||||
|
case TAG_CALL:
|
||||||
|
case TAG_RET:
|
||||||
|
case TAG_END:
|
||||||
|
if(gifch.madr < dmacRegs.rbor.ADDR) //probably not needed but we will check anyway.
|
||||||
|
{
|
||||||
|
//DevCon.Warning("GIF MFIFO MADR below bottom of ring buffer, wrapping GIF MADR = %x Ring Bottom %x", gifch.madr, dmacRegs.rbor.ADDR);
|
||||||
|
gifch.madr = qwctag(gifch.madr);
|
||||||
|
}
|
||||||
|
if(gifch.madr > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)) //Usual scenario is the tag is near the end (Front Mission 4)
|
||||||
|
{
|
||||||
|
//DevCon.Warning("GIF MFIFO MADR outside top of ring buffer, wrapping GIF MADR = %x Ring Top %x", gifch.madr, (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK)+16);
|
||||||
|
gifch.madr = qwctag(gifch.madr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//Do nothing as the MADR could be outside
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mfifoGIFtransfer(int qwc)
|
void mfifoGIFtransfer(int qwc)
|
||||||
{
|
{
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
|
@ -416,6 +452,8 @@ void mfifoGIFtransfer(int qwc)
|
||||||
|
|
||||||
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
|
||||||
|
|
||||||
|
mfifoGifMaskMem(ptag->ID);
|
||||||
|
|
||||||
if(gspath3done == true) gifstate = GIF_STATE_DONE;
|
if(gspath3done == true) gifstate = GIF_STATE_DONE;
|
||||||
else gifstate = GIF_STATE_READY;
|
else gifstate = GIF_STATE_READY;
|
||||||
|
|
||||||
|
@ -456,6 +494,17 @@ void gifMFIFOInterrupt()
|
||||||
GIF_LOG("gifMFIFOInterrupt");
|
GIF_LOG("gifMFIFOInterrupt");
|
||||||
mfifocycles = 0;
|
mfifocycles = 0;
|
||||||
|
|
||||||
|
if( gifRegs.stat.APATH == 3 )
|
||||||
|
{
|
||||||
|
gifRegs.stat.APATH = 0;
|
||||||
|
gifRegs.stat.OPH = 0;
|
||||||
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_IDLE || gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
|
{
|
||||||
|
if(gifUnit.checkPaths(1,1,0)) gifUnit.Execute(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
if(gifUnit.gifPath[GIF_PATH_3].state == GIF_PATH_WAIT)
|
||||||
{
|
{
|
||||||
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
gifUnit.gifPath[GIF_PATH_3].state = GIF_PATH_IDLE;
|
||||||
|
|
|
@ -473,7 +473,7 @@ struct Gif_Unit {
|
||||||
}
|
}
|
||||||
if (tranType == GIF_TRANS_MTVU) { // This is on the EE thread
|
if (tranType == GIF_TRANS_MTVU) { // This is on the EE thread
|
||||||
path1.mtvu.fakePackets++;
|
path1.mtvu.fakePackets++;
|
||||||
if (CanDoGif()) Execute(false);
|
if (CanDoGif()) Execute(false, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +481,7 @@ struct Gif_Unit {
|
||||||
GUNIT_LOG("%s - [path=%d][size=%d]", Gif_TransferStr[(tranType>>8)&0xf], (tranType&3)+1, size);
|
GUNIT_LOG("%s - [path=%d][size=%d]", Gif_TransferStr[(tranType>>8)&0xf], (tranType&3)+1, size);
|
||||||
if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; }
|
if (size == 0) { GUNIT_WARN("Gif Unit - Size == 0"); return 0; }
|
||||||
if(!CanDoGif()) { GUNIT_WARN("Gif Unit - Signal or PSE Set or Dir = GS to EE"); }
|
if(!CanDoGif()) { GUNIT_WARN("Gif Unit - Signal or PSE Set or Dir = GS to EE"); }
|
||||||
pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
|
//pxAssertDev((stat.APATH==0) || checkPaths(1,1,1), "Gif Unit - APATH wasn't cleared?");
|
||||||
lastTranType = tranType;
|
lastTranType = tranType;
|
||||||
|
|
||||||
if (tranType == GIF_TRANS_FIFO) {
|
if (tranType == GIF_TRANS_FIFO) {
|
||||||
|
@ -502,7 +502,7 @@ struct Gif_Unit {
|
||||||
}
|
}
|
||||||
|
|
||||||
gifPath[tranType&3].CopyGSPacketData(pMem, size, aligned);
|
gifPath[tranType&3].CopyGSPacketData(pMem, size, aligned);
|
||||||
size -= Execute(tranType == GIF_TRANS_DMA);
|
size -= Execute(tranType == GIF_TRANS_DMA, false);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ struct Gif_Unit {
|
||||||
|
|
||||||
// Processes gif packets and performs path arbitration
|
// Processes gif packets and performs path arbitration
|
||||||
// on EOPs or on Path 3 Images when IMT is set.
|
// on EOPs or on Path 3 Images when IMT is set.
|
||||||
int Execute(bool isPath3) {
|
int Execute(bool isPath3, bool isResume) {
|
||||||
if (!CanDoGif()) { DevCon.Error("Gif Unit - Signal or PSE Set or Dir = GS to EE"); return 0; }
|
if (!CanDoGif()) { DevCon.Error("Gif Unit - Signal or PSE Set or Dir = GS to EE"); return 0; }
|
||||||
bool didPath3 = false;
|
bool didPath3 = false;
|
||||||
int curPath = stat.APATH > 0 ? stat.APATH-1 : 0; //Init to zero if no path is already set.
|
int curPath = stat.APATH > 0 ? stat.APATH-1 : 0; //Init to zero if no path is already set.
|
||||||
|
@ -584,7 +584,7 @@ struct Gif_Unit {
|
||||||
elif (!gsSIGNAL.queued && !gifPath[1].isDone()) { stat.APATH = 2; stat.P2Q = 0; curPath = 1; }
|
elif (!gsSIGNAL.queued && !gifPath[1].isDone()) { stat.APATH = 2; stat.P2Q = 0; curPath = 1; }
|
||||||
elif (!gsSIGNAL.queued && !gifPath[2].isDone() && !Path3Masked() /*&& !stat.P2Q*/)
|
elif (!gsSIGNAL.queued && !gifPath[2].isDone() && !Path3Masked() /*&& !stat.P2Q*/)
|
||||||
{ stat.APATH = 3; stat.P3Q = 0; stat.IP3 = 0; curPath = 2; }
|
{ stat.APATH = 3; stat.P3Q = 0; stat.IP3 = 0; curPath = 2; }
|
||||||
else { stat.APATH = 0; stat.OPH = 0; break; }
|
else { if(isResume) { stat.APATH = 0; stat.OPH = 0; } break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//Some loaders/Refresh Rate selectors and things dont issue "End of Packet" commands
|
//Some loaders/Refresh Rate selectors and things dont issue "End of Packet" commands
|
||||||
|
|
|
@ -142,6 +142,14 @@ mem32_t __fastcall _hwRead32(u32 mem)
|
||||||
if(mem == (D1_CHCR + 0x10) && CHECK_VIFFIFOHACK)
|
if(mem == (D1_CHCR + 0x10) && CHECK_VIFFIFOHACK)
|
||||||
return psHu32(mem) + (vif1ch.qwc * 16);
|
return psHu32(mem) + (vif1ch.qwc * 16);
|
||||||
|
|
||||||
|
if((mem == GIF_CHCR) && !vif1ch.chcr.STR && gifRegs.stat.M3P && gifRegs.stat.APATH != 3)
|
||||||
|
{
|
||||||
|
//Hack for Wallace and Gromit Curse Project Zoo - Enabled the mask, then starts a new
|
||||||
|
//GIF DMA, the mask never comes off and it won't proceed until this is unset.
|
||||||
|
//Unsetting it works too but messes up other PATH3 games.
|
||||||
|
//If STR is already unset, it won't make the slightest difference.
|
||||||
|
return (psHu32(mem) & ~0x100);
|
||||||
|
}
|
||||||
return psHu32(mem);
|
return psHu32(mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -279,15 +279,15 @@ void IPU0dma()
|
||||||
case NO_STD:
|
case NO_STD:
|
||||||
break;
|
break;
|
||||||
case STD_GIF: // GIF
|
case STD_GIF: // GIF
|
||||||
Console.Warning("GIFSTALL");
|
DevCon.Warning("GIFSTALL");
|
||||||
g_nDMATransfer.GIFSTALL = true;
|
g_nDMATransfer.GIFSTALL = true;
|
||||||
break;
|
break;
|
||||||
case STD_VIF1: // VIF
|
case STD_VIF1: // VIF
|
||||||
Console.Warning("VIFSTALL");
|
DevCon.Warning("VIFSTALL");
|
||||||
g_nDMATransfer.VIFSTALL = true;
|
g_nDMATransfer.VIFSTALL = true;
|
||||||
break;
|
break;
|
||||||
case STD_SIF1:
|
case STD_SIF1:
|
||||||
Console.Warning("SIFSTALL");
|
DevCon.Warning("SIFSTALL");
|
||||||
g_nDMATransfer.SIFSTALL = true;
|
g_nDMATransfer.SIFSTALL = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -402,7 +402,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.GIFSTALL)
|
if (g_nDMATransfer.GIFSTALL)
|
||||||
{
|
{
|
||||||
// gif
|
// gif
|
||||||
Console.Warning("IPU GIF Stall");
|
DevCon.Warning("IPU GIF Stall");
|
||||||
g_nDMATransfer.GIFSTALL = false;
|
g_nDMATransfer.GIFSTALL = false;
|
||||||
//if (gif->chcr.STR) GIFdma();
|
//if (gif->chcr.STR) GIFdma();
|
||||||
}
|
}
|
||||||
|
@ -410,7 +410,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.VIFSTALL)
|
if (g_nDMATransfer.VIFSTALL)
|
||||||
{
|
{
|
||||||
// vif
|
// vif
|
||||||
Console.Warning("IPU VIF Stall");
|
DevCon.Warning("IPU VIF Stall");
|
||||||
g_nDMATransfer.VIFSTALL = false;
|
g_nDMATransfer.VIFSTALL = false;
|
||||||
//if (vif1ch.chcr.STR) dmaVIF1();
|
//if (vif1ch.chcr.STR) dmaVIF1();
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ void ipu0Interrupt()
|
||||||
if (g_nDMATransfer.SIFSTALL)
|
if (g_nDMATransfer.SIFSTALL)
|
||||||
{
|
{
|
||||||
// sif
|
// sif
|
||||||
Console.Warning("IPU SIF Stall");
|
DevCon.Warning("IPU SIF Stall");
|
||||||
g_nDMATransfer.SIFSTALL = false;
|
g_nDMATransfer.SIFSTALL = false;
|
||||||
|
|
||||||
// Not totally sure whether this needs to be done or not, so I'm
|
// Not totally sure whether this needs to be done or not, so I'm
|
||||||
|
|
|
@ -446,24 +446,28 @@ template<int vunum> static __fi void ClearVuFunc(u32 addr, u32 size) {
|
||||||
template<int vunum> static mem8_t __fc vuMicroRead8(u32 addr) {
|
template<int vunum> static mem8_t __fc vuMicroRead8(u32 addr) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
||||||
return vu->Micro[addr];
|
return vu->Micro[addr];
|
||||||
}
|
}
|
||||||
template<int vunum> static mem16_t __fc vuMicroRead16(u32 addr) {
|
template<int vunum> static mem16_t __fc vuMicroRead16(u32 addr) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
||||||
return *(u16*)&vu->Micro[addr];
|
return *(u16*)&vu->Micro[addr];
|
||||||
}
|
}
|
||||||
template<int vunum> static mem32_t __fc vuMicroRead32(u32 addr) {
|
template<int vunum> static mem32_t __fc vuMicroRead32(u32 addr) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
||||||
return *(u32*)&vu->Micro[addr];
|
return *(u32*)&vu->Micro[addr];
|
||||||
}
|
}
|
||||||
template<int vunum> static void __fc vuMicroRead64(u32 addr,mem64_t* data) {
|
template<int vunum> static void __fc vuMicroRead64(u32 addr,mem64_t* data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
||||||
*data=*(u64*)&vu->Micro[addr];
|
*data=*(u64*)&vu->Micro[addr];
|
||||||
}
|
}
|
||||||
|
@ -471,6 +475,7 @@ template<int vunum> static void __fc vuMicroRead128(u32 addr,mem128_t* data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
if (vunum && THREAD_VU1) vu1Thread.WaitVU();
|
||||||
|
|
||||||
CopyQWC(data,&vu->Micro[addr]);
|
CopyQWC(data,&vu->Micro[addr]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +484,7 @@ template<int vunum> static void __fc vuMicroRead128(u32 addr,mem128_t* data) {
|
||||||
template<int vunum> static void __fc vuMicroWrite8(u32 addr,mem8_t data) {
|
template<int vunum> static void __fc vuMicroWrite8(u32 addr,mem8_t data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) {
|
if (vunum && THREAD_VU1) {
|
||||||
vu1Thread.WriteMicroMem(addr, &data, sizeof(u8));
|
vu1Thread.WriteMicroMem(addr, &data, sizeof(u8));
|
||||||
return;
|
return;
|
||||||
|
@ -491,6 +497,7 @@ template<int vunum> static void __fc vuMicroWrite8(u32 addr,mem8_t data) {
|
||||||
template<int vunum> static void __fc vuMicroWrite16(u32 addr, mem16_t data) {
|
template<int vunum> static void __fc vuMicroWrite16(u32 addr, mem16_t data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) {
|
if (vunum && THREAD_VU1) {
|
||||||
vu1Thread.WriteMicroMem(addr, &data, sizeof(u16));
|
vu1Thread.WriteMicroMem(addr, &data, sizeof(u16));
|
||||||
return;
|
return;
|
||||||
|
@ -503,6 +510,7 @@ template<int vunum> static void __fc vuMicroWrite16(u32 addr, mem16_t data) {
|
||||||
template<int vunum> static void __fc vuMicroWrite32(u32 addr, mem32_t data) {
|
template<int vunum> static void __fc vuMicroWrite32(u32 addr, mem32_t data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) {
|
if (vunum && THREAD_VU1) {
|
||||||
vu1Thread.WriteMicroMem(addr, &data, sizeof(u32));
|
vu1Thread.WriteMicroMem(addr, &data, sizeof(u32));
|
||||||
return;
|
return;
|
||||||
|
@ -515,10 +523,12 @@ template<int vunum> static void __fc vuMicroWrite32(u32 addr, mem32_t data) {
|
||||||
template<int vunum> static void __fc vuMicroWrite64(u32 addr, const mem64_t* data) {
|
template<int vunum> static void __fc vuMicroWrite64(u32 addr, const mem64_t* data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) {
|
if (vunum && THREAD_VU1) {
|
||||||
vu1Thread.WriteMicroMem(addr, (void*)data, sizeof(u64));
|
vu1Thread.WriteMicroMem(addr, (void*)data, sizeof(u64));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(u64*)&vu->Micro[addr]!=data[0]) {
|
if (*(u64*)&vu->Micro[addr]!=data[0]) {
|
||||||
ClearVuFunc<vunum>(addr, 8);
|
ClearVuFunc<vunum>(addr, 8);
|
||||||
*(u64*)&vu->Micro[addr] =data[0];
|
*(u64*)&vu->Micro[addr] =data[0];
|
||||||
|
@ -527,6 +537,7 @@ template<int vunum> static void __fc vuMicroWrite64(u32 addr, const mem64_t* dat
|
||||||
template<int vunum> static void __fc vuMicroWrite128(u32 addr, const mem128_t* data) {
|
template<int vunum> static void __fc vuMicroWrite128(u32 addr, const mem128_t* data) {
|
||||||
VURegs* vu = vunum ? &VU1 : &VU0;
|
VURegs* vu = vunum ? &VU1 : &VU0;
|
||||||
addr &= vunum ? 0x3fff: 0xfff;
|
addr &= vunum ? 0x3fff: 0xfff;
|
||||||
|
|
||||||
if (vunum && THREAD_VU1) {
|
if (vunum && THREAD_VU1) {
|
||||||
vu1Thread.WriteMicroMem(addr, (void*)data, sizeof(u128));
|
vu1Thread.WriteMicroMem(addr, (void*)data, sizeof(u128));
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "Patch.h"
|
#include "Patch.h"
|
||||||
#include "GameDatabase.h"
|
#include "GameDatabase.h"
|
||||||
#include <wx/textfile.h>
|
#include <wx/textfile.h>
|
||||||
|
#include <wx/dir.h>
|
||||||
|
|
||||||
IniPatch Patch[ MAX_PATCH ];
|
IniPatch Patch[ MAX_PATCH ];
|
||||||
IniPatch Cheat[ MAX_CHEAT ];
|
IniPatch Cheat[ MAX_CHEAT ];
|
||||||
|
@ -165,35 +166,60 @@ void inifile_process(wxTextFile &f1 )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResetCheatsCount()
|
||||||
|
{
|
||||||
|
cheatnumber = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LoadCheatsFiles(const wxString& folderName, wxString& fileSpec, const wxString& friendlyName)
|
||||||
|
{
|
||||||
|
if (!wxDir::Exists(folderName)) {
|
||||||
|
Console.WriteLn(Color_Red, L"The %s folder ('%s') is inaccessible. Skipping...", friendlyName.c_str(), folderName.c_str());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
wxDir dir(folderName);
|
||||||
|
|
||||||
|
int before = cheatnumber;
|
||||||
|
wxString buffer;
|
||||||
|
wxTextFile f;
|
||||||
|
bool found = dir.GetFirst(&buffer, fileSpec, wxDIR_FILES);
|
||||||
|
while (found) {
|
||||||
|
Console.WriteLn(Color_Gray, L"Found %s file: '%s'", friendlyName.c_str(), buffer.c_str());
|
||||||
|
int before = cheatnumber;
|
||||||
|
f.Open(Path::Combine(dir.GetName(), buffer));
|
||||||
|
inifile_process(f);
|
||||||
|
f.Close();
|
||||||
|
int loaded = cheatnumber - before;
|
||||||
|
Console.WriteLn((loaded ? Color_Green : Color_Gray), L"Loaded %d %s from '%s'", loaded, friendlyName.c_str(), buffer.c_str());
|
||||||
|
found = dir.GetNext(&buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cheatnumber - before;
|
||||||
|
}
|
||||||
|
|
||||||
// This routine loads cheats from *.pnach files
|
// This routine loads cheats from *.pnach files
|
||||||
// Returns number of cheats loaded
|
// Returns number of cheats loaded
|
||||||
// Note: Should be called after InitPatches()
|
// Note: Should be called after InitPatches()
|
||||||
int InitCheats(const wxString& name)
|
int LoadCheats(wxString name, const wxString& folderName, const wxString& friendlyName)
|
||||||
{
|
{
|
||||||
wxTextFile f1;
|
if (!name.Length()) {
|
||||||
wxString buffer;
|
Console.WriteLn(Color_Gray, "Cheats: No CRC, using 00000000 instead.");
|
||||||
cheatnumber = 0;
|
name = L"00000000";
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME : We need to add a 'cheats' folder to the AppConfig, and use that instead. --air
|
int loaded = 0;
|
||||||
|
|
||||||
buffer = Path::Combine(L"cheats", name + L".pnach");
|
wxString filespec = name + L"*.pnach";
|
||||||
|
loaded += LoadCheatsFiles(folderName, filespec, friendlyName);
|
||||||
|
|
||||||
if(!f1.Open(buffer) && wxFileName::IsCaseSensitive())
|
wxString nameUpper = name; nameUpper.Upper();
|
||||||
{
|
if (wxFileName::IsCaseSensitive() && name != nameUpper) {
|
||||||
f1.Open( Path::Combine(L"cheats", name.Upper() + L".pnach") );
|
filespec = nameUpper + L"*.pnach";
|
||||||
}
|
loaded += LoadCheatsFiles(folderName, filespec, friendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
if(!f1.IsOpened())
|
Console.WriteLn((loaded ? Color_Green : Color_Gray), L"Overall %d %s loaded", loaded, friendlyName.c_str());
|
||||||
{
|
return loaded;
|
||||||
Console.WriteLn( Color_Gray, "No cheats found. Resuming execution without cheats..." );
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Console.WriteLn( Color_Green, "Cheats found!");
|
|
||||||
inifile_process( f1 );
|
|
||||||
|
|
||||||
Console.WriteLn("Cheats Loaded: %d", cheatnumber);
|
|
||||||
return cheatnumber;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 StrToU32(const wxString& str, int base = 10)
|
static u32 StrToU32(const wxString& str, int base = 10)
|
||||||
|
|
|
@ -57,7 +57,8 @@ namespace PatchFunc
|
||||||
PATCHTABLEFUNC cheat;
|
PATCHTABLEFUNC cheat;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int InitCheats(const wxString& name);
|
extern void ResetCheatsCount();
|
||||||
|
extern int LoadCheats(wxString name, const wxString& folderName, const wxString& friendlyName);
|
||||||
extern void inifile_command(bool isCheat, const wxString& cmd);
|
extern void inifile_command(bool isCheat, const wxString& cmd);
|
||||||
extern void inifile_trim(wxString& buffer);
|
extern void inifile_trim(wxString& buffer);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@ void SysPluginBindings::McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo&
|
||||||
Mcd->McdGetSizeInfo( (PS2E_THISPTR) Mcd, port, slot, &outways );
|
Mcd->McdGetSizeInfo( (PS2E_THISPTR) Mcd, port, slot, &outways );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SysPluginBindings::McdIsPSX( uint port, uint slot )
|
||||||
|
{
|
||||||
|
return Mcd->McdIsPSX( (PS2E_THISPTR) Mcd, port, slot );
|
||||||
|
}
|
||||||
|
|
||||||
void SysPluginBindings::McdRead( uint port, uint slot, u8 *dest, u32 adr, int size )
|
void SysPluginBindings::McdRead( uint port, uint slot, u8 *dest, u32 adr, int size )
|
||||||
{
|
{
|
||||||
Mcd->McdRead( (PS2E_THISPTR) Mcd, port, slot, dest, adr, size );
|
Mcd->McdRead( (PS2E_THISPTR) Mcd, port, slot, dest, adr, size );
|
||||||
|
|
|
@ -236,6 +236,7 @@ public:
|
||||||
|
|
||||||
bool McdIsPresent( uint port, uint slot );
|
bool McdIsPresent( uint port, uint slot );
|
||||||
void McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways );
|
void McdGetSizeInfo( uint port, uint slot, PS2E_McdSizeInfo& outways );
|
||||||
|
bool McdIsPSX( uint port, uint slot );
|
||||||
void McdRead( uint port, uint slot, u8 *dest, u32 adr, int size );
|
void McdRead( uint port, uint slot, u8 *dest, u32 adr, int size );
|
||||||
void McdSave( uint port, uint slot, const u8 *src, u32 adr, int size );
|
void McdSave( uint port, uint slot, const u8 *src, u32 adr, int size );
|
||||||
void McdEraseBlock( uint port, uint slot, u32 adr );
|
void McdEraseBlock( uint port, uint slot, u32 adr );
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct REG_VI {
|
||||||
|
|
||||||
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
//#define VUFLAG_BREAKONMFLAG 0x00000001
|
||||||
#define VUFLAG_MFLAGSET 0x00000002
|
#define VUFLAG_MFLAGSET 0x00000002
|
||||||
|
#define VUFLAG_INTCINTERRUPT 0x00000004
|
||||||
struct fdivPipe {
|
struct fdivPipe {
|
||||||
int enable;
|
int enable;
|
||||||
REG_VI reg;
|
REG_VI reg;
|
||||||
|
@ -154,6 +154,10 @@ struct __aligned16 VURegs {
|
||||||
|
|
||||||
u32 ebit;
|
u32 ebit;
|
||||||
|
|
||||||
|
u8 VIBackupCycles;
|
||||||
|
u32 VIOldValue;
|
||||||
|
u32 VIRegNumber;
|
||||||
|
|
||||||
fmacPipe fmac[8];
|
fmacPipe fmac[8];
|
||||||
fdivPipe fdiv;
|
fdivPipe fdiv;
|
||||||
efuPipe efu;
|
efuPipe efu;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue