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:
gregory.hainaut 2013-05-18 16:09:09 +00:00
commit b8e36b44af
215 changed files with 24934 additions and 4823 deletions

View File

@ -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
{ {

View File

@ -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;
}; };

370
3rdparty/SoundTouch/BPMDetect.cpp vendored Normal file
View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}; };
} }

View File

@ -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);
}
}; };
} }

View File

@ -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

View File

@ -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
} }

View File

@ -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

276
3rdparty/SoundTouch/PeakFinder.cpp vendored Normal file
View File

@ -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;
}

97
3rdparty/SoundTouch/PeakFinder.h vendored Normal file
View File

@ -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

View File

@ -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++;

View File

@ -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);

View File

@ -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

View File

@ -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;
} }
} }

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 $

137
3rdparty/SoundTouch/cpu_detect_x86.cpp vendored Normal file
View File

@ -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
}

View File

@ -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
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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

View File

@ -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>

359
3rdparty/winpcap/include/Packet32.h vendored Normal file
View File

@ -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

View File

@ -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__

137
3rdparty/winpcap/include/bittypes.h vendored Normal file
View File

@ -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 */

163
3rdparty/winpcap/include/ip6_misc.h vendored Normal file
View File

@ -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__ */

47
3rdparty/winpcap/include/pcap-bpf.h vendored Normal file
View File

@ -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>

42
3rdparty/winpcap/include/pcap-namedb.h vendored Normal file
View File

@ -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>

94
3rdparty/winpcap/include/pcap-stdinc.h vendored Normal file
View File

@ -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__*/

45
3rdparty/winpcap/include/pcap.h vendored Normal file
View File

@ -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>

View File

@ -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

934
3rdparty/winpcap/include/pcap/bpf.h vendored Normal file
View File

@ -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

89
3rdparty/winpcap/include/pcap/namedb.h vendored Normal file
View File

@ -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

407
3rdparty/winpcap/include/pcap/pcap.h vendored Normal file
View File

@ -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

129
3rdparty/winpcap/include/pcap/sll.h vendored Normal file
View File

@ -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

90
3rdparty/winpcap/include/pcap/usb.h vendored Normal file
View File

@ -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

46
3rdparty/winpcap/include/pcap/vlan.h vendored Normal file
View File

@ -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

444
3rdparty/winpcap/include/remote-ext.h vendored Normal file
View File

@ -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

BIN
3rdparty/winpcap/lib/Packet.lib vendored Normal file

Binary file not shown.

BIN
3rdparty/winpcap/lib/wpcap.lib vendored Normal file

Binary file not shown.

BIN
3rdparty/winpcap/lib/x64/Packet.lib vendored Normal file

Binary file not shown.

BIN
3rdparty/winpcap/lib/x64/wpcap.lib vendored Normal file

Binary file not shown.

3
3rdparty/winpcap/readme.txt vendored Normal file
View File

@ -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.

View File

@ -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>

View File

@ -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>

View File

@ -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>

2539
3rdparty/zlib/ChangeLog vendored

File diff suppressed because it is too large Load Diff

734
3rdparty/zlib/FAQ vendored
View File

@ -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.

229
3rdparty/zlib/README vendored
View File

@ -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.

View File

@ -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);

85
3rdparty/zlib/crc32.c vendored
View File

@ -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 */

View File

@ -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,

View File

@ -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;
} }

View File

@ -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) \

113
3rdparty/zlib/gzguts.h vendored
View File

@ -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

179
3rdparty/zlib/gzlib.c vendored
View File

@ -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;

417
3rdparty/zlib/gzread.c vendored
View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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 */
{ {

View File

@ -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));

View File

@ -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] = {

View File

@ -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);

View File

@ -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 */

View File

@ -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));

55
3rdparty/zlib/trees.c vendored
View File

@ -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);

View File

@ -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,

210
3rdparty/zlib/zconf.h vendored
View File

@ -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 */

339
3rdparty/zlib/zlib.h vendored
View File

@ -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
} }

46
3rdparty/zlib/zutil.c vendored
View File

@ -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 */

133
3rdparty/zlib/zutil.h vendored
View File

@ -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 */

View File

@ -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

View File

@ -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'"

View File

@ -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)

View File

@ -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()

View File

@ -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)")

View File

@ -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>

View File

@ -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);
} }
}; };

View File

@ -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

View File

@ -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

61
linux_various/glsl2h.pl Executable file
View File

@ -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";
}

View File

@ -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 ) );

View File

@ -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;

View File

@ -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);
}
}
} }

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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 );

View File

@ -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 );

View File

@ -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