Copy project optimization settings from official source
This commit is contained in:
parent
293b4cf599
commit
8da2a6eb10
|
@ -1,406 +0,0 @@
|
|||
|
||||
// Blip_Buffer 0.4.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module 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
|
||||
module 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 module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
int const buffer_extra = blip_widest_impulse_ + 2;
|
||||
|
||||
Blip_Buffer::Blip_Buffer()
|
||||
{
|
||||
factor_ = LONG_MAX;
|
||||
offset_ = 0;
|
||||
buffer_ = 0;
|
||||
buffer_size_ = 0;
|
||||
sample_rate_ = 0;
|
||||
reader_accum = 0;
|
||||
bass_shift = 0;
|
||||
clock_rate_ = 0;
|
||||
bass_freq_ = 16;
|
||||
length_ = 0;
|
||||
|
||||
// assumptions code makes about implementation-defined features
|
||||
#ifndef NDEBUG
|
||||
// right shift of negative value preserves sign
|
||||
buf_t_ i = -0x7FFFFFFE;
|
||||
assert( (i >> 1) == -0x3FFFFFFF );
|
||||
|
||||
// casting to short truncates to 16 bits and sign-extends
|
||||
i = 0x18000;
|
||||
assert( (short) i == -0x8000 );
|
||||
#endif
|
||||
}
|
||||
|
||||
Blip_Buffer::~Blip_Buffer()
|
||||
{
|
||||
free( buffer_ );
|
||||
}
|
||||
|
||||
void Blip_Buffer::clear( int entire_buffer )
|
||||
{
|
||||
offset_ = 0;
|
||||
reader_accum = 0;
|
||||
if ( buffer_ )
|
||||
{
|
||||
long count = (entire_buffer ? buffer_size_ : samples_avail());
|
||||
memset( buffer_, 0, (count + buffer_extra) * sizeof (buf_t_) );
|
||||
}
|
||||
}
|
||||
|
||||
Blip_Buffer::blargg_err_t Blip_Buffer::set_sample_rate( long new_rate, int msec )
|
||||
{
|
||||
// start with maximum length that resampled time can represent
|
||||
long new_size = (ULONG_MAX >> BLIP_BUFFER_ACCURACY) - buffer_extra - 64;
|
||||
if ( msec != blip_max_length )
|
||||
{
|
||||
long s = (new_rate * (msec + 1) + 999) / 1000;
|
||||
if ( s < new_size )
|
||||
new_size = s;
|
||||
else
|
||||
assert( 0 ); // fails if requested buffer length exceeds limit
|
||||
}
|
||||
|
||||
if ( buffer_size_ != new_size )
|
||||
{
|
||||
void* p = realloc( buffer_, (new_size + buffer_extra) * sizeof *buffer_ );
|
||||
if ( !p )
|
||||
return "Out of memory";
|
||||
buffer_ = (buf_t_*) p;
|
||||
}
|
||||
|
||||
buffer_size_ = new_size;
|
||||
|
||||
// update things based on the sample rate
|
||||
sample_rate_ = new_rate;
|
||||
length_ = new_size * 1000 / new_rate - 1;
|
||||
if ( msec )
|
||||
assert( length_ == msec ); // ensure length is same as that passed in
|
||||
if ( clock_rate_ )
|
||||
clock_rate( clock_rate_ );
|
||||
bass_freq( bass_freq_ );
|
||||
|
||||
clear();
|
||||
|
||||
return 0; // success
|
||||
}
|
||||
|
||||
blip_resampled_time_t Blip_Buffer::clock_rate_factor( long clock_rate ) const
|
||||
{
|
||||
double ratio = (double) sample_rate_ / clock_rate;
|
||||
long factor = (long) floor( ratio * (1L << BLIP_BUFFER_ACCURACY) + 0.5 );
|
||||
assert( factor > 0 || !sample_rate_ ); // fails if clock/output ratio is too large
|
||||
return (blip_resampled_time_t) factor;
|
||||
}
|
||||
|
||||
void Blip_Buffer::bass_freq( int freq )
|
||||
{
|
||||
bass_freq_ = freq;
|
||||
int shift = 31;
|
||||
if ( freq > 0 )
|
||||
{
|
||||
shift = 13;
|
||||
long f = (freq << 16) / sample_rate_;
|
||||
while ( (f >>= 1) && --shift ) { }
|
||||
}
|
||||
bass_shift = shift;
|
||||
}
|
||||
|
||||
void Blip_Buffer::end_frame( blip_time_t t )
|
||||
{
|
||||
offset_ += t * factor_;
|
||||
assert( samples_avail() <= (long) buffer_size_ ); // time outside buffer length
|
||||
}
|
||||
|
||||
void Blip_Buffer::remove_silence( long count )
|
||||
{
|
||||
assert( count <= samples_avail() ); // tried to remove more samples than available
|
||||
offset_ -= (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
|
||||
}
|
||||
|
||||
long Blip_Buffer::count_samples( blip_time_t t ) const
|
||||
{
|
||||
unsigned long last_sample = resampled_time( t ) >> BLIP_BUFFER_ACCURACY;
|
||||
unsigned long first_sample = offset_ >> BLIP_BUFFER_ACCURACY;
|
||||
return (long) (last_sample - first_sample);
|
||||
}
|
||||
|
||||
blip_time_t Blip_Buffer::count_clocks( long count ) const
|
||||
{
|
||||
if ( count > buffer_size_ )
|
||||
count = buffer_size_;
|
||||
blip_resampled_time_t time = (blip_resampled_time_t) count << BLIP_BUFFER_ACCURACY;
|
||||
return (blip_time_t) ((time - offset_ + factor_ - 1) / factor_);
|
||||
}
|
||||
|
||||
void Blip_Buffer::remove_samples( long count )
|
||||
{
|
||||
if ( count )
|
||||
{
|
||||
remove_silence( count );
|
||||
|
||||
// copy remaining samples to beginning and clear old samples
|
||||
long remain = samples_avail() + buffer_extra;
|
||||
memmove( buffer_, buffer_ + count, remain * sizeof *buffer_ );
|
||||
memset( buffer_ + remain, 0, count * sizeof *buffer_ );
|
||||
}
|
||||
}
|
||||
|
||||
// Blip_Synth_
|
||||
|
||||
Blip_Synth_::Blip_Synth_( short* p, int w ) :
|
||||
impulses( p ),
|
||||
width( w )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
kernel_unit = 0;
|
||||
buf = 0;
|
||||
last_amp = 0;
|
||||
delta_factor = 0;
|
||||
}
|
||||
|
||||
static double const pi = 3.1415926535897932384626433832795029;
|
||||
|
||||
static void gen_sinc( float* out, int count, double oversample, double treble, double cutoff )
|
||||
{
|
||||
if ( cutoff >= 0.999 )
|
||||
cutoff = 0.999;
|
||||
|
||||
if ( treble < -300.0 )
|
||||
treble = -300.0;
|
||||
if ( treble > 5.0 )
|
||||
treble = 5.0;
|
||||
|
||||
double const maxh = 4096.0;
|
||||
double const rolloff = pow( 10.0, 1.0 / (maxh * 20.0) * treble / (1.0 - cutoff) );
|
||||
double const pow_a_n = pow( rolloff, maxh - maxh * cutoff );
|
||||
double const to_angle = pi / 2 / maxh / oversample;
|
||||
for ( int i = 0; i < count; i++ )
|
||||
{
|
||||
double angle = ((i - count) * 2 + 1) * to_angle;
|
||||
double c = rolloff * cos( (maxh - 1.0) * angle ) - cos( maxh * angle );
|
||||
double cos_nc_angle = cos( maxh * cutoff * angle );
|
||||
double cos_nc1_angle = cos( (maxh * cutoff - 1.0) * angle );
|
||||
double cos_angle = cos( angle );
|
||||
|
||||
c = c * pow_a_n - rolloff * cos_nc1_angle + cos_nc_angle;
|
||||
double d = 1.0 + rolloff * (rolloff - cos_angle - cos_angle);
|
||||
double b = 2.0 - cos_angle - cos_angle;
|
||||
double a = 1.0 - cos_angle - cos_nc_angle + cos_nc1_angle;
|
||||
|
||||
out [i] = (float) ((a * d + c * b) / (b * d)); // a / b + c / d
|
||||
}
|
||||
}
|
||||
|
||||
void blip_eq_t::generate( float* out, int count ) const
|
||||
{
|
||||
// lower cutoff freq for narrow kernels with their wider transition band
|
||||
// (8 points->1.49, 16 points->1.15)
|
||||
double oversample = blip_res * 2.25 / count + 0.85;
|
||||
double half_rate = sample_rate * 0.5;
|
||||
if ( cutoff_freq )
|
||||
oversample = half_rate / cutoff_freq;
|
||||
double cutoff = rolloff_freq * oversample / half_rate;
|
||||
|
||||
gen_sinc( out, count, blip_res * oversample, treble, cutoff );
|
||||
|
||||
// apply (half of) hamming window
|
||||
double to_fraction = pi / (count - 1);
|
||||
for ( int i = count; i--; )
|
||||
out [i] *= 0.54 - 0.46 * cos( i * to_fraction );
|
||||
}
|
||||
|
||||
void Blip_Synth_::adjust_impulse()
|
||||
{
|
||||
// sum pairs for each phase and add error correction to end of first half
|
||||
int const size = impulses_size();
|
||||
for ( int p = blip_res; p-- >= blip_res / 2; )
|
||||
{
|
||||
int p2 = blip_res - 2 - p;
|
||||
long error = kernel_unit;
|
||||
for ( int i = 1; i < size; i += blip_res )
|
||||
{
|
||||
error -= impulses [i + p ];
|
||||
error -= impulses [i + p2];
|
||||
}
|
||||
if ( p == p2 )
|
||||
error /= 2; // phase = 0.5 impulse uses same half for both sides
|
||||
impulses [size - blip_res + p] += error;
|
||||
//printf( "error: %ld\n", error );
|
||||
}
|
||||
|
||||
//for ( int i = blip_res; i--; printf( "\n" ) )
|
||||
// for ( int j = 0; j < width / 2; j++ )
|
||||
// printf( "%5ld,", impulses [j * blip_res + i + 1] );
|
||||
}
|
||||
|
||||
void Blip_Synth_::treble_eq( blip_eq_t const& eq )
|
||||
{
|
||||
float fimpulse [blip_res / 2 * (blip_widest_impulse_ - 1) + blip_res * 2];
|
||||
|
||||
int const half_size = blip_res / 2 * (width - 1);
|
||||
eq.generate( &fimpulse [blip_res], half_size );
|
||||
|
||||
int i;
|
||||
|
||||
// need mirror slightly past center for calculation
|
||||
for ( i = blip_res; i--; )
|
||||
fimpulse [blip_res + half_size + i] = fimpulse [blip_res + half_size - 1 - i];
|
||||
|
||||
// starts at 0
|
||||
for ( i = 0; i < blip_res; i++ )
|
||||
fimpulse [i] = 0.0f;
|
||||
|
||||
// find rescale factor
|
||||
double total = 0.0;
|
||||
for ( i = 0; i < half_size; i++ )
|
||||
total += fimpulse [blip_res + i];
|
||||
|
||||
//double const base_unit = 44800.0 - 128 * 18; // allows treble up to +0 dB
|
||||
//double const base_unit = 37888.0; // allows treble to +5 dB
|
||||
double const base_unit = 32768.0; // necessary for blip_unscaled to work
|
||||
double rescale = base_unit / 2 / total;
|
||||
kernel_unit = (long) base_unit;
|
||||
|
||||
// integrate, first difference, rescale, convert to int
|
||||
double sum = 0.0;
|
||||
double next = 0.0;
|
||||
int const impulses_size = this->impulses_size();
|
||||
for ( i = 0; i < impulses_size; i++ )
|
||||
{
|
||||
impulses [i] = (short) floor( (next - sum) * rescale + 0.5 );
|
||||
sum += fimpulse [i];
|
||||
next += fimpulse [i + blip_res];
|
||||
}
|
||||
adjust_impulse();
|
||||
|
||||
// volume might require rescaling
|
||||
double vol = volume_unit_;
|
||||
if ( vol )
|
||||
{
|
||||
volume_unit_ = 0.0;
|
||||
volume_unit( vol );
|
||||
}
|
||||
}
|
||||
|
||||
void Blip_Synth_::volume_unit( double new_unit )
|
||||
{
|
||||
if ( new_unit != volume_unit_ )
|
||||
{
|
||||
// use default eq if it hasn't been set yet
|
||||
if ( !kernel_unit )
|
||||
treble_eq( -8.0 );
|
||||
|
||||
volume_unit_ = new_unit;
|
||||
double factor = new_unit * (1L << blip_sample_bits) / kernel_unit;
|
||||
|
||||
if ( factor > 0.0 )
|
||||
{
|
||||
int shift = 0;
|
||||
|
||||
// if unit is really small, might need to attenuate kernel
|
||||
while ( factor < 2.0 )
|
||||
{
|
||||
shift++;
|
||||
factor *= 2.0;
|
||||
}
|
||||
|
||||
if ( shift )
|
||||
{
|
||||
kernel_unit >>= shift;
|
||||
assert( kernel_unit > 0 ); // fails if volume unit is too low
|
||||
|
||||
// keep values positive to avoid round-towards-zero of sign-preserving
|
||||
// right shift for negative values
|
||||
long offset = 0x8000 + (1 << (shift - 1));
|
||||
long offset2 = 0x8000 >> shift;
|
||||
for ( int i = impulses_size(); i--; )
|
||||
impulses [i] = (short) (((impulses [i] + offset) >> shift) - offset2);
|
||||
adjust_impulse();
|
||||
}
|
||||
}
|
||||
delta_factor = (int) floor( factor + 0.5 );
|
||||
//printf( "delta_factor: %d, kernel_unit: %d\n", delta_factor, kernel_unit );
|
||||
}
|
||||
}
|
||||
|
||||
long Blip_Buffer::read_samples( blip_sample_t* out, long max_samples, int stereo )
|
||||
{
|
||||
long count = samples_avail();
|
||||
if ( count > max_samples )
|
||||
count = max_samples;
|
||||
|
||||
if ( count )
|
||||
{
|
||||
int const sample_shift = blip_sample_bits - 16;
|
||||
int const bass_shift = this->bass_shift;
|
||||
long accum = reader_accum;
|
||||
buf_t_* in = buffer_;
|
||||
|
||||
if ( !stereo )
|
||||
{
|
||||
for ( long n = count; n--; )
|
||||
{
|
||||
long s = accum >> sample_shift;
|
||||
accum -= accum >> bass_shift;
|
||||
accum += *in++;
|
||||
*out++ = (blip_sample_t) s;
|
||||
|
||||
// clamp sample
|
||||
if ( (blip_sample_t) s != s )
|
||||
out [-1] = (blip_sample_t) (0x7FFF - (s >> 24));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( long n = count; n--; )
|
||||
{
|
||||
long s = accum >> sample_shift;
|
||||
accum -= accum >> bass_shift;
|
||||
accum += *in++;
|
||||
*out = (blip_sample_t) s;
|
||||
out += 2;
|
||||
|
||||
// clamp sample
|
||||
if ( (blip_sample_t) s != s )
|
||||
out [-2] = (blip_sample_t) (0x7FFF - (s >> 24));
|
||||
}
|
||||
}
|
||||
|
||||
reader_accum = accum;
|
||||
remove_samples( count );
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
void Blip_Buffer::mix_samples( blip_sample_t const* in, long count )
|
||||
{
|
||||
buf_t_* out = buffer_ + (offset_ >> BLIP_BUFFER_ACCURACY) + blip_widest_impulse_ / 2;
|
||||
|
||||
int const sample_shift = blip_sample_bits - 16;
|
||||
int prev = 0;
|
||||
while ( count-- )
|
||||
{
|
||||
long s = (long) *in++ << sample_shift;
|
||||
*out += s - prev;
|
||||
prev = s;
|
||||
++out;
|
||||
}
|
||||
*out -= prev;
|
||||
}
|
||||
|
|
@ -1,354 +0,0 @@
|
|||
|
||||
// Band-limited sound synthesis and buffering
|
||||
|
||||
// Blip_Buffer 0.4.0
|
||||
|
||||
#ifndef BLIP_BUFFER_H
|
||||
#define BLIP_BUFFER_H
|
||||
|
||||
// Time unit at source clock rate
|
||||
typedef long blip_time_t;
|
||||
|
||||
// Output samples are 16-bit signed, with a range of -32768 to 32767
|
||||
typedef short blip_sample_t;
|
||||
enum { blip_sample_max = 32767 };
|
||||
|
||||
class Blip_Buffer {
|
||||
public:
|
||||
typedef const char* blargg_err_t;
|
||||
|
||||
// Set output sample rate and buffer length in milliseconds (1/1000 sec, defaults
|
||||
// to 1/4 second), then clear buffer. Returns NULL on success, otherwise if there
|
||||
// isn't enough memory, returns error without affecting current buffer setup.
|
||||
blargg_err_t set_sample_rate( long samples_per_sec, int msec_length = 1000 / 4 );
|
||||
|
||||
// Set number of source time units per second
|
||||
void clock_rate( long );
|
||||
|
||||
// End current time frame of specified duration and make its samples available
|
||||
// (along with any still-unread samples) for reading with read_samples(). Begins
|
||||
// a new time frame at the end of the current frame.
|
||||
void end_frame( blip_time_t time );
|
||||
|
||||
// Read at most 'max_samples' out of buffer into 'dest', removing them from from
|
||||
// the buffer. Returns number of samples actually read and removed. If stereo is
|
||||
// true, increments 'dest' one extra time after writing each sample, to allow
|
||||
// easy interleving of two channels into a stereo output buffer.
|
||||
long read_samples( blip_sample_t* dest, long max_samples, int stereo = 0 );
|
||||
|
||||
// Additional optional features
|
||||
|
||||
// Current output sample rate
|
||||
long sample_rate() const;
|
||||
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
|
||||
// Number of source time units per second
|
||||
long clock_rate() const;
|
||||
|
||||
// Set frequency high-pass filter frequency, where higher values reduce bass more
|
||||
void bass_freq( int frequency );
|
||||
|
||||
// Number of samples delay from synthesis to samples read out
|
||||
int output_latency() const;
|
||||
|
||||
// Remove all available samples and clear buffer to silence. If 'entire_buffer' is
|
||||
// false, just clears out any samples waiting rather than the entire buffer.
|
||||
void clear( int entire_buffer = 1 );
|
||||
|
||||
// Number of samples available for reading with read_samples()
|
||||
long samples_avail() const;
|
||||
|
||||
// Remove 'count' samples from those waiting to be read
|
||||
void remove_samples( long count );
|
||||
|
||||
// Experimental features
|
||||
|
||||
// Number of raw samples that can be mixed within frame of specified duration.
|
||||
long count_samples( blip_time_t duration ) const;
|
||||
|
||||
// Mix 'count' samples from 'buf' into buffer.
|
||||
void mix_samples( blip_sample_t const* buf, long count );
|
||||
|
||||
// Count number of clocks needed until 'count' samples will be available.
|
||||
// If buffer can't even hold 'count' samples, returns number of clocks until
|
||||
// buffer becomes full.
|
||||
blip_time_t count_clocks( long count ) const;
|
||||
|
||||
// not documented yet
|
||||
typedef unsigned long blip_resampled_time_t;
|
||||
void remove_silence( long count );
|
||||
blip_resampled_time_t resampled_duration( int t ) const { return t * factor_; }
|
||||
blip_resampled_time_t resampled_time( blip_time_t t ) const { return t * factor_ + offset_; }
|
||||
blip_resampled_time_t clock_rate_factor( long clock_rate ) const;
|
||||
public:
|
||||
Blip_Buffer();
|
||||
~Blip_Buffer();
|
||||
|
||||
// Deprecated
|
||||
typedef blip_resampled_time_t resampled_time_t;
|
||||
blargg_err_t sample_rate( long r ) { return set_sample_rate( r ); }
|
||||
blargg_err_t sample_rate( long r, int msec ) { return set_sample_rate( r, msec ); }
|
||||
private:
|
||||
// noncopyable
|
||||
Blip_Buffer( const Blip_Buffer& );
|
||||
Blip_Buffer& operator = ( const Blip_Buffer& );
|
||||
public:
|
||||
typedef long buf_t_;
|
||||
unsigned long factor_;
|
||||
blip_resampled_time_t offset_;
|
||||
buf_t_* buffer_;
|
||||
long buffer_size_;
|
||||
private:
|
||||
long reader_accum;
|
||||
int bass_shift;
|
||||
long sample_rate_;
|
||||
long clock_rate_;
|
||||
int bass_freq_;
|
||||
int length_;
|
||||
friend class Blip_Reader;
|
||||
};
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
// Number of bits in resample ratio fraction. Higher values give a more accurate ratio
|
||||
// but reduce maximum buffer size.
|
||||
#ifndef BLIP_BUFFER_ACCURACY
|
||||
#define BLIP_BUFFER_ACCURACY 16
|
||||
#endif
|
||||
|
||||
// Number bits in phase offset. Fewer than 6 bits (64 phase offsets) results in
|
||||
// noticeable broadband noise when synthesizing high frequency square waves.
|
||||
// Affects size of Blip_Synth objects since they store the waveform directly.
|
||||
#ifndef BLIP_PHASE_BITS
|
||||
#define BLIP_PHASE_BITS 6
|
||||
#endif
|
||||
|
||||
// Internal
|
||||
typedef unsigned long blip_resampled_time_t;
|
||||
int const blip_widest_impulse_ = 16;
|
||||
int const blip_res = 1 << BLIP_PHASE_BITS;
|
||||
class blip_eq_t;
|
||||
|
||||
class Blip_Synth_ {
|
||||
double volume_unit_;
|
||||
short* const impulses;
|
||||
int const width;
|
||||
long kernel_unit;
|
||||
int impulses_size() const { return blip_res / 2 * width + 1; }
|
||||
void adjust_impulse();
|
||||
public:
|
||||
Blip_Buffer* buf;
|
||||
int last_amp;
|
||||
int delta_factor;
|
||||
|
||||
Blip_Synth_( short* impulses, int width );
|
||||
void treble_eq( blip_eq_t const& );
|
||||
void volume_unit( double );
|
||||
};
|
||||
|
||||
// Quality level. Start with blip_good_quality.
|
||||
const int blip_med_quality = 8;
|
||||
const int blip_good_quality = 12;
|
||||
const int blip_high_quality = 16;
|
||||
|
||||
// Range specifies the greatest expected change in amplitude. Calculate it
|
||||
// by finding the difference between the maximum and minimum expected
|
||||
// amplitudes (max - min).
|
||||
template<int quality,int range>
|
||||
class Blip_Synth {
|
||||
public:
|
||||
// Set overall volume of waveform
|
||||
void volume( double v ) { impl.volume_unit( v * (1.0 / (range < 0 ? -range : range)) ); }
|
||||
|
||||
// Configure low-pass filter (see notes.txt)
|
||||
void treble_eq( blip_eq_t const& eq ) { impl.treble_eq( eq ); }
|
||||
|
||||
// Get/set Blip_Buffer used for output
|
||||
Blip_Buffer* output() const { return impl.buf; }
|
||||
void output( Blip_Buffer* b ) { impl.buf = b; impl.last_amp = 0; }
|
||||
|
||||
// Update amplitude of waveform at given time. Using this requires a separate
|
||||
// Blip_Synth for each waveform.
|
||||
void update( blip_time_t time, int amplitude );
|
||||
|
||||
// Low-level interface
|
||||
|
||||
// Add an amplitude transition of specified delta, optionally into specified buffer
|
||||
// rather than the one set with output(). Delta can be positive or negative.
|
||||
// The actual change in amplitude is delta * (volume / range)
|
||||
void offset( blip_time_t, int delta, Blip_Buffer* ) const;
|
||||
void offset( blip_time_t t, int delta ) const { offset( t, delta, impl.buf ); }
|
||||
|
||||
// Works directly in terms of fractional output samples. Contact author for more.
|
||||
void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
|
||||
|
||||
// Same as offset(), except code is inlined for higher performance
|
||||
void offset_inline( blip_time_t t, int delta, Blip_Buffer* buf ) const {
|
||||
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
|
||||
}
|
||||
void offset_inline( blip_time_t t, int delta ) const {
|
||||
offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
|
||||
}
|
||||
|
||||
public:
|
||||
Blip_Synth() : impl( impulses, quality ) { }
|
||||
private:
|
||||
typedef short imp_t;
|
||||
imp_t impulses [blip_res * (quality / 2) + 1];
|
||||
Blip_Synth_ impl;
|
||||
};
|
||||
|
||||
// Low-pass equalization parameters
|
||||
class blip_eq_t {
|
||||
public:
|
||||
// Logarithmic rolloff to treble dB at half sampling rate. Negative values reduce
|
||||
// treble, small positive values (0 to 5.0) increase treble.
|
||||
blip_eq_t( double treble_db = 0 );
|
||||
|
||||
// See notes.txt
|
||||
blip_eq_t( double treble, long rolloff_freq, long sample_rate, long cutoff_freq = 0 );
|
||||
|
||||
private:
|
||||
double treble;
|
||||
long rolloff_freq;
|
||||
long sample_rate;
|
||||
long cutoff_freq;
|
||||
void generate( float* out, int count ) const;
|
||||
friend class Blip_Synth_;
|
||||
};
|
||||
|
||||
int const blip_sample_bits = 30;
|
||||
|
||||
// Optimized inline sample reader for custom sample formats and mixing of Blip_Buffer samples
|
||||
class Blip_Reader {
|
||||
public:
|
||||
// Begin reading samples from buffer. Returns value to pass to next() (can
|
||||
// be ignored if default bass_freq is acceptable).
|
||||
int begin( Blip_Buffer& );
|
||||
|
||||
// Current sample
|
||||
long read() const { return accum >> (blip_sample_bits - 16); }
|
||||
|
||||
// Current raw sample in full internal resolution
|
||||
long read_raw() const { return accum; }
|
||||
|
||||
// Advance to next sample
|
||||
void next( int bass_shift = 9 ) { accum += *buf++ - (accum >> bass_shift); }
|
||||
|
||||
// End reading samples from buffer. The number of samples read must now be removed
|
||||
// using Blip_Buffer::remove_samples().
|
||||
void end( Blip_Buffer& b ) { b.reader_accum = accum; }
|
||||
|
||||
private:
|
||||
const Blip_Buffer::buf_t_* buf;
|
||||
long accum;
|
||||
};
|
||||
|
||||
|
||||
// End of public interface
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Compatibility with older version
|
||||
const long blip_unscaled = 65535;
|
||||
const int blip_low_quality = blip_med_quality;
|
||||
const int blip_best_quality = blip_high_quality;
|
||||
|
||||
#define BLIP_FWD( i ) { \
|
||||
long t0 = i0 * delta + buf [fwd + i]; \
|
||||
long t1 = imp [blip_res * (i + 1)] * delta + buf [fwd + 1 + i]; \
|
||||
i0 = imp [blip_res * (i + 2)]; \
|
||||
buf [fwd + i] = t0; \
|
||||
buf [fwd + 1 + i] = t1; }
|
||||
|
||||
#define BLIP_REV( r ) { \
|
||||
long t0 = i0 * delta + buf [rev - r]; \
|
||||
long t1 = imp [blip_res * r] * delta + buf [rev + 1 - r]; \
|
||||
i0 = imp [blip_res * (r - 1)]; \
|
||||
buf [rev - r] = t0; \
|
||||
buf [rev + 1 - r] = t1; }
|
||||
|
||||
template<int quality,int range>
|
||||
inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
|
||||
int delta, Blip_Buffer* blip_buf ) const
|
||||
{
|
||||
// Fails if time is beyond end of Blip_Buffer, due to a bug in caller code or the
|
||||
// need for a longer buffer as set by set_sample_rate().
|
||||
assert( (long) (time >> BLIP_BUFFER_ACCURACY) < blip_buf->buffer_size_ );
|
||||
delta *= impl.delta_factor;
|
||||
int phase = (int) (time >> (BLIP_BUFFER_ACCURACY - BLIP_PHASE_BITS) & (blip_res - 1));
|
||||
imp_t const* imp = impulses + blip_res - phase;
|
||||
long* buf = blip_buf->buffer_ + (time >> BLIP_BUFFER_ACCURACY);
|
||||
long i0 = *imp;
|
||||
|
||||
int const fwd = (blip_widest_impulse_ - quality) / 2;
|
||||
int const rev = fwd + quality - 2;
|
||||
|
||||
BLIP_FWD( 0 )
|
||||
if ( quality > 8 ) BLIP_FWD( 2 )
|
||||
if ( quality > 12 ) BLIP_FWD( 4 )
|
||||
{
|
||||
int const mid = quality / 2 - 1;
|
||||
long t0 = i0 * delta + buf [fwd + mid - 1];
|
||||
long t1 = imp [blip_res * mid] * delta + buf [fwd + mid];
|
||||
imp = impulses + phase;
|
||||
i0 = imp [blip_res * mid];
|
||||
buf [fwd + mid - 1] = t0;
|
||||
buf [fwd + mid] = t1;
|
||||
}
|
||||
if ( quality > 12 ) BLIP_REV( 6 )
|
||||
if ( quality > 8 ) BLIP_REV( 4 )
|
||||
BLIP_REV( 2 )
|
||||
|
||||
long t0 = i0 * delta + buf [rev];
|
||||
long t1 = *imp * delta + buf [rev + 1];
|
||||
buf [rev] = t0;
|
||||
buf [rev + 1] = t1;
|
||||
}
|
||||
|
||||
#undef BLIP_FWD
|
||||
#undef BLIP_REV
|
||||
|
||||
template<int quality,int range>
|
||||
void Blip_Synth<quality,range>::offset( blip_time_t t, int delta, Blip_Buffer* buf ) const
|
||||
{
|
||||
offset_resampled( t * buf->factor_ + buf->offset_, delta, buf );
|
||||
}
|
||||
|
||||
template<int quality,int range>
|
||||
void Blip_Synth<quality,range>::update( blip_time_t t, int amp )
|
||||
{
|
||||
int delta = amp - impl.last_amp;
|
||||
impl.last_amp = amp;
|
||||
offset_resampled( t * impl.buf->factor_ + impl.buf->offset_, delta, impl.buf );
|
||||
}
|
||||
|
||||
inline blip_eq_t::blip_eq_t( double t ) :
|
||||
treble( t ), rolloff_freq( 0 ), sample_rate( 44100 ), cutoff_freq( 0 ) { }
|
||||
inline blip_eq_t::blip_eq_t( double t, long rf, long sr, long cf ) :
|
||||
treble( t ), rolloff_freq( rf ), sample_rate( sr ), cutoff_freq( cf ) { }
|
||||
|
||||
inline int Blip_Buffer::length() const { return length_; }
|
||||
inline long Blip_Buffer::samples_avail() const { return (long) (offset_ >> BLIP_BUFFER_ACCURACY); }
|
||||
inline long Blip_Buffer::sample_rate() const { return sample_rate_; }
|
||||
inline int Blip_Buffer::output_latency() const { return blip_widest_impulse_ / 2; }
|
||||
inline long Blip_Buffer::clock_rate() const { return clock_rate_; }
|
||||
inline void Blip_Buffer::clock_rate( long cps ) { factor_ = clock_rate_factor( clock_rate_ = cps ); }
|
||||
|
||||
inline int Blip_Reader::begin( Blip_Buffer& blip_buf )
|
||||
{
|
||||
buf = blip_buf.buffer_;
|
||||
accum = blip_buf.reader_accum;
|
||||
return blip_buf.bass_shift;
|
||||
}
|
||||
|
||||
int const blip_max_length = 0;
|
||||
int const blip_default_length = 250;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,204 +0,0 @@
|
|||
|
||||
// Blip_Synth and Blip_Wave are waveform transition synthesizers for adding
|
||||
// waveforms to a Blip_Buffer.
|
||||
|
||||
// Blip_Buffer 0.3.3. Copyright (C) 2003-2005 Shay Green. GNU LGPL license.
|
||||
|
||||
#ifndef BLIP_SYNTH_H
|
||||
#define BLIP_SYNTH_H
|
||||
|
||||
#ifndef BLIP_BUFFER_H
|
||||
#include "Blip_Buffer.h"
|
||||
#endif
|
||||
|
||||
// Quality level. Higher levels are slower, and worse in a few cases.
|
||||
// Use blip_good_quality as a starting point.
|
||||
const int blip_low_quality = 1;
|
||||
const int blip_med_quality = 2;
|
||||
const int blip_good_quality = 3;
|
||||
const int blip_high_quality = 4;
|
||||
|
||||
// Blip_Synth is a transition waveform synthesizer which adds band-limited
|
||||
// offsets (transitions) into a Blip_Buffer. For a simpler interface, use
|
||||
// Blip_Wave (below).
|
||||
//
|
||||
// Range specifies the greatest expected offset that will occur. For a
|
||||
// waveform that goes between +amp and -amp, range should be amp * 2 (half
|
||||
// that if it only goes between +amp and 0). When range is large, a higher
|
||||
// accuracy scheme is used; to force this even when range is small, pass
|
||||
// the negative of range (i.e. -range).
|
||||
template<int quality,int range>
|
||||
class Blip_Synth {
|
||||
BOOST_STATIC_ASSERT( 1 <= quality && quality <= 5 );
|
||||
BOOST_STATIC_ASSERT( -32768 <= range && range <= 32767 );
|
||||
enum {
|
||||
abs_range = (range < 0) ? -range : range,
|
||||
fine_mode = (range > 512 || range < 0),
|
||||
width = (quality < 5 ? quality * 4 : Blip_Buffer::widest_impulse_),
|
||||
res = 1 << blip_res_bits_,
|
||||
impulse_size = width / 2 * (fine_mode + 1),
|
||||
base_impulses_size = width / 2 * (res / 2 + 1),
|
||||
fine_bits = (fine_mode ? (abs_range <= 64 ? 2 : abs_range <= 128 ? 3 :
|
||||
abs_range <= 256 ? 4 : abs_range <= 512 ? 5 : abs_range <= 1024 ? 6 :
|
||||
abs_range <= 2048 ? 7 : 8) : 0)
|
||||
};
|
||||
blip_pair_t_ impulses [impulse_size * res * 2 + base_impulses_size];
|
||||
Blip_Impulse_ impulse;
|
||||
public:
|
||||
Blip_Synth() { impulse.init( impulses, width, res, fine_bits ); }
|
||||
|
||||
// Configure low-pass filter (see notes.txt). Not optimized for real-time control
|
||||
void treble_eq( const blip_eq_t& eq ) { impulse.treble_eq( eq ); }
|
||||
|
||||
// Set volume of a transition at amplitude 'range' by setting volume_unit
|
||||
// to v / range
|
||||
void volume( double v ) { impulse.volume_unit( v * (1.0 / abs_range) ); }
|
||||
|
||||
// Set base volume unit of transitions, where 1.0 is a full swing between the
|
||||
// positive and negative extremes. Not optimized for real-time control.
|
||||
void volume_unit( double unit ) { impulse.volume_unit( unit ); }
|
||||
|
||||
// Default Blip_Buffer used for output when none is specified for a given call
|
||||
Blip_Buffer* output() const { return impulse.buf; }
|
||||
void output( Blip_Buffer* b ) { impulse.buf = b; }
|
||||
|
||||
// Add an amplitude offset (transition) with an amplitude of delta * volume_unit
|
||||
// into the specified buffer (default buffer if none specified) at the
|
||||
// specified source time. Amplitude can be positive or negative. To increase
|
||||
// performance by inlining code at the call site, use offset_inline().
|
||||
void offset( blip_time_t, int delta, Blip_Buffer* ) const;
|
||||
|
||||
void offset_resampled( blip_resampled_time_t, int delta, Blip_Buffer* ) const;
|
||||
void offset_resampled( blip_resampled_time_t t, int o ) const {
|
||||
offset_resampled( t, o, impulse.buf );
|
||||
}
|
||||
void offset( blip_time_t t, int delta ) const {
|
||||
offset( t, delta, impulse.buf );
|
||||
}
|
||||
void offset_inline( blip_time_t time, int delta, Blip_Buffer* buf ) const {
|
||||
offset_resampled( time * buf->factor_ + buf->offset_, delta, buf );
|
||||
}
|
||||
void offset_inline( blip_time_t time, int delta ) const {
|
||||
offset_inline( time, delta, impulse.buf );
|
||||
}
|
||||
};
|
||||
|
||||
// Blip_Wave is a synthesizer for adding a *single* waveform to a Blip_Buffer.
|
||||
// A wave is built from a series of delays and new amplitudes. This provides a
|
||||
// simpler interface than Blip_Synth.
|
||||
template<int quality,int range>
|
||||
class Blip_Wave {
|
||||
Blip_Synth<quality,range> synth;
|
||||
blip_time_t time_;
|
||||
int last_amp;
|
||||
public:
|
||||
// Start wave at time 0 and amplitude 0
|
||||
Blip_Wave() : time_( 0 ), last_amp( 0 ) { }
|
||||
|
||||
// See Blip_Synth for description
|
||||
void volume( double v ) { synth.volume( v ); }
|
||||
void volume_unit( double v ) { synth.volume_unit( v ); }
|
||||
void treble_eq( const blip_eq_t& eq){ synth.treble_eq( eq ); }
|
||||
Blip_Buffer* output() const { return synth.output(); }
|
||||
void output( Blip_Buffer* b ) { synth.output( b ); if ( !b ) time_ = last_amp = 0; }
|
||||
|
||||
// Current time in frame
|
||||
blip_time_t time() const { return time_; }
|
||||
void time( blip_time_t t ) { time_ = t; }
|
||||
|
||||
// Current amplitude of wave
|
||||
int amplitude() const { return last_amp; }
|
||||
void amplitude( int );
|
||||
|
||||
// Move forward by 't' time units
|
||||
void delay( blip_time_t t ) { time_ += t; }
|
||||
|
||||
// End time frame of specified duration. Localize time to new frame.
|
||||
void end_frame( blip_time_t duration ) {
|
||||
assert(( "Blip_Wave::end_frame(): Wave hadn't yet been run for entire frame",
|
||||
duration <= time_ ));
|
||||
time_ -= duration;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// End of public interface
|
||||
|
||||
template<int quality,int range>
|
||||
void Blip_Wave<quality,range>::amplitude( int amp ) {
|
||||
int delta = amp - last_amp;
|
||||
last_amp = amp;
|
||||
synth.offset_inline( time_, delta );
|
||||
}
|
||||
|
||||
template<int quality,int range>
|
||||
inline void Blip_Synth<quality,range>::offset_resampled( blip_resampled_time_t time,
|
||||
int delta, Blip_Buffer* blip_buf ) const
|
||||
{
|
||||
typedef blip_pair_t_ pair_t;
|
||||
|
||||
unsigned sample_index = (time >> BLIP_BUFFER_ACCURACY) & ~1;
|
||||
assert(( "Blip_Synth/Blip_wave: Went past end of buffer",
|
||||
sample_index < blip_buf->buffer_size_ ));
|
||||
enum { const_offset = Blip_Buffer::widest_impulse_ / 2 - width / 2 };
|
||||
pair_t* buf = (pair_t*) &blip_buf->buffer_ [const_offset + sample_index];
|
||||
|
||||
enum { shift = BLIP_BUFFER_ACCURACY - blip_res_bits_ };
|
||||
enum { mask = res * 2 - 1 };
|
||||
const pair_t* imp = &impulses [((time >> shift) & mask) * impulse_size];
|
||||
|
||||
pair_t offset = impulse.offset * delta;
|
||||
|
||||
if ( !fine_bits )
|
||||
{
|
||||
// normal mode
|
||||
for ( int n = width / 4; n; --n )
|
||||
{
|
||||
pair_t t0 = buf [0] - offset;
|
||||
pair_t t1 = buf [1] - offset;
|
||||
|
||||
t0 += imp [0] * delta;
|
||||
t1 += imp [1] * delta;
|
||||
imp += 2;
|
||||
|
||||
buf [0] = t0;
|
||||
buf [1] = t1;
|
||||
buf += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// fine mode
|
||||
enum { sub_range = 1 << fine_bits };
|
||||
delta += sub_range / 2;
|
||||
int delta2 = (delta & (sub_range - 1)) - sub_range / 2;
|
||||
delta >>= fine_bits;
|
||||
|
||||
for ( int n = width / 4; n; --n )
|
||||
{
|
||||
pair_t t0 = buf [0] - offset;
|
||||
pair_t t1 = buf [1] - offset;
|
||||
|
||||
t0 += imp [0] * delta2;
|
||||
t0 += imp [1] * delta;
|
||||
|
||||
t1 += imp [2] * delta2;
|
||||
t1 += imp [3] * delta;
|
||||
|
||||
imp += 4;
|
||||
|
||||
buf [0] = t0;
|
||||
buf [1] = t1;
|
||||
buf += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<int quality,int range>
|
||||
void Blip_Synth<quality,range>::offset( blip_time_t time, int delta, Blip_Buffer* buf ) const {
|
||||
offset_resampled( time * buf->factor_ + buf->offset_, delta, buf );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
504
Gb_Apu/COPYING
504
Gb_Apu/COPYING
|
@ -1,504 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
|
@ -1,318 +0,0 @@
|
|||
|
||||
// Gb_Snd_Emu 0.1.4. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module 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
|
||||
module 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 module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
|
||||
int const vol_reg = 0xFF24;
|
||||
int const status_reg = 0xFF26;
|
||||
|
||||
Gb_Apu::Gb_Apu()
|
||||
{
|
||||
square1.synth = &square_synth;
|
||||
square2.synth = &square_synth;
|
||||
wave.synth = &other_synth;
|
||||
noise.synth = &other_synth;
|
||||
|
||||
oscs [0] = &square1;
|
||||
oscs [1] = &square2;
|
||||
oscs [2] = &wave;
|
||||
oscs [3] = &noise;
|
||||
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
osc.regs = ®s [i * 5];
|
||||
osc.output = NULL;
|
||||
osc.outputs [0] = NULL;
|
||||
osc.outputs [1] = NULL;
|
||||
osc.outputs [2] = NULL;
|
||||
osc.outputs [3] = NULL;
|
||||
}
|
||||
|
||||
volume( 1.0 );
|
||||
reset();
|
||||
}
|
||||
|
||||
Gb_Apu::~Gb_Apu()
|
||||
{
|
||||
}
|
||||
|
||||
void Gb_Apu::treble_eq( const blip_eq_t& eq )
|
||||
{
|
||||
square_synth.treble_eq( eq );
|
||||
other_synth.treble_eq( eq );
|
||||
}
|
||||
|
||||
void Gb_Apu::osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
|
||||
{
|
||||
require( (unsigned) index < osc_count );
|
||||
require( (center && left && right) || (!center && !left && !right) );
|
||||
Gb_Osc& osc = *oscs [index];
|
||||
osc.outputs [1] = right;
|
||||
osc.outputs [2] = left;
|
||||
osc.outputs [3] = center;
|
||||
osc.output = osc.outputs [osc.output_select];
|
||||
}
|
||||
|
||||
void Gb_Apu::output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right )
|
||||
{
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
osc_output( i, center, left, right );
|
||||
}
|
||||
|
||||
void Gb_Apu::update_volume()
|
||||
{
|
||||
// to do: doesn't handle differing left/right global volume
|
||||
int data = regs [vol_reg - start_addr];
|
||||
double vol = (max( data & 7, data >> 4 & 7 ) + 1) * volume_unit;
|
||||
square_synth.volume( vol );
|
||||
other_synth.volume( vol );
|
||||
}
|
||||
|
||||
static unsigned char const powerup_regs [0x30] = {
|
||||
0x80,0x3F,0x00,0xFF,0xBF, // square 1
|
||||
0xFF,0x3F,0x00,0xFF,0xBF, // square 2
|
||||
0x7F,0xFF,0x9F,0xFF,0xBF, // wave
|
||||
0xFF,0xFF,0x00,0x00,0xBF, // noise
|
||||
0x00, // left/right enables
|
||||
0x77, // master volume
|
||||
0x80, // power
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0x84,0x40,0x43,0xAA,0x2D,0x78,0x92,0x3C, // wave table
|
||||
0x60,0x59,0x59,0xB0,0x34,0xB8,0x2E,0xDA
|
||||
};
|
||||
|
||||
void Gb_Apu::reset(bool igba)
|
||||
{
|
||||
next_frame_time = 0;
|
||||
last_time = 0;
|
||||
frame_count = 0;
|
||||
stereo_found = false;
|
||||
|
||||
square1.reset();
|
||||
square2.reset();
|
||||
wave.reset(gba = igba);
|
||||
noise.reset();
|
||||
noise.bits = 1;
|
||||
wave.wave_pos = 0;
|
||||
|
||||
// avoid click at beginning
|
||||
regs [vol_reg - start_addr] = 0x77;
|
||||
update_volume();
|
||||
|
||||
regs [status_reg - start_addr] = 0x01; // force power
|
||||
write_register( 0, status_reg, 0x00 );
|
||||
}
|
||||
|
||||
// to do: remove
|
||||
//static unsigned long abs_time;
|
||||
|
||||
void Gb_Apu::run_until( gb_time_t end_time )
|
||||
{
|
||||
require( end_time >= last_time ); // end_time must not be before previous time
|
||||
if ( end_time == last_time )
|
||||
return;
|
||||
|
||||
while ( true )
|
||||
{
|
||||
gb_time_t time = next_frame_time;
|
||||
if ( time > end_time )
|
||||
time = end_time;
|
||||
|
||||
// run oscillators
|
||||
for ( int i = 0; i < osc_count; ++i )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
if ( osc.output )
|
||||
{
|
||||
int playing = false;
|
||||
if ( osc.enabled && osc.volume &&
|
||||
(!(osc.regs [4] & osc.len_enabled_mask) || osc.length) )
|
||||
playing = -1;
|
||||
if ( osc.output != osc.outputs [3] )
|
||||
stereo_found = true;
|
||||
switch ( i )
|
||||
{
|
||||
case 0: square1.run( last_time, time, playing ); break;
|
||||
case 1: square2.run( last_time, time, playing ); break;
|
||||
case 2: wave .run( last_time, time, playing ); break;
|
||||
case 3: noise .run( last_time, time, playing ); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
last_time = time;
|
||||
|
||||
if ( time == end_time )
|
||||
break;
|
||||
|
||||
next_frame_time += 4194304 / 256; // 256 Hz
|
||||
|
||||
// 256 Hz actions
|
||||
square1.clock_length();
|
||||
square2.clock_length();
|
||||
wave.clock_length();
|
||||
noise.clock_length();
|
||||
|
||||
frame_count = (frame_count + 1) & 3;
|
||||
if ( frame_count == 0 )
|
||||
{
|
||||
// 64 Hz actions
|
||||
square1.clock_envelope();
|
||||
square2.clock_envelope();
|
||||
noise.clock_envelope();
|
||||
}
|
||||
|
||||
if ( frame_count & 1 )
|
||||
square1.clock_sweep(); // 128 Hz action
|
||||
}
|
||||
}
|
||||
|
||||
bool Gb_Apu::end_frame( gb_time_t end_time )
|
||||
{
|
||||
if ( end_time > last_time )
|
||||
run_until( end_time );
|
||||
|
||||
//abs_time += end_time;
|
||||
|
||||
assert( next_frame_time >= end_time );
|
||||
next_frame_time -= end_time;
|
||||
|
||||
assert( last_time >= end_time );
|
||||
last_time -= end_time;
|
||||
|
||||
bool result = stereo_found;
|
||||
stereo_found = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Gb_Apu::write_register( gb_time_t time, gb_addr_t addr, int data )
|
||||
{
|
||||
require( (unsigned) data < 0x100 );
|
||||
|
||||
int reg = addr - start_addr;
|
||||
if ( (unsigned) reg >= register_count )
|
||||
return;
|
||||
|
||||
run_until( time );
|
||||
|
||||
int old_reg = regs [reg];
|
||||
regs [reg] = data;
|
||||
|
||||
if ( addr < vol_reg )
|
||||
{
|
||||
write_osc( reg / 5, reg, data );
|
||||
}
|
||||
else if ( addr == vol_reg && data != old_reg ) // global volume
|
||||
{
|
||||
// return all oscs to 0
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
int amp = osc.last_amp;
|
||||
osc.last_amp = 0;
|
||||
if ( amp && osc.enabled && osc.output )
|
||||
other_synth.offset( time, -amp, osc.output );
|
||||
}
|
||||
|
||||
if ( wave.outputs [3] )
|
||||
other_synth.offset( time, 30, wave.outputs [3] );
|
||||
|
||||
update_volume();
|
||||
|
||||
if ( wave.outputs [3] )
|
||||
other_synth.offset( time, -30, wave.outputs [3] );
|
||||
|
||||
// oscs will update with new amplitude when next run
|
||||
}
|
||||
else if ( addr == 0xFF25 || addr == status_reg )
|
||||
{
|
||||
int mask = (regs [status_reg - start_addr] & 0x80) ? ~0 : 0;
|
||||
int flags = regs [0xFF25 - start_addr] & mask;
|
||||
|
||||
// left/right assignments
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
{
|
||||
Gb_Osc& osc = *oscs [i];
|
||||
osc.enabled &= mask;
|
||||
int bits = flags >> i;
|
||||
Blip_Buffer* old_output = osc.output;
|
||||
osc.output_select = (bits >> 3 & 2) | (bits & 1);
|
||||
osc.output = osc.outputs [osc.output_select];
|
||||
if ( osc.output != old_output )
|
||||
{
|
||||
int amp = osc.last_amp;
|
||||
osc.last_amp = 0;
|
||||
if ( amp && old_output )
|
||||
other_synth.offset( time, -amp, old_output );
|
||||
}
|
||||
}
|
||||
|
||||
if ( addr == status_reg && data != old_reg )
|
||||
{
|
||||
if ( !(data & 0x80) )
|
||||
{
|
||||
for ( int i = 0; i < (int) sizeof powerup_regs; i++ )
|
||||
{
|
||||
if ( i != status_reg - start_addr )
|
||||
write_register( time, i + start_addr, powerup_regs [i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//dprintf( "APU powered on\n" );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( addr >= 0xFF30 )
|
||||
{
|
||||
int bank;
|
||||
if (gba) bank = (wave.wave_bank ^ 0x20);
|
||||
else bank = 0;
|
||||
int index = (addr & 0x0F) * 2 + bank;
|
||||
wave.wave [index] = data >> 4;
|
||||
wave.wave [index + 1] = data & 0x0F;
|
||||
}
|
||||
}
|
||||
|
||||
int Gb_Apu::read_register( gb_time_t time, gb_addr_t addr )
|
||||
{
|
||||
run_until( time );
|
||||
|
||||
int index = addr - start_addr;
|
||||
require( (unsigned) index < register_count );
|
||||
int data = regs [index];
|
||||
|
||||
if ( addr == status_reg )
|
||||
{
|
||||
data = (data & 0x80) | 0x70;
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
{
|
||||
const Gb_Osc& osc = *oscs [i];
|
||||
if ( osc.enabled && (osc.length || !(osc.regs [4] & osc.len_enabled_mask)) )
|
||||
data |= 1 << i;
|
||||
}
|
||||
} else if ( gba && addr >= 0xff30 ) {
|
||||
int bank = (wave.wave_bank ^ 0x20);
|
||||
int index = (addr & 0x0f) * 2;
|
||||
data = wave.wave [bank + index] << 4;
|
||||
data |= wave.wave [bank + index + 1];
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
|
||||
// Nintendo Game Boy PAPU sound chip emulator
|
||||
|
||||
// Gb_Snd_Emu 0.1.4
|
||||
|
||||
#ifndef GB_APU_H
|
||||
#define GB_APU_H
|
||||
|
||||
typedef long gb_time_t; // clock cycle count
|
||||
typedef unsigned gb_addr_t; // 16-bit address
|
||||
|
||||
#include "Gb_Oscs.h"
|
||||
|
||||
class Gb_Apu {
|
||||
public:
|
||||
|
||||
// Set overall volume of all oscillators, where 1.0 is full volume
|
||||
void volume( double );
|
||||
|
||||
// Set treble equalization
|
||||
void treble_eq( const blip_eq_t& );
|
||||
|
||||
// Outputs can be assigned to a single buffer for mono output, or to three
|
||||
// buffers for stereo output (using Stereo_Buffer to do the mixing).
|
||||
|
||||
// Assign all oscillator outputs to specified buffer(s). If buffer
|
||||
// is NULL, silences all oscillators.
|
||||
void output( Blip_Buffer* mono );
|
||||
void output( Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
|
||||
|
||||
// Assign single oscillator output to buffer(s). Valid indicies are 0 to 3,
|
||||
// which refer to Square 1, Square 2, Wave, and Noise. If buffer is NULL,
|
||||
// silences oscillator.
|
||||
enum { osc_count = 4 };
|
||||
void osc_output( int index, Blip_Buffer* mono );
|
||||
void osc_output( int index, Blip_Buffer* center, Blip_Buffer* left, Blip_Buffer* right );
|
||||
|
||||
// Reset oscillators and internal state
|
||||
void reset(bool gba = false);
|
||||
|
||||
// Reads and writes at addr must satisfy start_addr <= addr <= end_addr
|
||||
enum { start_addr = 0xFF10 };
|
||||
enum { end_addr = 0xFF3f };
|
||||
enum { register_count = end_addr - start_addr + 1 };
|
||||
|
||||
// Write 'data' to address at specified time
|
||||
void write_register( gb_time_t, gb_addr_t, int data );
|
||||
|
||||
// Read from address at specified time
|
||||
int read_register( gb_time_t, gb_addr_t );
|
||||
|
||||
// Run all oscillators up to specified time, end current time frame, then
|
||||
// start a new frame at time 0. Returns true if any oscillators added
|
||||
// sound to one of the left/right buffers, false if they only added
|
||||
// to the center buffer.
|
||||
bool end_frame( gb_time_t );
|
||||
|
||||
public:
|
||||
Gb_Apu();
|
||||
~Gb_Apu();
|
||||
private:
|
||||
// noncopyable
|
||||
Gb_Apu( const Gb_Apu& );
|
||||
Gb_Apu& operator = ( const Gb_Apu& );
|
||||
|
||||
Gb_Osc* oscs [osc_count];
|
||||
gb_time_t next_frame_time;
|
||||
gb_time_t last_time;
|
||||
double volume_unit;
|
||||
int frame_count;
|
||||
bool stereo_found;
|
||||
|
||||
Gb_Square square1;
|
||||
Gb_Square square2;
|
||||
Gb_Wave wave;
|
||||
Gb_Noise noise;
|
||||
BOOST::uint8_t regs [register_count];
|
||||
Gb_Square::Synth square_synth; // used by squares
|
||||
Gb_Wave::Synth other_synth; // used by wave and noise
|
||||
|
||||
bool gba; // enable GBA extensions to wave channel
|
||||
|
||||
void update_volume();
|
||||
void run_until( gb_time_t );
|
||||
void write_osc( int index, int reg, int data );
|
||||
};
|
||||
|
||||
inline void Gb_Apu::output( Blip_Buffer* b ) { output( b, b, b ); }
|
||||
|
||||
inline void Gb_Apu::osc_output( int i, Blip_Buffer* b ) { osc_output( i, b, b, b ); }
|
||||
|
||||
inline void Gb_Apu::volume( double vol )
|
||||
{
|
||||
volume_unit = 0.60 / osc_count / 15 /*steps*/ / 2 /*?*/ / 8 /*master vol range*/ * vol;
|
||||
update_volume();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,360 +0,0 @@
|
|||
|
||||
// Gb_Snd_Emu 0.1.4. http://www.slack.net/~ant/
|
||||
|
||||
#include "Gb_Apu.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module 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
|
||||
module 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 module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
|
||||
// Gb_Osc
|
||||
|
||||
void Gb_Osc::reset()
|
||||
{
|
||||
delay = 0;
|
||||
last_amp = 0;
|
||||
length = 0;
|
||||
output_select = 3;
|
||||
output = outputs [output_select];
|
||||
}
|
||||
|
||||
void Gb_Osc::clock_length()
|
||||
{
|
||||
if ( (regs [4] & len_enabled_mask) && length )
|
||||
length--;
|
||||
}
|
||||
|
||||
// Gb_Env
|
||||
|
||||
void Gb_Env::clock_envelope()
|
||||
{
|
||||
if ( env_delay && !--env_delay )
|
||||
{
|
||||
env_delay = regs [2] & 7;
|
||||
int v = volume - 1 + (regs [2] >> 2 & 2);
|
||||
if ( (unsigned) v < 15 )
|
||||
volume = v;
|
||||
}
|
||||
}
|
||||
|
||||
bool Gb_Env::write_register( int reg, int data )
|
||||
{
|
||||
switch ( reg )
|
||||
{
|
||||
case 1:
|
||||
length = 64 - (regs [1] & 0x3f);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if ( !(data >> 4) )
|
||||
enabled = false;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if ( data & trigger )
|
||||
{
|
||||
env_delay = regs [2] & 7;
|
||||
volume = regs [2] >> 4;
|
||||
enabled = true;
|
||||
if ( length == 0 )
|
||||
length = 64;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gb_Square
|
||||
|
||||
void Gb_Square::reset()
|
||||
{
|
||||
phase = 0;
|
||||
sweep_freq = 0;
|
||||
sweep_delay = 0;
|
||||
Gb_Env::reset();
|
||||
}
|
||||
|
||||
void Gb_Square::clock_sweep()
|
||||
{
|
||||
int sweep_period = (regs [0] & period_mask) >> 4;
|
||||
if ( sweep_period && sweep_delay && !--sweep_delay )
|
||||
{
|
||||
sweep_delay = sweep_period;
|
||||
regs [3] = sweep_freq & 0xFF;
|
||||
regs [4] = (regs [4] & ~0x07) | (sweep_freq >> 8 & 0x07);
|
||||
|
||||
int offset = sweep_freq >> (regs [0] & shift_mask);
|
||||
if ( regs [0] & 0x08 )
|
||||
offset = -offset;
|
||||
sweep_freq += offset;
|
||||
|
||||
if ( sweep_freq < 0 )
|
||||
{
|
||||
sweep_freq = 0;
|
||||
}
|
||||
else if ( sweep_freq >= 2048 )
|
||||
{
|
||||
sweep_delay = 0; // don't modify channel frequency any further
|
||||
sweep_freq = 2048; // silence sound immediately
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Square::run( gb_time_t time, gb_time_t end_time, int playing )
|
||||
{
|
||||
if ( sweep_freq == 2048 )
|
||||
playing = false;
|
||||
|
||||
static unsigned char const table [4] = { 1, 2, 4, 6 };
|
||||
int const duty = table [regs [1] >> 6];
|
||||
int amp = volume & playing;
|
||||
if ( phase >= duty )
|
||||
amp = -amp;
|
||||
|
||||
int frequency = this->frequency();
|
||||
if ( unsigned (frequency - 1) > 2040 ) // frequency < 1 || frequency > 2041
|
||||
{
|
||||
// really high frequency results in DC at half volume
|
||||
amp = volume >> 1;
|
||||
playing = false;
|
||||
}
|
||||
|
||||
int delta = amp - last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
last_amp = amp;
|
||||
synth->offset( time, delta, output );
|
||||
}
|
||||
|
||||
time += delay;
|
||||
if ( !playing )
|
||||
time = end_time;
|
||||
|
||||
if ( time < end_time )
|
||||
{
|
||||
int const period = (2048 - frequency) * 4;
|
||||
Blip_Buffer* const output = this->output;
|
||||
int phase = this->phase;
|
||||
int delta = amp * 2;
|
||||
do
|
||||
{
|
||||
phase = (phase + 1) & 7;
|
||||
if ( phase == 0 || phase == duty )
|
||||
{
|
||||
delta = -delta;
|
||||
synth->offset_inline( time, delta, output );
|
||||
}
|
||||
time += period;
|
||||
}
|
||||
while ( time < end_time );
|
||||
|
||||
this->phase = phase;
|
||||
last_amp = delta >> 1;
|
||||
}
|
||||
delay = time - end_time;
|
||||
}
|
||||
|
||||
// Gb_Noise
|
||||
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
|
||||
void Gb_Noise::run( gb_time_t time, gb_time_t end_time, int playing )
|
||||
{
|
||||
int amp = volume & playing;
|
||||
int tap = 13 - (regs [3] & 8);
|
||||
if ( bits >> tap & 2 )
|
||||
amp = -amp;
|
||||
|
||||
int delta = amp - last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
last_amp = amp;
|
||||
synth->offset( time, delta, output );
|
||||
}
|
||||
|
||||
time += delay;
|
||||
if ( !playing )
|
||||
time = end_time;
|
||||
|
||||
if ( time < end_time )
|
||||
{
|
||||
static unsigned char const table [8] = { 8, 16, 32, 48, 64, 80, 96, 112 };
|
||||
int period = table [regs [3] & 7] << (regs [3] >> 4);
|
||||
|
||||
// keep parallel resampled time to eliminate time conversion in the loop
|
||||
Blip_Buffer* const output = this->output;
|
||||
const blip_resampled_time_t resampled_period =
|
||||
output->resampled_duration( period );
|
||||
blip_resampled_time_t resampled_time = output->resampled_time( time );
|
||||
unsigned bits = this->bits;
|
||||
int delta = amp * 2;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned changed = (bits >> tap) + 1;
|
||||
time += period;
|
||||
bits <<= 1;
|
||||
if ( changed & 2 )
|
||||
{
|
||||
delta = -delta;
|
||||
bits |= 1;
|
||||
synth->offset_resampled( resampled_time, delta, output );
|
||||
}
|
||||
resampled_time += resampled_period;
|
||||
}
|
||||
while ( time < end_time );
|
||||
|
||||
this->bits = bits;
|
||||
last_amp = delta >> 1;
|
||||
}
|
||||
delay = time - end_time;
|
||||
}
|
||||
|
||||
// Gb_Wave
|
||||
|
||||
void Gb_Wave::reset(bool gba)
|
||||
{
|
||||
volume_forced = 0;
|
||||
wave_pos = 0;
|
||||
wave_mode = gba;
|
||||
wave_size = 32;
|
||||
wave_bank = 0;
|
||||
memset( wave, 0, sizeof wave );
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
inline void Gb_Wave::write_register( int reg, int data )
|
||||
{
|
||||
switch ( reg )
|
||||
{
|
||||
case 0:
|
||||
if ( !(data & 0x80) )
|
||||
enabled = false;
|
||||
if (wave_mode)
|
||||
{
|
||||
wave_bank = (data & 0x40) >> 1;
|
||||
wave_size = (data & 0x20) + 32;
|
||||
}
|
||||
if (wave_pos > wave_size) wave_pos %= wave_size;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
length = 256 - regs [1];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
volume = data >> 5 & 3;
|
||||
if (wave_mode) volume_forced = data & 0x80;
|
||||
if (volume_forced) volume = -1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if ( data & trigger & regs [0] )
|
||||
{
|
||||
wave_pos = 0;
|
||||
enabled = true;
|
||||
if ( length == 0 )
|
||||
length = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Gb_Wave::run( gb_time_t time, gb_time_t end_time, int playing )
|
||||
{
|
||||
int volume_shift = (volume - 1) & 7; // volume = 0 causes shift = 7
|
||||
int amp = (wave_size == 32) ? wave [wave_bank + wave_pos] : wave [wave_pos];
|
||||
if (volume_forced) amp = ((amp >> 1) + amp) >> 1;
|
||||
else amp >>= volume_shift;
|
||||
amp = (amp & playing) * 2;
|
||||
|
||||
int frequency = this->frequency();
|
||||
if ( unsigned (frequency - 1) > 2044 ) // frequency < 1 || frequency > 2045
|
||||
{
|
||||
if (volume_forced) amp = ((30 >> 1) + 30) >> 1;
|
||||
else amp = 30 >> volume_shift;
|
||||
amp &= playing;
|
||||
playing = false;
|
||||
}
|
||||
|
||||
int delta = amp - last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
last_amp = amp;
|
||||
synth->offset( time, delta, output );
|
||||
}
|
||||
|
||||
time += delay;
|
||||
if ( !playing )
|
||||
time = end_time;
|
||||
|
||||
if ( time < end_time )
|
||||
{
|
||||
Blip_Buffer* const output = this->output;
|
||||
int const period = (2048 - frequency) * 2;
|
||||
int wave_pos = (this->wave_pos + 1) & (wave_size - 1);
|
||||
|
||||
do
|
||||
{
|
||||
int amp = (wave_size == 32) ? wave [wave_bank + wave_pos] : wave [wave_pos];
|
||||
if (volume_forced) amp = ((amp >> 1) + amp) >> 1;
|
||||
else amp >>= volume_shift;
|
||||
amp *= 2;
|
||||
wave_pos = (wave_pos + 1) & (wave_size - 1);
|
||||
int delta = amp - last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
last_amp = amp;
|
||||
synth->offset_inline( time, delta, output );
|
||||
}
|
||||
time += period;
|
||||
}
|
||||
while ( time < end_time );
|
||||
|
||||
this->wave_pos = (wave_pos - 1) & (wave_size - 1);
|
||||
}
|
||||
delay = time - end_time;
|
||||
}
|
||||
|
||||
// Gb_Apu::write_osc
|
||||
|
||||
void Gb_Apu::write_osc( int index, int reg, int data )
|
||||
{
|
||||
reg -= index * 5;
|
||||
Gb_Square* sq = &square2;
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
sq = &square1;
|
||||
case 1:
|
||||
if ( sq->write_register( reg, data ) && index == 0 )
|
||||
{
|
||||
square1.sweep_freq = square1.frequency();
|
||||
if ( (regs [0] & sq->period_mask) && (regs [0] & sq->shift_mask) )
|
||||
{
|
||||
square1.sweep_delay = 1; // cause sweep to recalculate now
|
||||
square1.clock_sweep();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wave.write_register( reg, data );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if ( noise.write_register( reg, data ) )
|
||||
noise.bits = 0x7FFF;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
|
||||
// Private oscillators used by Gb_Apu
|
||||
|
||||
// Gb_Snd_Emu 0.1.4
|
||||
|
||||
#ifndef GB_OSCS_H
|
||||
#define GB_OSCS_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
struct Gb_Osc
|
||||
{
|
||||
enum { trigger = 0x80 };
|
||||
enum { len_enabled_mask = 0x40 };
|
||||
|
||||
Blip_Buffer* outputs [4]; // NULL, right, left, center
|
||||
Blip_Buffer* output;
|
||||
int output_select;
|
||||
BOOST::uint8_t* regs; // osc's 5 registers
|
||||
|
||||
int delay;
|
||||
int last_amp;
|
||||
int volume;
|
||||
int length;
|
||||
bool enabled;
|
||||
|
||||
void reset();
|
||||
void clock_length();
|
||||
int frequency() const { return (regs [4] & 7) * 0x100 + regs [3]; }
|
||||
};
|
||||
|
||||
struct Gb_Env : Gb_Osc
|
||||
{
|
||||
int env_delay;
|
||||
|
||||
void reset();
|
||||
void clock_envelope();
|
||||
bool write_register( int, int );
|
||||
};
|
||||
|
||||
struct Gb_Square : Gb_Env
|
||||
{
|
||||
enum { period_mask = 0x70 };
|
||||
enum { shift_mask = 0x07 };
|
||||
|
||||
typedef Blip_Synth<blip_good_quality,1> Synth;
|
||||
Synth const* synth;
|
||||
int sweep_delay;
|
||||
int sweep_freq;
|
||||
int phase;
|
||||
|
||||
void reset();
|
||||
void clock_sweep();
|
||||
void run( gb_time_t, gb_time_t, int playing );
|
||||
};
|
||||
|
||||
struct Gb_Noise : Gb_Env
|
||||
{
|
||||
typedef Blip_Synth<blip_med_quality,1> Synth;
|
||||
Synth const* synth;
|
||||
unsigned bits;
|
||||
|
||||
void run( gb_time_t, gb_time_t, int playing );
|
||||
};
|
||||
|
||||
struct Gb_Wave : Gb_Osc
|
||||
{
|
||||
typedef Blip_Synth<blip_med_quality,1> Synth;
|
||||
Synth const* synth;
|
||||
int volume_forced;
|
||||
int wave_pos;
|
||||
unsigned wave_mode;
|
||||
unsigned wave_size;
|
||||
unsigned wave_bank;
|
||||
BOOST::uint8_t wave [32 * 2];
|
||||
|
||||
void reset(bool gba = false);
|
||||
void write_register( int, int );
|
||||
void run( gb_time_t, gb_time_t, int playing );
|
||||
};
|
||||
|
||||
inline void Gb_Env::reset()
|
||||
{
|
||||
env_delay = 0;
|
||||
Gb_Osc::reset();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,215 +0,0 @@
|
|||
|
||||
// Blip_Buffer 0.4.0. http://www.slack.net/~ant/
|
||||
|
||||
#include "Multi_Buffer.h"
|
||||
|
||||
/* Copyright (C) 2003-2006 Shay Green. This module 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
|
||||
module 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 module; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include BLARGG_SOURCE_BEGIN
|
||||
|
||||
Multi_Buffer::Multi_Buffer( int spf ) : samples_per_frame_( spf )
|
||||
{
|
||||
length_ = 0;
|
||||
sample_rate_ = 0;
|
||||
channels_changed_count_ = 1;
|
||||
}
|
||||
|
||||
blargg_err_t Multi_Buffer::set_channel_count( int )
|
||||
{
|
||||
return blargg_success;
|
||||
}
|
||||
|
||||
Mono_Buffer::Mono_Buffer() : Multi_Buffer( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
Mono_Buffer::~Mono_Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
blargg_err_t Mono_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
BLARGG_RETURN_ERR( buf.set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( buf.sample_rate(), buf.length() );
|
||||
}
|
||||
|
||||
// Silent_Buffer
|
||||
|
||||
Silent_Buffer::Silent_Buffer() : Multi_Buffer( 1 ) // 0 channels would probably confuse
|
||||
{
|
||||
chan.left = NULL;
|
||||
chan.center = NULL;
|
||||
chan.right = NULL;
|
||||
}
|
||||
|
||||
// Mono_Buffer
|
||||
|
||||
Mono_Buffer::channel_t Mono_Buffer::channel( int )
|
||||
{
|
||||
channel_t ch;
|
||||
ch.center = &buf;
|
||||
ch.left = &buf;
|
||||
ch.right = &buf;
|
||||
return ch;
|
||||
}
|
||||
|
||||
void Mono_Buffer::end_frame( blip_time_t t, bool )
|
||||
{
|
||||
buf.end_frame( t );
|
||||
}
|
||||
|
||||
// Stereo_Buffer
|
||||
|
||||
Stereo_Buffer::Stereo_Buffer() : Multi_Buffer( 2 )
|
||||
{
|
||||
chan.center = &bufs [0];
|
||||
chan.left = &bufs [1];
|
||||
chan.right = &bufs [2];
|
||||
}
|
||||
|
||||
Stereo_Buffer::~Stereo_Buffer()
|
||||
{
|
||||
}
|
||||
|
||||
blargg_err_t Stereo_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
for ( int i = 0; i < buf_count; i++ )
|
||||
BLARGG_RETURN_ERR( bufs [i].set_sample_rate( rate, msec ) );
|
||||
return Multi_Buffer::set_sample_rate( bufs [0].sample_rate(), bufs [0].length() );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clock_rate( long rate )
|
||||
{
|
||||
for ( int i = 0; i < buf_count; i++ )
|
||||
bufs [i].clock_rate( rate );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::bass_freq( int bass )
|
||||
{
|
||||
for ( unsigned i = 0; i < buf_count; i++ )
|
||||
bufs [i].bass_freq( bass );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::clear()
|
||||
{
|
||||
stereo_added = false;
|
||||
was_stereo = false;
|
||||
for ( int i = 0; i < buf_count; i++ )
|
||||
bufs [i].clear();
|
||||
}
|
||||
|
||||
void Stereo_Buffer::end_frame( blip_time_t clock_count, bool stereo )
|
||||
{
|
||||
for ( unsigned i = 0; i < buf_count; i++ )
|
||||
bufs [i].end_frame( clock_count );
|
||||
|
||||
stereo_added |= stereo;
|
||||
}
|
||||
|
||||
long Stereo_Buffer::read_samples( blip_sample_t* out, long count )
|
||||
{
|
||||
require( !(count & 1) ); // count must be even
|
||||
count = (unsigned) count / 2;
|
||||
|
||||
long avail = bufs [0].samples_avail();
|
||||
if ( count > avail )
|
||||
count = avail;
|
||||
if ( count )
|
||||
{
|
||||
if ( stereo_added || was_stereo )
|
||||
{
|
||||
mix_stereo( out, count );
|
||||
|
||||
bufs [0].remove_samples( count );
|
||||
bufs [1].remove_samples( count );
|
||||
bufs [2].remove_samples( count );
|
||||
}
|
||||
else
|
||||
{
|
||||
mix_mono( out, count );
|
||||
|
||||
bufs [0].remove_samples( count );
|
||||
|
||||
bufs [1].remove_silence( count );
|
||||
bufs [2].remove_silence( count );
|
||||
}
|
||||
|
||||
// to do: this might miss opportunities for optimization
|
||||
if ( !bufs [0].samples_avail() ) {
|
||||
was_stereo = stereo_added;
|
||||
stereo_added = false;
|
||||
}
|
||||
}
|
||||
|
||||
return count * 2;
|
||||
}
|
||||
|
||||
#include BLARGG_ENABLE_OPTIMIZER
|
||||
|
||||
void Stereo_Buffer::mix_stereo( blip_sample_t* out, long count )
|
||||
{
|
||||
Blip_Reader left;
|
||||
Blip_Reader right;
|
||||
Blip_Reader center;
|
||||
|
||||
left.begin( bufs [1] );
|
||||
right.begin( bufs [2] );
|
||||
int bass = center.begin( bufs [0] );
|
||||
|
||||
while ( count-- )
|
||||
{
|
||||
int c = center.read();
|
||||
long l = c + left.read();
|
||||
long r = c + right.read();
|
||||
center.next( bass );
|
||||
out [0] = l;
|
||||
out [1] = r;
|
||||
out += 2;
|
||||
|
||||
if ( (BOOST::int16_t) l != l )
|
||||
out [-2] = 0x7FFF - (l >> 24);
|
||||
|
||||
left.next( bass );
|
||||
right.next( bass );
|
||||
|
||||
if ( (BOOST::int16_t) r != r )
|
||||
out [-1] = 0x7FFF - (r >> 24);
|
||||
}
|
||||
|
||||
center.end( bufs [0] );
|
||||
right.end( bufs [2] );
|
||||
left.end( bufs [1] );
|
||||
}
|
||||
|
||||
void Stereo_Buffer::mix_mono( blip_sample_t* out, long count )
|
||||
{
|
||||
Blip_Reader in;
|
||||
int bass = in.begin( bufs [0] );
|
||||
|
||||
while ( count-- )
|
||||
{
|
||||
long s = in.read();
|
||||
in.next( bass );
|
||||
out [0] = s;
|
||||
out [1] = s;
|
||||
out += 2;
|
||||
|
||||
if ( (BOOST::int16_t) s != s ) {
|
||||
s = 0x7FFF - (s >> 24);
|
||||
out [-2] = s;
|
||||
out [-1] = s;
|
||||
}
|
||||
}
|
||||
|
||||
in.end( bufs [0] );
|
||||
}
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
|
||||
// Multi-channel sound buffer interface, and basic mono and stereo buffers
|
||||
|
||||
// Blip_Buffer 0.4.0
|
||||
|
||||
#ifndef MULTI_BUFFER_H
|
||||
#define MULTI_BUFFER_H
|
||||
|
||||
#include "blargg_common.h"
|
||||
#include "Blip_Buffer.h"
|
||||
|
||||
// Interface to one or more Blip_Buffers mapped to one or more channels
|
||||
// consisting of left, center, and right buffers.
|
||||
class Multi_Buffer {
|
||||
public:
|
||||
Multi_Buffer( int samples_per_frame );
|
||||
virtual ~Multi_Buffer() { }
|
||||
|
||||
// Set the number of channels available
|
||||
virtual blargg_err_t set_channel_count( int );
|
||||
|
||||
// Get indexed channel, from 0 to channel count - 1
|
||||
struct channel_t {
|
||||
Blip_Buffer* center;
|
||||
Blip_Buffer* left;
|
||||
Blip_Buffer* right;
|
||||
};
|
||||
virtual channel_t channel( int index ) = 0;
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual blargg_err_t set_sample_rate( long rate, int msec = blip_default_length ) = 0;
|
||||
virtual void clock_rate( long ) = 0;
|
||||
virtual void bass_freq( int ) = 0;
|
||||
virtual void clear() = 0;
|
||||
long sample_rate() const;
|
||||
|
||||
// Length of buffer, in milliseconds
|
||||
int length() const;
|
||||
|
||||
// See Blip_Buffer.h. For optimal operation, pass false for 'added_stereo'
|
||||
// if nothing was added to the left and right buffers of any channel for
|
||||
// this time frame.
|
||||
virtual void end_frame( blip_time_t, bool added_stereo = true ) = 0;
|
||||
|
||||
// Number of samples per output frame (1 = mono, 2 = stereo)
|
||||
int samples_per_frame() const;
|
||||
|
||||
// Count of changes to channel configuration. Incremented whenever
|
||||
// a change is made to any of the Blip_Buffers for any channel.
|
||||
unsigned channels_changed_count() { return channels_changed_count_; }
|
||||
|
||||
// See Blip_Buffer.h
|
||||
virtual long read_samples( blip_sample_t*, long ) = 0;
|
||||
virtual long samples_avail() const = 0;
|
||||
|
||||
protected:
|
||||
void channels_changed() { channels_changed_count_++; }
|
||||
private:
|
||||
// noncopyable
|
||||
Multi_Buffer( const Multi_Buffer& );
|
||||
Multi_Buffer& operator = ( const Multi_Buffer& );
|
||||
|
||||
unsigned channels_changed_count_;
|
||||
long sample_rate_;
|
||||
int length_;
|
||||
int const samples_per_frame_;
|
||||
};
|
||||
|
||||
// Uses a single buffer and outputs mono samples.
|
||||
class Mono_Buffer : public Multi_Buffer {
|
||||
Blip_Buffer buf;
|
||||
public:
|
||||
Mono_Buffer();
|
||||
~Mono_Buffer();
|
||||
|
||||
// Buffer used for all channels
|
||||
Blip_Buffer* center() { return &buf; }
|
||||
|
||||
// See Multi_Buffer
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int );
|
||||
void end_frame( blip_time_t, bool unused = true );
|
||||
long samples_avail() const;
|
||||
long read_samples( blip_sample_t*, long );
|
||||
};
|
||||
|
||||
// Uses three buffers (one for center) and outputs stereo sample pairs.
|
||||
class Stereo_Buffer : public Multi_Buffer {
|
||||
public:
|
||||
Stereo_Buffer();
|
||||
~Stereo_Buffer();
|
||||
|
||||
// Buffers used for all channels
|
||||
Blip_Buffer* center() { return &bufs [0]; }
|
||||
Blip_Buffer* left() { return &bufs [1]; }
|
||||
Blip_Buffer* right() { return &bufs [2]; }
|
||||
|
||||
// See Multi_Buffer
|
||||
blargg_err_t set_sample_rate( long, int msec = blip_default_length );
|
||||
void clock_rate( long );
|
||||
void bass_freq( int );
|
||||
void clear();
|
||||
channel_t channel( int index );
|
||||
void end_frame( blip_time_t, bool added_stereo = true );
|
||||
|
||||
long samples_avail() const;
|
||||
long read_samples( blip_sample_t*, long );
|
||||
|
||||
private:
|
||||
enum { buf_count = 3 };
|
||||
Blip_Buffer bufs [buf_count];
|
||||
channel_t chan;
|
||||
bool stereo_added;
|
||||
bool was_stereo;
|
||||
|
||||
void mix_stereo( blip_sample_t*, long );
|
||||
void mix_mono( blip_sample_t*, long );
|
||||
};
|
||||
|
||||
// Silent_Buffer generates no samples, useful where no sound is wanted
|
||||
class Silent_Buffer : public Multi_Buffer {
|
||||
channel_t chan;
|
||||
public:
|
||||
Silent_Buffer();
|
||||
|
||||
blargg_err_t set_sample_rate( long rate, int msec = blip_default_length );
|
||||
void clock_rate( long ) { }
|
||||
void bass_freq( int ) { }
|
||||
void clear() { }
|
||||
channel_t channel( int ) { return chan; }
|
||||
void end_frame( blip_time_t, bool unused = true ) { }
|
||||
long samples_avail() const { return 0; }
|
||||
long read_samples( blip_sample_t*, long ) { return 0; }
|
||||
};
|
||||
|
||||
|
||||
// End of public interface
|
||||
|
||||
inline blargg_err_t Multi_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
sample_rate_ = rate;
|
||||
length_ = msec;
|
||||
return blargg_success;
|
||||
}
|
||||
|
||||
inline blargg_err_t Silent_Buffer::set_sample_rate( long rate, int msec )
|
||||
{
|
||||
return Multi_Buffer::set_sample_rate( rate, msec );
|
||||
}
|
||||
|
||||
inline int Multi_Buffer::samples_per_frame() const { return samples_per_frame_; }
|
||||
|
||||
inline long Stereo_Buffer::samples_avail() const { return bufs [0].samples_avail() * 2; }
|
||||
|
||||
inline Stereo_Buffer::channel_t Stereo_Buffer::channel( int ) { return chan; }
|
||||
|
||||
inline long Multi_Buffer::sample_rate() const { return sample_rate_; }
|
||||
|
||||
inline int Multi_Buffer::length() const { return length_; }
|
||||
|
||||
inline void Mono_Buffer::clock_rate( long rate ) { buf.clock_rate( rate ); }
|
||||
|
||||
inline void Mono_Buffer::clear() { buf.clear(); }
|
||||
|
||||
inline void Mono_Buffer::bass_freq( int freq ) { buf.bass_freq( freq ); }
|
||||
|
||||
inline long Mono_Buffer::read_samples( blip_sample_t* p, long s ) { return buf.read_samples( p, s ); }
|
||||
|
||||
inline long Mono_Buffer::samples_avail() const { return buf.samples_avail(); }
|
||||
|
||||
#endif
|
||||
|
|
@ -1,242 +0,0 @@
|
|||
|
||||
// Sets up common environment for Shay Green's libraries.
|
||||
//
|
||||
// To change configuration options, modify blargg_config.h, not this file.
|
||||
|
||||
#ifndef BLARGG_COMMON_H
|
||||
#define BLARGG_COMMON_H
|
||||
|
||||
// HAVE_CONFIG_H: If defined, include user's "config.h" first (which *can*
|
||||
// re-include blargg_common.h if it needs to)
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#undef BLARGG_COMMON_H
|
||||
#include "config.h"
|
||||
#define BLARGG_COMMON_H
|
||||
#endif
|
||||
|
||||
// BLARGG_NONPORTABLE: If defined to 1, platform-specific (and possibly non-portable)
|
||||
// optimizations are used. Defaults to off. Report any problems that occur only when
|
||||
// this is enabled.
|
||||
#ifndef BLARGG_NONPORTABLE
|
||||
#define BLARGG_NONPORTABLE 0
|
||||
#endif
|
||||
|
||||
// BLARGG_BIG_ENDIAN, BLARGG_LITTLE_ENDIAN: Determined automatically, otherwise only
|
||||
// one must be #defined to 1. Only needed if something actually depends on byte order.
|
||||
#if !defined (BLARGG_BIG_ENDIAN) && !defined (BLARGG_LITTLE_ENDIAN)
|
||||
#if defined (MSB_FIRST) || defined (__powerc) || defined (macintosh) || \
|
||||
defined (WORDS_BIGENDIAN) || defined (__BIG_ENDIAN__)
|
||||
#define BLARGG_BIG_ENDIAN 1
|
||||
#else
|
||||
#define BLARGG_LITTLE_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Determine compiler's language support
|
||||
|
||||
// Metrowerks CodeWarrior
|
||||
#if defined (__MWERKS__)
|
||||
#define BLARGG_COMPILER_HAS_NAMESPACE 1
|
||||
#if !__option(bool)
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
#define STATIC_CAST(T,expr) static_cast< T > (expr)
|
||||
|
||||
// Microsoft Visual C++
|
||||
#elif defined (_MSC_VER)
|
||||
#if _MSC_VER < 1100
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
|
||||
// GNU C++
|
||||
#elif defined (__GNUC__)
|
||||
#if __GNUC__ > 2
|
||||
#define BLARGG_COMPILER_HAS_NAMESPACE 1
|
||||
#endif
|
||||
|
||||
// Mingw
|
||||
#elif defined (__MINGW32__)
|
||||
// empty
|
||||
|
||||
// Pre-ISO C++ compiler
|
||||
#elif __cplusplus < 199711
|
||||
#ifndef BLARGG_COMPILER_HAS_BOOL
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* BLARGG_COMPILER_HAS_BOOL: If 0, provides bool support for old compilers.
|
||||
If errors occur here, add the following line to your config.h file:
|
||||
#define BLARGG_COMPILER_HAS_BOOL 0
|
||||
*/
|
||||
#if defined (BLARGG_COMPILER_HAS_BOOL) && !BLARGG_COMPILER_HAS_BOOL
|
||||
typedef int bool;
|
||||
const bool true = 1;
|
||||
const bool false = 0;
|
||||
#endif
|
||||
|
||||
// BLARGG_USE_NAMESPACE: If 1, use <cxxx> headers rather than <xxxx.h>
|
||||
#if BLARGG_USE_NAMESPACE || (!defined (BLARGG_USE_NAMESPACE) && BLARGG_COMPILER_HAS_NAMESPACE)
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#define STD std
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#define STD
|
||||
#endif
|
||||
|
||||
// BLARGG_NEW is used in place of 'new' to create objects. By default, plain new is used.
|
||||
// To prevent an exception if out of memory, #define BLARGG_NEW new (std::nothrow)
|
||||
#ifndef BLARGG_NEW
|
||||
#define BLARGG_NEW new
|
||||
#endif
|
||||
|
||||
// BOOST::int8_t etc.
|
||||
|
||||
// HAVE_STDINT_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#define BOOST
|
||||
|
||||
// HAVE_INTTYPES_H: If defined, use <stdint.h> for int8_t etc.
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#define BOOST
|
||||
|
||||
#else
|
||||
struct BOOST
|
||||
{
|
||||
#if UCHAR_MAX == 0xFF && SCHAR_MAX == 0x7F
|
||||
typedef signed char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
#else
|
||||
// No suitable 8-bit type available
|
||||
typedef struct see_blargg_common_h int8_t;
|
||||
typedef struct see_blargg_common_h uint8_t;
|
||||
#endif
|
||||
|
||||
#if USHRT_MAX == 0xFFFF
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
#else
|
||||
// No suitable 16-bit type available
|
||||
typedef struct see_blargg_common_h int16_t;
|
||||
typedef struct see_blargg_common_h uint16_t;
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
// No suitable 32-bit type available
|
||||
typedef struct see_blargg_common_h int32_t;
|
||||
typedef struct see_blargg_common_h uint32_t;
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
// BLARGG_SOURCE_BEGIN: Library sources #include this after other #includes.
|
||||
#ifndef BLARGG_SOURCE_BEGIN
|
||||
#define BLARGG_SOURCE_BEGIN "blargg_source.h"
|
||||
#endif
|
||||
|
||||
// BLARGG_ENABLE_OPTIMIZER: Library sources #include this for speed-critical code
|
||||
#ifndef BLARGG_ENABLE_OPTIMIZER
|
||||
#define BLARGG_ENABLE_OPTIMIZER "blargg_common.h"
|
||||
#endif
|
||||
|
||||
// BLARGG_CPU_*: Used to select between some optimizations
|
||||
#if !defined (BLARGG_CPU_POWERPC) && !defined (BLARGG_CPU_X86)
|
||||
#if defined (__powerc)
|
||||
#define BLARGG_CPU_POWERPC 1
|
||||
#elif defined (_MSC_VER) && defined (_M_IX86)
|
||||
#define BLARGG_CPU_X86 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// BOOST_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
|
||||
#ifndef BOOST_STATIC_ASSERT
|
||||
#ifdef _MSC_VER
|
||||
// MSVC6 (_MSC_VER < 1300) fails for use of __LINE__ when /Zl is specified
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / ((expr) ? 1 : 0) - 1] )
|
||||
#else
|
||||
// Some other compilers fail when declaring same function multiple times in class,
|
||||
// so differentiate them by line
|
||||
#define BOOST_STATIC_ASSERT( expr ) \
|
||||
void blargg_failed_( int (*arg) [2 / ((expr) ? 1 : 0) - 1] [__LINE__] )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// STATIC_CAST(T,expr): Used in place of static_cast<T> (expr)
|
||||
#ifndef STATIC_CAST
|
||||
#define STATIC_CAST(T,expr) ((T) (expr))
|
||||
#endif
|
||||
|
||||
// blargg_err_t (NULL on success, otherwise error string)
|
||||
#ifndef blargg_err_t
|
||||
typedef const char* blargg_err_t;
|
||||
#endif
|
||||
const char* const blargg_success = 0;
|
||||
|
||||
// blargg_vector: Simple array that does *not* work for types with a constructor (non-POD).
|
||||
template<class T>
|
||||
class blargg_vector {
|
||||
T* begin_;
|
||||
STD::size_t size_;
|
||||
public:
|
||||
blargg_vector() : begin_( 0 ), size_( 0 ) { }
|
||||
~blargg_vector() { STD::free( begin_ ); }
|
||||
|
||||
typedef STD::size_t size_type;
|
||||
|
||||
blargg_err_t resize( size_type n )
|
||||
{
|
||||
void* p = STD::realloc( begin_, n * sizeof (T) );
|
||||
if ( !p && n )
|
||||
return "Out of memory";
|
||||
begin_ = (T*) p;
|
||||
size_ = n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
void* p = begin_;
|
||||
begin_ = 0;
|
||||
size_ = 0;
|
||||
STD::free( p );
|
||||
}
|
||||
|
||||
size_type size() const { return size_; }
|
||||
|
||||
T* begin() { return begin_; }
|
||||
T* end() { return begin_ + size_; }
|
||||
|
||||
const T* begin() const { return begin_; }
|
||||
const T* end() const { return begin_ + size_; }
|
||||
|
||||
T& operator [] ( size_type n )
|
||||
{
|
||||
assert( n <= size_ ); // allow for past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
|
||||
const T& operator [] ( size_type n ) const
|
||||
{
|
||||
assert( n <= size_ ); // allow for past-the-end value
|
||||
return begin_ [n];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,156 +0,0 @@
|
|||
|
||||
// CPU Byte Order Utilities
|
||||
|
||||
// Game_Music_Emu 0.3.0
|
||||
|
||||
#ifndef BLARGG_ENDIAN
|
||||
#define BLARGG_ENDIAN
|
||||
|
||||
#include "blargg_common.h"
|
||||
|
||||
#if 0
|
||||
// Read 16/32-bit little-endian integer from memory
|
||||
unsigned GET_LE16( void const* );
|
||||
unsigned long GET_LE32( void const* );
|
||||
|
||||
// Read 16/32-bit big-endian integer from memory
|
||||
unsigned GET_BE16( void const* );
|
||||
unsigned long GET_BE32( void const* );
|
||||
|
||||
// Write 16/32-bit integer to memory in little-endian format
|
||||
void SET_LE16( void*, unsigned );
|
||||
void SET_LE32( void*, unsigned );
|
||||
|
||||
// Write 16/32-bit integer to memory in big-endian format
|
||||
void SET_BE16( void*, unsigned long );
|
||||
void SET_BE32( void*, unsigned long );
|
||||
#endif
|
||||
|
||||
inline unsigned get_le16( void const* p )
|
||||
{
|
||||
return ((unsigned char*) p) [1] * 0x100 +
|
||||
((unsigned char*) p) [0];
|
||||
}
|
||||
|
||||
inline unsigned get_be16( void const* p )
|
||||
{
|
||||
return ((unsigned char*) p) [0] * 0x100 +
|
||||
((unsigned char*) p) [1];
|
||||
}
|
||||
|
||||
inline unsigned long get_le32( void const* p )
|
||||
{
|
||||
return ((unsigned char*) p) [3] * 0x01000000 +
|
||||
((unsigned char*) p) [2] * 0x00010000 +
|
||||
((unsigned char*) p) [1] * 0x00000100 +
|
||||
((unsigned char*) p) [0];
|
||||
}
|
||||
|
||||
inline unsigned long get_be32( void const* p )
|
||||
{
|
||||
return ((unsigned char*) p) [0] * 0x01000000 +
|
||||
((unsigned char*) p) [1] * 0x00010000 +
|
||||
((unsigned char*) p) [2] * 0x00000100 +
|
||||
((unsigned char*) p) [3];
|
||||
}
|
||||
|
||||
inline void set_le16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
}
|
||||
|
||||
inline void set_be16( void* p, unsigned n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [1] = (unsigned char) n;
|
||||
}
|
||||
|
||||
inline void set_le32( void* p, unsigned long n )
|
||||
{
|
||||
((unsigned char*) p) [3] = (unsigned char) (n >> 24);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [0] = (unsigned char) n;
|
||||
}
|
||||
|
||||
inline void set_be32( void* p, unsigned long n )
|
||||
{
|
||||
((unsigned char*) p) [0] = (unsigned char) (n >> 24);
|
||||
((unsigned char*) p) [1] = (unsigned char) (n >> 16);
|
||||
((unsigned char*) p) [2] = (unsigned char) (n >> 8);
|
||||
((unsigned char*) p) [3] = (unsigned char) n;
|
||||
}
|
||||
|
||||
#ifndef GET_LE16
|
||||
// Optimized implementation if byte order is known
|
||||
#if BLARGG_NONPORTABLE && BLARGG_LITTLE_ENDIAN
|
||||
#define GET_LE16( addr ) (*(BOOST::uint16_t*) (addr))
|
||||
#define GET_LE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||
#define SET_LE16( addr, data ) (void (*(BOOST::uint16_t*) (addr) = (data)))
|
||||
#define SET_LE32( addr, data ) (void (*(BOOST::uint32_t*) (addr) = (data)))
|
||||
|
||||
#elif BLARGG_NONPORTABLE && BLARGG_CPU_POWERPC
|
||||
// PowerPC has special byte-reversed instructions
|
||||
// to do: assumes that PowerPC is running in big-endian mode
|
||||
#define GET_LE16( addr ) (__lhbrx( (addr), 0 ))
|
||||
#define GET_LE32( addr ) (__lwbrx( (addr), 0 ))
|
||||
#define SET_LE16( addr, data ) (__sthbrx( (data), (addr), 0 ))
|
||||
#define SET_LE32( addr, data ) (__stwbrx( (data), (addr), 0 ))
|
||||
|
||||
#define GET_BE16( addr ) (*(BOOST::uint16_t*) (addr))
|
||||
#define GET_BE32( addr ) (*(BOOST::uint32_t*) (addr))
|
||||
#define SET_BE16( addr, data ) (void (*(BOOST::uint16_t*) (addr) = (data)))
|
||||
#define SET_BE32( addr, data ) (void (*(BOOST::uint32_t*) (addr) = (data)))
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE16
|
||||
#define GET_LE16( addr ) get_le16( addr )
|
||||
#endif
|
||||
|
||||
#ifndef GET_LE32
|
||||
#define GET_LE32( addr ) get_le32( addr )
|
||||
#endif
|
||||
|
||||
#ifndef SET_LE16
|
||||
#define SET_LE16( addr, data ) set_le16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef SET_LE32
|
||||
#define SET_LE32( addr, data ) set_le32( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE16
|
||||
#define GET_BE16( addr ) get_be16( addr )
|
||||
#endif
|
||||
|
||||
#ifndef GET_BE32
|
||||
#define GET_BE32( addr ) get_be32( addr )
|
||||
#endif
|
||||
|
||||
#ifndef SET_BE16
|
||||
#define SET_BE16( addr, data ) set_be16( addr, data )
|
||||
#endif
|
||||
|
||||
#ifndef SET_BE32
|
||||
#define SET_BE32( addr, data ) set_be32( addr, data )
|
||||
#endif
|
||||
|
||||
// auto-selecting versions
|
||||
|
||||
inline void set_le( BOOST::uint16_t* p, unsigned n ) { SET_LE16( p, n ); }
|
||||
inline void set_le( BOOST::uint32_t* p, unsigned long n ) { SET_LE32( p, n ); }
|
||||
|
||||
inline void set_be( BOOST::uint16_t* p, unsigned n ) { SET_BE16( p, n ); }
|
||||
inline void set_be( BOOST::uint32_t* p, unsigned long n ) { SET_BE32( p, n ); }
|
||||
|
||||
inline unsigned get_le( BOOST::uint16_t* p ) { return GET_LE16( p ); }
|
||||
inline unsigned long get_le( BOOST::uint32_t* p ) { return GET_LE32( p ); }
|
||||
|
||||
inline unsigned get_be( BOOST::uint16_t* p ) { return GET_BE16( p ); }
|
||||
inline unsigned long get_be( BOOST::uint32_t* p ) { return GET_BE32( p ); }
|
||||
|
||||
#endif
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
|
||||
// By default, #included at beginning of library source files.
|
||||
// Can be overridden by #defining BLARGG_SOURCE_BEGIN to path of alternate file.
|
||||
|
||||
// Copyright (C) 2005 Shay Green.
|
||||
|
||||
#ifndef BLARGG_SOURCE_H
|
||||
#define BLARGG_SOURCE_H
|
||||
|
||||
// If debugging is enabled, abort program if expr is false. Meant for checking
|
||||
// internal state and consistency. A failed assertion indicates a bug in the module.
|
||||
// void assert( bool expr );
|
||||
#include <assert.h>
|
||||
|
||||
// If debugging is enabled and expr is false, abort program. Meant for checking
|
||||
// caller-supplied parameters and operations that are outside the control of the
|
||||
// module. A failed requirement indicates a bug outside the module.
|
||||
// void require( bool expr );
|
||||
#undef require
|
||||
#define require( expr ) assert( expr )
|
||||
|
||||
// Like printf() except output goes to debug log file. Might be defined to do
|
||||
// nothing (not even evaluate its arguments).
|
||||
// void dprintf( const char* format, ... );
|
||||
#undef dprintf
|
||||
#ifdef BLARGG_DPRINTF
|
||||
#define dprintf BLARGG_DPRINTF
|
||||
#else
|
||||
inline void blargg_dprintf_( const char*, ... ) { }
|
||||
#define dprintf (1) ? (void) 0 : blargg_dprintf_
|
||||
#endif
|
||||
|
||||
// If enabled, evaluate expr and if false, make debug log entry with source file
|
||||
// and line. Meant for finding situations that should be examined further, but that
|
||||
// don't indicate a problem. In all cases, execution continues normally.
|
||||
#undef check
|
||||
#ifdef BLARGG_CHECK
|
||||
#define check( expr ) BLARGG_CHECK( expr )
|
||||
#else
|
||||
#define check( expr ) ((void) 0)
|
||||
#endif
|
||||
|
||||
// If expr returns non-NULL error string, return it from current function, otherwise continue.
|
||||
#define BLARGG_RETURN_ERR( expr ) do { \
|
||||
blargg_err_t blargg_return_err_ = (expr); \
|
||||
if ( blargg_return_err_ ) return blargg_return_err_; \
|
||||
} while ( 0 )
|
||||
|
||||
// If ptr is NULL, return out of memory error string.
|
||||
#define BLARGG_CHECK_ALLOC( ptr ) do { if ( (ptr) == 0 ) return "Out of memory"; } while ( 0 )
|
||||
|
||||
// Avoid any macros which evaluate their arguments multiple times
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
// using const references generates crappy code, and I am currenly only using these
|
||||
// for built-in types, so they take arguments by value
|
||||
|
||||
template<class T>
|
||||
inline T min( T x, T y )
|
||||
{
|
||||
if ( x < y )
|
||||
return x;
|
||||
return y;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline T max( T x, T y )
|
||||
{
|
||||
if ( x < y )
|
||||
return y;
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
// Boost substitute. For full boost library see http://boost.org
|
||||
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#define BOOST_CONFIG_HPP
|
||||
|
||||
#define BOOST_MINIMAL 1
|
||||
|
||||
#define BLARGG_BEGIN_NAMESPACE( name )
|
||||
#define BLARGG_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
|
||||
// Boost substitute. For full boost library see http://boost.org
|
||||
|
||||
#ifndef BOOST_CSTDINT_HPP
|
||||
#define BOOST_CSTDINT_HPP
|
||||
|
||||
#if BLARGG_USE_NAMESPACE
|
||||
#include <climits>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
BLARGG_BEGIN_NAMESPACE( boost )
|
||||
|
||||
#if UCHAR_MAX != 0xFF || SCHAR_MAX != 0x7F
|
||||
# error "No suitable 8-bit type available"
|
||||
#endif
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed char int8_t;
|
||||
|
||||
#if USHRT_MAX != 0xFFFF
|
||||
# error "No suitable 16-bit type available"
|
||||
#endif
|
||||
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
#if ULONG_MAX == 0xFFFFFFFF
|
||||
typedef long int32_t;
|
||||
typedef unsigned long uint32_t;
|
||||
#elif UINT_MAX == 0xFFFFFFFF
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
# error "No suitable 32-bit type available"
|
||||
#endif
|
||||
|
||||
BLARGG_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
// Boost substitute. For full boost library see http://boost.org
|
||||
|
||||
#ifndef BOOST_STATIC_ASSERT_HPP
|
||||
#define BOOST_STATIC_ASSERT_HPP
|
||||
|
||||
#if defined (_MSC_VER) && _MSC_VER <= 1200
|
||||
// MSVC6 can't handle the ##line concatenation
|
||||
#define BOOST_STATIC_ASSERT( expr ) struct { int n [1 / ((expr) ? 1 : 0)]; }
|
||||
|
||||
#else
|
||||
#define BOOST_STATIC_ASSERT3( expr, line ) \
|
||||
typedef int boost_static_assert_##line [1 / ((expr) ? 1 : 0)]
|
||||
|
||||
#define BOOST_STATIC_ASSERT2( expr, line ) BOOST_STATIC_ASSERT3( expr, line )
|
||||
|
||||
#define BOOST_STATIC_ASSERT( expr ) BOOST_STATIC_ASSERT2( expr, __LINE__ )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
43
VBA.vcproj
43
VBA.vcproj
|
@ -158,46 +158,21 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="0"
|
||||
EnableIntrinsicFunctions="true"
|
||||
AdditionalOptions="/D_ST_MODEL
/D_SECURE_SCL=0"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
EnableFiberSafeOptimizations="false"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)src\win32\dependencies\zlib";"$(SolutionDir)src\win32\dependencies\libpng";"$(SolutionDir)src\win32\dependencies\cximage""
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;NDEBUG;FINAL_VERSION;MMX;_CRT_SECURE_NO_WARNINGS"
|
||||
IgnoreStandardIncludePath="false"
|
||||
GeneratePreprocessedFile="0"
|
||||
KeepComments="false"
|
||||
StringPooling="false"
|
||||
MinimalRebuild="false"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="0"
|
||||
SmallerTypeCheck="false"
|
||||
AdditionalIncludeDirectories=".\src\win32\dependencies\zlib;.\src\win32\dependencies\libpng;.\src\win32\dependencies\cximage"
|
||||
PreprocessorDefinitions="WIN32;WINVER=0x0500;NDEBUG;_WINDOWS;OEMRESOURCE;MMX;ASM;FINAL_VERSION;BKPT_SUPPORT;_CRT_SECURE_NO_DEPRECATE"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="0"
|
||||
BufferSecurityCheck="true"
|
||||
EnableFunctionLevelLinking="false"
|
||||
EnableEnhancedInstructionSet="0"
|
||||
DisableLanguageExtensions="false"
|
||||
DefaultCharIsUnsigned="false"
|
||||
TreatWChar_tAsBuiltInType="false"
|
||||
ForceConformanceInForLoopScope="false"
|
||||
RuntimeTypeInfo="false"
|
||||
BufferSecurityCheck="false"
|
||||
EnableEnhancedInstructionSet="1"
|
||||
FloatingPointModel="2"
|
||||
UsePrecompiledHeader="0"
|
||||
ExpandAttributedSource="false"
|
||||
AssemblerOutput="0"
|
||||
BrowseInformation="0"
|
||||
WarningLevel="3"
|
||||
WarnAsError="false"
|
||||
SuppressStartupBanner="true"
|
||||
Detect64BitPortabilityProblems="false"
|
||||
DebugInformationFormat="0"
|
||||
CallingConvention="0"
|
||||
CompileAs="2"
|
||||
ShowIncludes="false"
|
||||
UndefineAllPreprocessorDefinitions="false"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="libpng"
|
||||
ProjectGUID="{664BE444-CCED-4C81-9724-7057ECBAAC82}"
|
||||
RootNamespace="libpng"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)zlib""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/libpng.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)zlib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/libpng.lib"
|
||||
IgnoreAllDefaultLibraries="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\png.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\png.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngconf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngerror.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngget.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngmem.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngpread.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngread.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrtran.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrutil.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngset.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngtrans.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngvcrd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwio.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwrite.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwtran.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwutil.c"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -1,158 +0,0 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="libpng"
|
||||
ProjectGUID="{664BE444-CCED-4C81-9724-7057ECBAAC82}"
|
||||
RootNamespace="libpng"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)zlib""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/libpng.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SolutionDir)zlib""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/libpng.lib"
|
||||
IgnoreAllDefaultLibraries="TRUE"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<File
|
||||
RelativePath=".\png.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\png.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngconf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngerror.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngget.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngmem.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngpread.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngread.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrio.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrtran.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngrutil.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngset.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngtrans.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngvcrd.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwio.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwrite.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwtran.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pngwutil.c">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
828
libpng/png.c
828
libpng/png.c
|
@ -1,828 +0,0 @@
|
|||
|
||||
/* png.c - location for general purpose libpng functions
|
||||
*
|
||||
* libpng version 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#define PNG_NO_EXTERN
|
||||
#include "png.h"
|
||||
|
||||
/* Generate a compiler error if there is an old png.h in the search path. */
|
||||
typedef version_1_2_8 Your_png_h_is_not_version_1_2_8;
|
||||
|
||||
/* Version information for C files. This had better match the version
|
||||
* string defined in png.h. */
|
||||
|
||||
#ifdef PNG_USE_GLOBAL_ARRAYS
|
||||
/* png_libpng_ver was changed to a function in version 1.0.5c */
|
||||
const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING;
|
||||
|
||||
/* png_sig was changed to a function in version 1.0.5c */
|
||||
/* Place to hold the signature string for a PNG file. */
|
||||
const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
|
||||
/* Invoke global declarations for constant strings for known chunk types */
|
||||
PNG_IHDR;
|
||||
PNG_IDAT;
|
||||
PNG_IEND;
|
||||
PNG_PLTE;
|
||||
PNG_bKGD;
|
||||
PNG_cHRM;
|
||||
PNG_gAMA;
|
||||
PNG_hIST;
|
||||
PNG_iCCP;
|
||||
PNG_iTXt;
|
||||
PNG_oFFs;
|
||||
PNG_pCAL;
|
||||
PNG_sCAL;
|
||||
PNG_pHYs;
|
||||
PNG_sBIT;
|
||||
PNG_sPLT;
|
||||
PNG_sRGB;
|
||||
PNG_tEXt;
|
||||
PNG_tIME;
|
||||
PNG_tRNS;
|
||||
PNG_zTXt;
|
||||
|
||||
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
|
||||
|
||||
/* start of interlace block */
|
||||
const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
|
||||
|
||||
/* offset to next interlace block */
|
||||
const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
|
||||
|
||||
/* start of interlace block in the y direction */
|
||||
const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
|
||||
|
||||
/* offset to next interlace block in the y direction */
|
||||
const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
|
||||
|
||||
/* width of interlace block (used in assembler routines only) */
|
||||
#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
|
||||
const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
|
||||
#endif
|
||||
|
||||
/* Height of interlace block. This is not currently used - if you need
|
||||
* it, uncomment it here and in png.h
|
||||
const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
|
||||
*/
|
||||
|
||||
/* Mask to determine which pixels are valid in a pass */
|
||||
const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
|
||||
|
||||
/* Mask to determine which pixels to overwrite while displaying */
|
||||
const int FARDATA png_pass_dsp_mask[]
|
||||
= {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
|
||||
|
||||
#endif /* PNG_USE_GLOBAL_ARRAYS */
|
||||
|
||||
/* Tells libpng that we have already handled the first "num_bytes" bytes
|
||||
* of the PNG file signature. If the PNG data is embedded into another
|
||||
* stream we can set num_bytes = 8 so that libpng will not attempt to read
|
||||
* or write any of the magic bytes before it starts on the IHDR.
|
||||
*/
|
||||
|
||||
void PNGAPI
|
||||
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
|
||||
{
|
||||
png_debug(1, "in png_set_sig_bytes\n");
|
||||
if (num_bytes > 8)
|
||||
png_error(png_ptr, "Too many bytes for PNG signature.");
|
||||
|
||||
png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
|
||||
}
|
||||
|
||||
/* Checks whether the supplied bytes match the PNG signature. We allow
|
||||
* checking less than the full 8-byte signature so that those apps that
|
||||
* already read the first few bytes of a file to determine the file type
|
||||
* can simply check the remaining bytes for extra assurance. Returns
|
||||
* an integer less than, equal to, or greater than zero if sig is found,
|
||||
* respectively, to be less than, to match, or be greater than the correct
|
||||
* PNG signature (this is the same behaviour as strcmp, memcmp, etc).
|
||||
*/
|
||||
int PNGAPI
|
||||
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
|
||||
{
|
||||
png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
if (num_to_check > 8)
|
||||
num_to_check = 8;
|
||||
else if (num_to_check < 1)
|
||||
return (0);
|
||||
|
||||
if (start > 7)
|
||||
return (0);
|
||||
|
||||
if (start + num_to_check > 8)
|
||||
num_to_check = 8 - start;
|
||||
|
||||
return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
|
||||
}
|
||||
|
||||
/* (Obsolete) function to check signature bytes. It does not allow one
|
||||
* to check a partial signature. This function might be removed in the
|
||||
* future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG.
|
||||
*/
|
||||
int PNGAPI
|
||||
png_check_sig(png_bytep sig, int num)
|
||||
{
|
||||
return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
|
||||
}
|
||||
|
||||
/* Function to allocate memory for zlib and clear it to 0. */
|
||||
#ifdef PNG_1_0_X
|
||||
voidpf PNGAPI
|
||||
#else
|
||||
voidpf /* private */
|
||||
#endif
|
||||
png_zalloc(voidpf png_ptr, uInt items, uInt size)
|
||||
{
|
||||
png_voidp ptr;
|
||||
png_structp p=png_ptr;
|
||||
png_uint_32 save_flags=p->flags;
|
||||
png_uint_32 num_bytes;
|
||||
|
||||
if (items > PNG_UINT_32_MAX/size)
|
||||
{
|
||||
png_warning (png_ptr, "Potential overflow in png_zalloc()");
|
||||
return (NULL);
|
||||
}
|
||||
num_bytes = (png_uint_32)items * size;
|
||||
|
||||
p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
|
||||
ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
|
||||
p->flags=save_flags;
|
||||
|
||||
#if defined(PNG_1_0_X) && !defined(PNG_NO_ZALLOC_ZERO)
|
||||
if (ptr == NULL)
|
||||
return ((voidpf)ptr);
|
||||
|
||||
if (num_bytes > (png_uint_32)0x8000L)
|
||||
{
|
||||
png_memset(ptr, 0, (png_size_t)0x8000L);
|
||||
png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
|
||||
(png_size_t)(num_bytes - (png_uint_32)0x8000L));
|
||||
}
|
||||
else
|
||||
{
|
||||
png_memset(ptr, 0, (png_size_t)num_bytes);
|
||||
}
|
||||
#endif
|
||||
return ((voidpf)ptr);
|
||||
}
|
||||
|
||||
/* function to free memory for zlib */
|
||||
#ifdef PNG_1_0_X
|
||||
void PNGAPI
|
||||
#else
|
||||
void /* private */
|
||||
#endif
|
||||
png_zfree(voidpf png_ptr, voidpf ptr)
|
||||
{
|
||||
png_free((png_structp)png_ptr, (png_voidp)ptr);
|
||||
}
|
||||
|
||||
/* Reset the CRC variable to 32 bits of 1's. Care must be taken
|
||||
* in case CRC is > 32 bits to leave the top bits 0.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_reset_crc(png_structp png_ptr)
|
||||
{
|
||||
png_ptr->crc = crc32(0, Z_NULL, 0);
|
||||
}
|
||||
|
||||
/* Calculate the CRC over a section of data. We can only pass as
|
||||
* much data to this routine as the largest single buffer size. We
|
||||
* also check that this data will actually be used before going to the
|
||||
* trouble of calculating it.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
|
||||
{
|
||||
int need_crc = 1;
|
||||
|
||||
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
|
||||
{
|
||||
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
|
||||
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
|
||||
need_crc = 0;
|
||||
}
|
||||
else /* critical */
|
||||
{
|
||||
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
|
||||
need_crc = 0;
|
||||
}
|
||||
|
||||
if (need_crc)
|
||||
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
|
||||
}
|
||||
|
||||
/* Allocate the memory for an info_struct for the application. We don't
|
||||
* really need the png_ptr, but it could potentially be useful in the
|
||||
* future. This should be used in favour of malloc(png_sizeof(png_info))
|
||||
* and png_info_init() so that applications that want to use a shared
|
||||
* libpng don't have to be recompiled if png_info changes size.
|
||||
*/
|
||||
png_infop PNGAPI
|
||||
png_create_info_struct(png_structp png_ptr)
|
||||
{
|
||||
png_infop info_ptr;
|
||||
|
||||
png_debug(1, "in png_create_info_struct\n");
|
||||
if(png_ptr == NULL) return (NULL);
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
|
||||
png_ptr->malloc_fn, png_ptr->mem_ptr);
|
||||
#else
|
||||
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
|
||||
#endif
|
||||
if (info_ptr != NULL)
|
||||
png_info_init_3(&info_ptr, png_sizeof(png_info));
|
||||
|
||||
return (info_ptr);
|
||||
}
|
||||
|
||||
/* This function frees the memory associated with a single info struct.
|
||||
* Normally, one would use either png_destroy_read_struct() or
|
||||
* png_destroy_write_struct() to free an info struct, but this may be
|
||||
* useful for some applications.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
|
||||
{
|
||||
png_infop info_ptr = NULL;
|
||||
|
||||
png_debug(1, "in png_destroy_info_struct\n");
|
||||
if (info_ptr_ptr != NULL)
|
||||
info_ptr = *info_ptr_ptr;
|
||||
|
||||
if (info_ptr != NULL)
|
||||
{
|
||||
png_info_destroy(png_ptr, info_ptr);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
|
||||
png_ptr->mem_ptr);
|
||||
#else
|
||||
png_destroy_struct((png_voidp)info_ptr);
|
||||
#endif
|
||||
*info_ptr_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the info structure. This is now an internal function (0.89)
|
||||
* and applications using it are urged to use png_create_info_struct()
|
||||
* instead.
|
||||
*/
|
||||
#if defined(PNG_1_0_X) || defined (PNG_1_2_X)
|
||||
#undef png_info_init
|
||||
void PNGAPI
|
||||
png_info_init(png_infop info_ptr)
|
||||
{
|
||||
/* We only come here via pre-1.0.12-compiled applications */
|
||||
png_info_init_3(&info_ptr, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PNGAPI
|
||||
png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
|
||||
{
|
||||
png_infop info_ptr = *ptr_ptr;
|
||||
|
||||
png_debug(1, "in png_info_init_3\n");
|
||||
|
||||
if(png_sizeof(png_info) > png_info_struct_size)
|
||||
{
|
||||
png_destroy_struct(info_ptr);
|
||||
info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
|
||||
*ptr_ptr = info_ptr;
|
||||
}
|
||||
|
||||
/* set everything to 0 */
|
||||
png_memset(info_ptr, 0, png_sizeof (png_info));
|
||||
}
|
||||
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
void PNGAPI
|
||||
png_data_freer(png_structp png_ptr, png_infop info_ptr,
|
||||
int freer, png_uint_32 mask)
|
||||
{
|
||||
png_debug(1, "in png_data_freer\n");
|
||||
if (png_ptr == NULL || info_ptr == NULL)
|
||||
return;
|
||||
if(freer == PNG_DESTROY_WILL_FREE_DATA)
|
||||
info_ptr->free_me |= mask;
|
||||
else if(freer == PNG_USER_WILL_FREE_DATA)
|
||||
info_ptr->free_me &= ~mask;
|
||||
else
|
||||
png_warning(png_ptr,
|
||||
"Unknown freer parameter in png_data_freer.");
|
||||
}
|
||||
#endif
|
||||
|
||||
void PNGAPI
|
||||
png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask,
|
||||
int num)
|
||||
{
|
||||
png_debug(1, "in png_free_data\n");
|
||||
if (png_ptr == NULL || info_ptr == NULL)
|
||||
return;
|
||||
|
||||
#if defined(PNG_TEXT_SUPPORTED)
|
||||
/* free text item num or (if num == -1) all text items */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_TEXT)
|
||||
#endif
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if (info_ptr->text && info_ptr->text[num].key)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->text[num].key);
|
||||
info_ptr->text[num].key = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < info_ptr->num_text; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
|
||||
png_free(png_ptr, info_ptr->text);
|
||||
info_ptr->text = NULL;
|
||||
info_ptr->num_text=0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tRNS_SUPPORTED)
|
||||
/* free any tRNS entry */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
|
||||
#else
|
||||
if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
|
||||
#endif
|
||||
{
|
||||
png_free(png_ptr, info_ptr->trans);
|
||||
info_ptr->valid &= ~PNG_INFO_tRNS;
|
||||
#ifndef PNG_FREE_ME_SUPPORTED
|
||||
png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
|
||||
#endif
|
||||
info_ptr->trans = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_sCAL_SUPPORTED)
|
||||
/* free any sCAL entry */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_SCAL)
|
||||
#endif
|
||||
{
|
||||
#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
|
||||
png_free(png_ptr, info_ptr->scal_s_width);
|
||||
png_free(png_ptr, info_ptr->scal_s_height);
|
||||
info_ptr->scal_s_width = NULL;
|
||||
info_ptr->scal_s_height = NULL;
|
||||
#endif
|
||||
info_ptr->valid &= ~PNG_INFO_sCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_pCAL_SUPPORTED)
|
||||
/* free any pCAL entry */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_PCAL)
|
||||
#endif
|
||||
{
|
||||
png_free(png_ptr, info_ptr->pcal_purpose);
|
||||
png_free(png_ptr, info_ptr->pcal_units);
|
||||
info_ptr->pcal_purpose = NULL;
|
||||
info_ptr->pcal_units = NULL;
|
||||
if (info_ptr->pcal_params != NULL)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->pcal_params[i]);
|
||||
info_ptr->pcal_params[i]=NULL;
|
||||
}
|
||||
png_free(png_ptr, info_ptr->pcal_params);
|
||||
info_ptr->pcal_params = NULL;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_pCAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_iCCP_SUPPORTED)
|
||||
/* free any iCCP entry */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_ICCP)
|
||||
#endif
|
||||
{
|
||||
png_free(png_ptr, info_ptr->iccp_name);
|
||||
png_free(png_ptr, info_ptr->iccp_profile);
|
||||
info_ptr->iccp_name = NULL;
|
||||
info_ptr->iccp_profile = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_iCCP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_sPLT_SUPPORTED)
|
||||
/* free a given sPLT entry, or (if num == -1) all sPLT entries */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_SPLT)
|
||||
#endif
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if(info_ptr->splt_palettes)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->splt_palettes[num].name);
|
||||
png_free(png_ptr, info_ptr->splt_palettes[num].entries);
|
||||
info_ptr->splt_palettes[num].name = NULL;
|
||||
info_ptr->splt_palettes[num].entries = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(info_ptr->splt_palettes_num)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
|
||||
|
||||
png_free(png_ptr, info_ptr->splt_palettes);
|
||||
info_ptr->splt_palettes = NULL;
|
||||
info_ptr->splt_palettes_num = 0;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_sPLT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_UNKN)
|
||||
#endif
|
||||
{
|
||||
if (num != -1)
|
||||
{
|
||||
if(info_ptr->unknown_chunks)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->unknown_chunks[num].data);
|
||||
info_ptr->unknown_chunks[num].data = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
if(info_ptr->unknown_chunks_num)
|
||||
{
|
||||
for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
|
||||
|
||||
png_free(png_ptr, info_ptr->unknown_chunks);
|
||||
info_ptr->unknown_chunks = NULL;
|
||||
info_ptr->unknown_chunks_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_hIST_SUPPORTED)
|
||||
/* free any hIST entry */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
|
||||
#else
|
||||
if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
|
||||
#endif
|
||||
{
|
||||
png_free(png_ptr, info_ptr->hist);
|
||||
info_ptr->hist = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_hIST;
|
||||
#ifndef PNG_FREE_ME_SUPPORTED
|
||||
png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* free any PLTE entry that was internally allocated */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
|
||||
#else
|
||||
if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
|
||||
#endif
|
||||
{
|
||||
png_zfree(png_ptr, info_ptr->palette);
|
||||
info_ptr->palette = NULL;
|
||||
info_ptr->valid &= ~PNG_INFO_PLTE;
|
||||
#ifndef PNG_FREE_ME_SUPPORTED
|
||||
png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
|
||||
#endif
|
||||
info_ptr->num_palette = 0;
|
||||
}
|
||||
|
||||
#if defined(PNG_INFO_IMAGE_SUPPORTED)
|
||||
/* free any image bits attached to the info structure */
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
|
||||
#else
|
||||
if (mask & PNG_FREE_ROWS)
|
||||
#endif
|
||||
{
|
||||
if(info_ptr->row_pointers)
|
||||
{
|
||||
int row;
|
||||
for (row = 0; row < (int)info_ptr->height; row++)
|
||||
{
|
||||
png_free(png_ptr, info_ptr->row_pointers[row]);
|
||||
info_ptr->row_pointers[row]=NULL;
|
||||
}
|
||||
png_free(png_ptr, info_ptr->row_pointers);
|
||||
info_ptr->row_pointers=NULL;
|
||||
}
|
||||
info_ptr->valid &= ~PNG_INFO_IDAT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_FREE_ME_SUPPORTED
|
||||
if(num == -1)
|
||||
info_ptr->free_me &= ~mask;
|
||||
else
|
||||
info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This is an internal routine to free any memory that the info struct is
|
||||
* pointing to before re-using it or freeing the struct itself. Recall
|
||||
* that png_free() checks for NULL pointers for us.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
png_debug(1, "in png_info_destroy\n");
|
||||
|
||||
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
|
||||
|
||||
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
|
||||
if (png_ptr->num_chunk_list)
|
||||
{
|
||||
png_free(png_ptr, png_ptr->chunk_list);
|
||||
png_ptr->chunk_list=NULL;
|
||||
png_ptr->num_chunk_list=0;
|
||||
}
|
||||
#endif
|
||||
|
||||
png_info_init_3(&info_ptr, png_sizeof(png_info));
|
||||
}
|
||||
|
||||
/* This function returns a pointer to the io_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy() or png_read_destroy() are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_io_ptr(png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr->io_ptr);
|
||||
}
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
/* Initialize the default input/output functions for the PNG file. If you
|
||||
* use your own read or write routines, you can call either png_set_read_fn()
|
||||
* or png_set_write_fn() instead of png_init_io(). If you have defined
|
||||
* PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
|
||||
* necessarily available.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_init_io(png_structp png_ptr, png_FILE_p fp)
|
||||
{
|
||||
png_debug(1, "in png_init_io\n");
|
||||
png_ptr->io_ptr = (png_voidp)fp;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_TIME_RFC1123_SUPPORTED)
|
||||
/* Convert the supplied time into an RFC 1123 string suitable for use in
|
||||
* a "Creation Time" or other text-based time string.
|
||||
*/
|
||||
png_charp PNGAPI
|
||||
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
|
||||
{
|
||||
static PNG_CONST char short_months[12][4] =
|
||||
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
|
||||
if (png_ptr->time_buffer == NULL)
|
||||
{
|
||||
png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
|
||||
png_sizeof(char)));
|
||||
}
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
{
|
||||
wchar_t time_buf[29];
|
||||
wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
|
||||
ptime->day % 32, short_months[(ptime->month - 1) % 12],
|
||||
ptime->year, ptime->hour % 24, ptime->minute % 60,
|
||||
ptime->second % 61);
|
||||
WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
|
||||
NULL, NULL);
|
||||
}
|
||||
#else
|
||||
#ifdef USE_FAR_KEYWORD
|
||||
{
|
||||
char near_time_buf[29];
|
||||
sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
|
||||
ptime->day % 32, short_months[(ptime->month - 1) % 12],
|
||||
ptime->year, ptime->hour % 24, ptime->minute % 60,
|
||||
ptime->second % 61);
|
||||
png_memcpy(png_ptr->time_buffer, near_time_buf,
|
||||
29*png_sizeof(char));
|
||||
}
|
||||
#else
|
||||
sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
|
||||
ptime->day % 32, short_months[(ptime->month - 1) % 12],
|
||||
ptime->year, ptime->hour % 24, ptime->minute % 60,
|
||||
ptime->second % 61);
|
||||
#endif
|
||||
#endif /* _WIN32_WCE */
|
||||
return ((png_charp)png_ptr->time_buffer);
|
||||
}
|
||||
#endif /* PNG_TIME_RFC1123_SUPPORTED */
|
||||
|
||||
#if 0
|
||||
/* Signature string for a PNG file. */
|
||||
png_bytep PNGAPI
|
||||
png_sig_bytes(void)
|
||||
{
|
||||
return ((png_bytep)"\211\120\116\107\015\012\032\012");
|
||||
}
|
||||
#endif
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_copyright(png_structp png_ptr)
|
||||
{
|
||||
if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) "\n libpng version 1.2.8 - December 3, 2004\n\
|
||||
Copyright (c) 1998-2004 Glenn Randers-Pehrson\n\
|
||||
Copyright (c) 1996-1997 Andreas Dilger\n\
|
||||
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
|
||||
return ((png_charp) "");
|
||||
}
|
||||
|
||||
/* The following return the library version as a short string in the
|
||||
* format 1.0.0 through 99.99.99zz. To get the version of *.h files
|
||||
* used with your application, print out PNG_LIBPNG_VER_STRING, which
|
||||
* is defined in png.h.
|
||||
* Note: now there is no difference between png_get_libpng_ver() and
|
||||
* png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
|
||||
* it is guaranteed that png.c uses the correct version of png.h.
|
||||
*/
|
||||
png_charp PNGAPI
|
||||
png_get_libpng_ver(png_structp png_ptr)
|
||||
{
|
||||
/* Version of *.c files used when building libpng */
|
||||
if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) PNG_LIBPNG_VER_STRING);
|
||||
return ((png_charp) "");
|
||||
}
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_header_ver(png_structp png_ptr)
|
||||
{
|
||||
/* Version of *.h files used when building libpng */
|
||||
if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) PNG_LIBPNG_VER_STRING);
|
||||
return ((png_charp) "");
|
||||
}
|
||||
|
||||
png_charp PNGAPI
|
||||
png_get_header_version(png_structp png_ptr)
|
||||
{
|
||||
/* Returns longer string containing both version and date */
|
||||
if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */
|
||||
return ((png_charp) PNG_HEADER_VERSION_STRING);
|
||||
return ((png_charp) "");
|
||||
}
|
||||
|
||||
#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
int PNGAPI
|
||||
png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
|
||||
{
|
||||
/* check chunk_name and return "keep" value if it's on the list, else 0 */
|
||||
int i;
|
||||
png_bytep p;
|
||||
if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
|
||||
return 0;
|
||||
p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
|
||||
for (i = png_ptr->num_chunk_list; i; i--, p-=5)
|
||||
if (!png_memcmp(chunk_name, p, 4))
|
||||
return ((int)*(p+4));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function, added to libpng-1.0.6g, is untested. */
|
||||
int PNGAPI
|
||||
png_reset_zstream(png_structp png_ptr)
|
||||
{
|
||||
return (inflateReset(&png_ptr->zstream));
|
||||
}
|
||||
|
||||
/* This function was added to libpng-1.0.7 */
|
||||
png_uint_32 PNGAPI
|
||||
png_access_version_number(void)
|
||||
{
|
||||
/* Version of *.c files used when building libpng */
|
||||
return((png_uint_32) PNG_LIBPNG_VER);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(PNG_1_0_X)
|
||||
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
|
||||
/* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
|
||||
/* this INTERNAL function was added to libpng 1.2.0 */
|
||||
void /* PRIVATE */
|
||||
png_init_mmx_flags (png_structp png_ptr)
|
||||
{
|
||||
png_ptr->mmx_rowbytes_threshold = 0;
|
||||
png_ptr->mmx_bitdepth_threshold = 0;
|
||||
|
||||
# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
|
||||
|
||||
png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
|
||||
|
||||
if (png_mmx_support() > 0) {
|
||||
png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
|
||||
# ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
|
||||
| PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
|
||||
# endif
|
||||
# ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
|
||||
| PNG_ASM_FLAG_MMX_READ_INTERLACE
|
||||
# endif
|
||||
# ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
|
||||
;
|
||||
# else
|
||||
| PNG_ASM_FLAG_MMX_READ_FILTER_SUB
|
||||
| PNG_ASM_FLAG_MMX_READ_FILTER_UP
|
||||
| PNG_ASM_FLAG_MMX_READ_FILTER_AVG
|
||||
| PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
|
||||
|
||||
png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
|
||||
png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
|
||||
# endif
|
||||
} else {
|
||||
png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
|
||||
| PNG_MMX_READ_FLAGS
|
||||
| PNG_MMX_WRITE_FLAGS );
|
||||
}
|
||||
|
||||
# else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */
|
||||
|
||||
/* clear all MMX flags; no support is compiled in */
|
||||
png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
|
||||
|
||||
# endif /* ?(PNGVCRD || PNGGCCRD) */
|
||||
}
|
||||
|
||||
#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */
|
||||
|
||||
/* this function was added to libpng 1.2.0 */
|
||||
#if !defined(PNG_USE_PNGGCCRD) && \
|
||||
!(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
|
||||
int PNGAPI
|
||||
png_mmx_support(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif /* PNG_1_0_X */
|
||||
|
||||
#ifdef PNG_SIZE_T
|
||||
/* Added at libpng version 1.2.6 */
|
||||
PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size));
|
||||
png_size_t PNGAPI
|
||||
png_convert_size(size_t size)
|
||||
{
|
||||
if (size > (png_size_t)-1)
|
||||
PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */
|
||||
return ((png_size_t)size);
|
||||
}
|
||||
#endif /* PNG_SIZE_T */
|
3419
libpng/png.h
3419
libpng/png.h
File diff suppressed because it is too large
Load Diff
1437
libpng/pngconf.h
1437
libpng/pngconf.h
File diff suppressed because it is too large
Load Diff
|
@ -1,295 +0,0 @@
|
|||
|
||||
/* pngerror.c - stub functions for i/o and memory allocation
|
||||
*
|
||||
* libpng version 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This file provides a location for all error handling. Users who
|
||||
* need special error handling are expected to write replacement functions
|
||||
* and use png_set_error_fn() to use those functions. See the instructions
|
||||
* at each function.
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
|
||||
static void /* PRIVATE */
|
||||
png_default_error PNGARG((png_structp png_ptr,
|
||||
png_const_charp error_message));
|
||||
static void /* PRIVATE */
|
||||
png_default_warning PNGARG((png_structp png_ptr,
|
||||
png_const_charp warning_message));
|
||||
|
||||
/* This function is called whenever there is a fatal error. This function
|
||||
* should not be changed. If there is a need to handle errors differently,
|
||||
* you should supply a replacement error function and use png_set_error_fn()
|
||||
* to replace the error function at run-time.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
char msg[16];
|
||||
if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
|
||||
{
|
||||
if (*error_message == '#')
|
||||
{
|
||||
int offset;
|
||||
for (offset=1; offset<15; offset++)
|
||||
if (*(error_message+offset) == ' ')
|
||||
break;
|
||||
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<offset-1; i++)
|
||||
msg[i]=error_message[i+1];
|
||||
msg[i]='\0';
|
||||
error_message=msg;
|
||||
}
|
||||
else
|
||||
error_message+=offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
|
||||
{
|
||||
msg[0]='0';
|
||||
msg[1]='\0';
|
||||
error_message=msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (png_ptr != NULL && png_ptr->error_fn != NULL)
|
||||
(*(png_ptr->error_fn))(png_ptr, error_message);
|
||||
|
||||
/* If the custom handler doesn't exist, or if it returns,
|
||||
use the default handler, which will not return. */
|
||||
png_default_error(png_ptr, error_message);
|
||||
}
|
||||
|
||||
/* This function is called whenever there is a non-fatal error. This function
|
||||
* should not be changed. If there is a need to handle warnings differently,
|
||||
* you should supply a replacement warning function and use
|
||||
* png_set_error_fn() to replace the warning function at run-time.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
int offset = 0;
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
|
||||
#endif
|
||||
{
|
||||
if (*warning_message == '#')
|
||||
{
|
||||
for (offset=1; offset<15; offset++)
|
||||
if (*(warning_message+offset) == ' ')
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
||||
(*(png_ptr->warning_fn))(png_ptr, warning_message+offset);
|
||||
else
|
||||
png_default_warning(png_ptr, warning_message+offset);
|
||||
}
|
||||
|
||||
/* These utilities are used internally to build an error message that relates
|
||||
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
|
||||
* this is used to prefix the message. The message is limited in length
|
||||
* to 63 bytes, the name characters are output as hex digits wrapped in []
|
||||
* if the character is invalid.
|
||||
*/
|
||||
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
|
||||
static PNG_CONST char png_digit[16] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
static void /* PRIVATE */
|
||||
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
|
||||
error_message)
|
||||
{
|
||||
int iout = 0, iin = 0;
|
||||
|
||||
while (iin < 4)
|
||||
{
|
||||
int c = png_ptr->chunk_name[iin++];
|
||||
if (isnonalpha(c))
|
||||
{
|
||||
buffer[iout++] = '[';
|
||||
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
|
||||
buffer[iout++] = png_digit[c & 0x0f];
|
||||
buffer[iout++] = ']';
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[iout++] = (png_byte)c;
|
||||
}
|
||||
}
|
||||
|
||||
if (error_message == NULL)
|
||||
buffer[iout] = 0;
|
||||
else
|
||||
{
|
||||
buffer[iout++] = ':';
|
||||
buffer[iout++] = ' ';
|
||||
png_strncpy(buffer+iout, error_message, 63);
|
||||
buffer[iout+63] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_chunk_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
char msg[18+64];
|
||||
png_format_buffer(png_ptr, msg, error_message);
|
||||
png_error(png_ptr, msg);
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
char msg[18+64];
|
||||
png_format_buffer(png_ptr, msg, warning_message);
|
||||
png_warning(png_ptr, msg);
|
||||
}
|
||||
|
||||
/* This is the default error handling function. Note that replacements for
|
||||
* this function MUST NOT RETURN, or the program will likely crash. This
|
||||
* function is used by default, or if the program supplies NULL for the
|
||||
* error function pointer in png_set_error_fn().
|
||||
*/
|
||||
static void /* PRIVATE */
|
||||
png_default_error(png_structp png_ptr, png_const_charp error_message)
|
||||
{
|
||||
#ifndef PNG_NO_CONSOLE_IO
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (*error_message == '#')
|
||||
{
|
||||
int offset;
|
||||
char error_number[16];
|
||||
for (offset=0; offset<15; offset++)
|
||||
{
|
||||
error_number[offset] = *(error_message+offset+1);
|
||||
if (*(error_message+offset) == ' ')
|
||||
break;
|
||||
}
|
||||
if((offset > 1) && (offset < 15))
|
||||
{
|
||||
error_number[offset-1]='\0';
|
||||
fprintf(stderr, "libpng error no. %s: %s\n", error_number,
|
||||
error_message+offset);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
fprintf(stderr, "libpng error: %s\n", error_message);
|
||||
#endif
|
||||
|
||||
#ifdef PNG_SETJMP_SUPPORTED
|
||||
# ifdef USE_FAR_KEYWORD
|
||||
{
|
||||
jmp_buf jmpbuf;
|
||||
png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf));
|
||||
longjmp(jmpbuf, 1);
|
||||
}
|
||||
# else
|
||||
longjmp(png_ptr->jmpbuf, 1);
|
||||
# endif
|
||||
#else
|
||||
/* make compiler happy */ ;
|
||||
if (png_ptr)
|
||||
PNG_ABORT();
|
||||
#endif
|
||||
#ifdef PNG_NO_CONSOLE_IO
|
||||
/* make compiler happy */ ;
|
||||
if (&error_message != NULL)
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function is called when there is a warning, but the library thinks
|
||||
* it can continue anyway. Replacement functions don't have to do anything
|
||||
* here if you don't want them to. In the default configuration, png_ptr is
|
||||
* not used, but it is passed in case it may be useful.
|
||||
*/
|
||||
static void /* PRIVATE */
|
||||
png_default_warning(png_structp png_ptr, png_const_charp warning_message)
|
||||
{
|
||||
#ifndef PNG_NO_CONSOLE_IO
|
||||
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
if (*warning_message == '#')
|
||||
{
|
||||
int offset;
|
||||
char warning_number[16];
|
||||
for (offset=0; offset<15; offset++)
|
||||
{
|
||||
warning_number[offset]=*(warning_message+offset+1);
|
||||
if (*(warning_message+offset) == ' ')
|
||||
break;
|
||||
}
|
||||
if((offset > 1) && (offset < 15))
|
||||
{
|
||||
warning_number[offset-1]='\0';
|
||||
fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
|
||||
warning_message+offset);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "libpng warning: %s\n", warning_message);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
fprintf(stderr, "libpng warning: %s\n", warning_message);
|
||||
#else
|
||||
/* make compiler happy */ ;
|
||||
if (warning_message)
|
||||
return;
|
||||
#endif
|
||||
/* make compiler happy */ ;
|
||||
if (png_ptr)
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function is called when the application wants to use another method
|
||||
* of handling errors and warnings. Note that the error function MUST NOT
|
||||
* return to the calling routine or serious problems will occur. The return
|
||||
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
|
||||
png_error_ptr error_fn, png_error_ptr warning_fn)
|
||||
{
|
||||
png_ptr->error_ptr = error_ptr;
|
||||
png_ptr->error_fn = error_fn;
|
||||
png_ptr->warning_fn = warning_fn;
|
||||
}
|
||||
|
||||
|
||||
/* This function returns a pointer to the error_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy and png_read_destroy are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_error_ptr(png_structp png_ptr)
|
||||
{
|
||||
return ((png_voidp)png_ptr->error_ptr);
|
||||
}
|
||||
|
||||
|
||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
||||
void PNGAPI
|
||||
png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
|
||||
{
|
||||
if(png_ptr != NULL)
|
||||
{
|
||||
png_ptr->flags &=
|
||||
((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
|
||||
}
|
||||
}
|
||||
#endif
|
934
libpng/pngget.c
934
libpng/pngget.c
|
@ -1,934 +0,0 @@
|
|||
|
||||
/* pngget.c - retrieval of values from info struct
|
||||
*
|
||||
* libpng 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->valid & flag);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->rowbytes);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if defined(PNG_INFO_IMAGE_SUPPORTED)
|
||||
png_bytepp PNGAPI
|
||||
png_get_rows(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->row_pointers);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_EASY_ACCESS_SUPPORTED
|
||||
/* easy access to info, added in libpng-0.99 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_image_width(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->width;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_image_height(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->height;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->bit_depth;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_color_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->color_type;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->filter_type;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->interlace_type;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
{
|
||||
return info_ptr->compression_type;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
|
||||
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
|
||||
return (0);
|
||||
else return (info_ptr->x_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
|
||||
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
|
||||
return (0);
|
||||
else return (info_ptr->y_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
|
||||
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
|
||||
info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
|
||||
return (0);
|
||||
else return (info_ptr->x_pixels_per_unit);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
float PNGAPI
|
||||
png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_pHYs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
|
||||
if (info_ptr->x_pixels_per_unit == 0)
|
||||
return ((float)0.0);
|
||||
else
|
||||
return ((float)((float)info_ptr->y_pixels_per_unit
|
||||
/(float)info_ptr->x_pixels_per_unit));
|
||||
}
|
||||
#else
|
||||
return (0.0);
|
||||
#endif
|
||||
return ((float)0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_oFFs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
|
||||
if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
|
||||
return (0);
|
||||
else return (info_ptr->x_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_oFFs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
|
||||
if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
|
||||
return (0);
|
||||
else return (info_ptr->y_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_oFFs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
|
||||
if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
|
||||
return (0);
|
||||
else return (info_ptr->x_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_int_32 PNGAPI
|
||||
png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
#if defined(PNG_oFFs_SUPPORTED)
|
||||
if (info_ptr->valid & PNG_INFO_oFFs)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
|
||||
if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
|
||||
return (0);
|
||||
else return (info_ptr->y_offset);
|
||||
}
|
||||
#else
|
||||
return (0);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
|
||||
*.0254 +.5));
|
||||
}
|
||||
|
||||
float PNGAPI
|
||||
png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
|
||||
*.00003937);
|
||||
}
|
||||
|
||||
float PNGAPI
|
||||
png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
|
||||
*.00003937);
|
||||
}
|
||||
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "pHYs");
|
||||
if (res_x != NULL)
|
||||
{
|
||||
*res_x = info_ptr->x_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (res_y != NULL)
|
||||
{
|
||||
*res_y = info_ptr->y_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (unit_type != NULL)
|
||||
{
|
||||
*unit_type = (int)info_ptr->phys_unit_type;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
if(*unit_type == 1)
|
||||
{
|
||||
if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
|
||||
if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif /* PNG_pHYs_SUPPORTED */
|
||||
#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
|
||||
|
||||
/* png_get_channels really belongs in here, too, but it's been around longer */
|
||||
|
||||
#endif /* PNG_EASY_ACCESS_SUPPORTED */
|
||||
|
||||
png_byte PNGAPI
|
||||
png_get_channels(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->channels);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
png_bytep PNGAPI
|
||||
png_get_signature(png_structp png_ptr, png_infop info_ptr)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL)
|
||||
return(info_ptr->signature);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#if defined(PNG_bKGD_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
|
||||
png_color_16p *background)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
|
||||
&& background != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "bKGD");
|
||||
*background = &(info_ptr->background);
|
||||
return (PNG_INFO_bKGD);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_cHRM_SUPPORTED)
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
|
||||
double *white_x, double *white_y, double *red_x, double *red_y,
|
||||
double *green_x, double *green_y, double *blue_x, double *blue_y)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "cHRM");
|
||||
if (white_x != NULL)
|
||||
*white_x = (double)info_ptr->x_white;
|
||||
if (white_y != NULL)
|
||||
*white_y = (double)info_ptr->y_white;
|
||||
if (red_x != NULL)
|
||||
*red_x = (double)info_ptr->x_red;
|
||||
if (red_y != NULL)
|
||||
*red_y = (double)info_ptr->y_red;
|
||||
if (green_x != NULL)
|
||||
*green_x = (double)info_ptr->x_green;
|
||||
if (green_y != NULL)
|
||||
*green_y = (double)info_ptr->y_green;
|
||||
if (blue_x != NULL)
|
||||
*blue_x = (double)info_ptr->x_blue;
|
||||
if (blue_y != NULL)
|
||||
*blue_y = (double)info_ptr->y_blue;
|
||||
return (PNG_INFO_cHRM);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
|
||||
png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
|
||||
png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
|
||||
png_fixed_point *blue_x, png_fixed_point *blue_y)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "cHRM");
|
||||
if (white_x != NULL)
|
||||
*white_x = info_ptr->int_x_white;
|
||||
if (white_y != NULL)
|
||||
*white_y = info_ptr->int_y_white;
|
||||
if (red_x != NULL)
|
||||
*red_x = info_ptr->int_x_red;
|
||||
if (red_y != NULL)
|
||||
*red_y = info_ptr->int_y_red;
|
||||
if (green_x != NULL)
|
||||
*green_x = info_ptr->int_x_green;
|
||||
if (green_y != NULL)
|
||||
*green_y = info_ptr->int_y_green;
|
||||
if (blue_x != NULL)
|
||||
*blue_x = info_ptr->int_x_blue;
|
||||
if (blue_y != NULL)
|
||||
*blue_y = info_ptr->int_y_blue;
|
||||
return (PNG_INFO_cHRM);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PNG_gAMA_SUPPORTED)
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
|
||||
&& file_gamma != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "gAMA");
|
||||
*file_gamma = (double)info_ptr->gamma;
|
||||
return (PNG_INFO_gAMA);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
|
||||
png_fixed_point *int_file_gamma)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
|
||||
&& int_file_gamma != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "gAMA");
|
||||
*int_file_gamma = info_ptr->int_gamma;
|
||||
return (PNG_INFO_gAMA);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PNG_sRGB_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
|
||||
&& file_srgb_intent != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "sRGB");
|
||||
*file_srgb_intent = (int)info_ptr->srgb_intent;
|
||||
return (PNG_INFO_sRGB);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_iCCP_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
|
||||
png_charpp name, int *compression_type,
|
||||
png_charpp profile, png_uint_32 *proflen)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
|
||||
&& name != NULL && profile != NULL && proflen != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "iCCP");
|
||||
*name = info_ptr->iccp_name;
|
||||
*profile = info_ptr->iccp_profile;
|
||||
/* compression_type is a dummy so the API won't have to change
|
||||
if we introduce multiple compression types later. */
|
||||
*proflen = (int)info_ptr->iccp_proflen;
|
||||
*compression_type = (int)info_ptr->iccp_compression;
|
||||
return (PNG_INFO_iCCP);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_sPLT_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
|
||||
png_sPLT_tpp spalettes)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
|
||||
*spalettes = info_ptr->splt_palettes;
|
||||
return ((png_uint_32)info_ptr->splt_palettes_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_hIST_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
|
||||
&& hist != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "hIST");
|
||||
*hist = info_ptr->hist;
|
||||
return (PNG_INFO_hIST);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *width, png_uint_32 *height, int *bit_depth,
|
||||
int *color_type, int *interlace_type, int *compression_type,
|
||||
int *filter_type)
|
||||
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
|
||||
bit_depth != NULL && color_type != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "IHDR");
|
||||
*width = info_ptr->width;
|
||||
*height = info_ptr->height;
|
||||
*bit_depth = info_ptr->bit_depth;
|
||||
if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
|
||||
png_error(png_ptr, "Invalid bit depth");
|
||||
*color_type = info_ptr->color_type;
|
||||
if (info_ptr->color_type > 6)
|
||||
png_error(png_ptr, "Invalid color type");
|
||||
if (compression_type != NULL)
|
||||
*compression_type = info_ptr->compression_type;
|
||||
if (filter_type != NULL)
|
||||
*filter_type = info_ptr->filter_type;
|
||||
if (interlace_type != NULL)
|
||||
*interlace_type = info_ptr->interlace_type;
|
||||
|
||||
/* check for potential overflow of rowbytes */
|
||||
if (*width == 0 || *width > PNG_UINT_31_MAX)
|
||||
png_error(png_ptr, "Invalid image width");
|
||||
if (*height == 0 || *height > PNG_UINT_31_MAX)
|
||||
png_error(png_ptr, "Invalid image height");
|
||||
if (info_ptr->width > (PNG_UINT_32_MAX
|
||||
>> 3) /* 8-byte RGBA pixels */
|
||||
- 64 /* bigrowbuf hack */
|
||||
- 1 /* filter byte */
|
||||
- 7*8 /* rounding of width to multiple of 8 pixels */
|
||||
- 8) /* extra max_pixel_depth pad */
|
||||
{
|
||||
png_warning(png_ptr,
|
||||
"Width too large for libpng to process image data.");
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(PNG_oFFs_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
|
||||
png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
|
||||
&& offset_x != NULL && offset_y != NULL && unit_type != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "oFFs");
|
||||
*offset_x = info_ptr->x_offset;
|
||||
*offset_y = info_ptr->y_offset;
|
||||
*unit_type = (int)info_ptr->offset_unit_type;
|
||||
return (PNG_INFO_oFFs);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_pCAL_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
|
||||
png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
|
||||
png_charp *units, png_charpp *params)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
|
||||
&& purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
|
||||
nparams != NULL && units != NULL && params != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "pCAL");
|
||||
*purpose = info_ptr->pcal_purpose;
|
||||
*X0 = info_ptr->pcal_X0;
|
||||
*X1 = info_ptr->pcal_X1;
|
||||
*type = (int)info_ptr->pcal_type;
|
||||
*nparams = (int)info_ptr->pcal_nparams;
|
||||
*units = info_ptr->pcal_units;
|
||||
*params = info_ptr->pcal_params;
|
||||
return (PNG_INFO_pCAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_sCAL_SUPPORTED)
|
||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
|
||||
int *unit, double *width, double *height)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_sCAL))
|
||||
{
|
||||
*unit = info_ptr->scal_unit;
|
||||
*width = info_ptr->scal_pixel_width;
|
||||
*height = info_ptr->scal_pixel_height;
|
||||
return (PNG_INFO_sCAL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#else
|
||||
#ifdef PNG_FIXED_POINT_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
|
||||
int *unit, png_charpp width, png_charpp height)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_sCAL))
|
||||
{
|
||||
*unit = info_ptr->scal_unit;
|
||||
*width = info_ptr->scal_s_width;
|
||||
*height = info_ptr->scal_s_height;
|
||||
return (PNG_INFO_sCAL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(PNG_pHYs_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
|
||||
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
|
||||
if (png_ptr != NULL && info_ptr != NULL &&
|
||||
(info_ptr->valid & PNG_INFO_pHYs))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "pHYs");
|
||||
if (res_x != NULL)
|
||||
{
|
||||
*res_x = info_ptr->x_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (res_y != NULL)
|
||||
{
|
||||
*res_y = info_ptr->y_pixels_per_unit;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
if (unit_type != NULL)
|
||||
{
|
||||
*unit_type = (int)info_ptr->phys_unit_type;
|
||||
retval |= PNG_INFO_pHYs;
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_uint_32 PNGAPI
|
||||
png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
|
||||
int *num_palette)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
|
||||
&& palette != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "PLTE");
|
||||
*palette = info_ptr->palette;
|
||||
*num_palette = info_ptr->num_palette;
|
||||
png_debug1(3, "num_palette = %d\n", *num_palette);
|
||||
return (PNG_INFO_PLTE);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#if defined(PNG_sBIT_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
|
||||
&& sig_bit != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "sBIT");
|
||||
*sig_bit = &(info_ptr->sig_bit);
|
||||
return (PNG_INFO_sBIT);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_TEXT_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
|
||||
int *num_text)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n",
|
||||
(png_ptr->chunk_name[0] == '\0' ? "text"
|
||||
: (png_const_charp)png_ptr->chunk_name));
|
||||
if (text_ptr != NULL)
|
||||
*text_ptr = info_ptr->text;
|
||||
if (num_text != NULL)
|
||||
*num_text = info_ptr->num_text;
|
||||
return ((png_uint_32)info_ptr->num_text);
|
||||
}
|
||||
if (num_text != NULL)
|
||||
*num_text = 0;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tIME_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
|
||||
&& mod_time != NULL)
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "tIME");
|
||||
*mod_time = &(info_ptr->mod_time);
|
||||
return (PNG_INFO_tIME);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tRNS_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
|
||||
png_bytep *trans, int *num_trans, png_color_16p *trans_values)
|
||||
{
|
||||
png_uint_32 retval = 0;
|
||||
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
|
||||
{
|
||||
png_debug1(1, "in %s retrieval function\n", "tRNS");
|
||||
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
if (trans != NULL)
|
||||
{
|
||||
*trans = info_ptr->trans;
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
if (trans_values != NULL)
|
||||
*trans_values = &(info_ptr->trans_values);
|
||||
}
|
||||
else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
|
||||
{
|
||||
if (trans_values != NULL)
|
||||
{
|
||||
*trans_values = &(info_ptr->trans_values);
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
if(trans != NULL)
|
||||
*trans = NULL;
|
||||
}
|
||||
if(num_trans != NULL)
|
||||
{
|
||||
*num_trans = info_ptr->num_trans;
|
||||
retval |= PNG_INFO_tRNS;
|
||||
}
|
||||
}
|
||||
return (retval);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
|
||||
png_uint_32 PNGAPI
|
||||
png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
|
||||
png_unknown_chunkpp unknowns)
|
||||
{
|
||||
if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
|
||||
*unknowns = info_ptr->unknown_chunks;
|
||||
return ((png_uint_32)info_ptr->unknown_chunks_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
|
||||
png_byte PNGAPI
|
||||
png_get_rgb_to_gray_status (png_structp png_ptr)
|
||||
{
|
||||
return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_USER_CHUNKS_SUPPORTED)
|
||||
png_voidp PNGAPI
|
||||
png_get_user_chunk_ptr(png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_chunk_ptr : NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
png_uint_32 PNGAPI
|
||||
png_get_compression_buffer_size(png_structp png_ptr)
|
||||
{
|
||||
return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PNG_1_0_X
|
||||
#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
|
||||
/* this function was added to libpng 1.2.0 and should exist by default */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_asm_flags (png_structp png_ptr)
|
||||
{
|
||||
return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L);
|
||||
}
|
||||
|
||||
/* this function was added to libpng 1.2.0 and should exist by default */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_asm_flagmask (int flag_select)
|
||||
{
|
||||
png_uint_32 settable_asm_flags = 0;
|
||||
|
||||
if (flag_select & PNG_SELECT_READ)
|
||||
settable_asm_flags |=
|
||||
PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
|
||||
PNG_ASM_FLAG_MMX_READ_INTERLACE |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_UP |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
|
||||
/* no non-MMX flags yet */
|
||||
|
||||
#if 0
|
||||
/* GRR: no write-flags yet, either, but someday... */
|
||||
if (flag_select & PNG_SELECT_WRITE)
|
||||
settable_asm_flags |=
|
||||
PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
|
||||
#endif /* 0 */
|
||||
|
||||
return settable_asm_flags; /* _theoretically_ settable capabilities only */
|
||||
}
|
||||
#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
|
||||
|
||||
|
||||
#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
|
||||
/* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
|
||||
/* this function was added to libpng 1.2.0 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_mmx_flagmask (int flag_select, int *compilerID)
|
||||
{
|
||||
png_uint_32 settable_mmx_flags = 0;
|
||||
|
||||
if (flag_select & PNG_SELECT_READ)
|
||||
settable_mmx_flags |=
|
||||
PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
|
||||
PNG_ASM_FLAG_MMX_READ_INTERLACE |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_UP |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
|
||||
PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
|
||||
#if 0
|
||||
/* GRR: no MMX write support yet, but someday... */
|
||||
if (flag_select & PNG_SELECT_WRITE)
|
||||
settable_mmx_flags |=
|
||||
PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
|
||||
#endif /* 0 */
|
||||
|
||||
if (compilerID != NULL) {
|
||||
#ifdef PNG_USE_PNGVCRD
|
||||
*compilerID = 1; /* MSVC */
|
||||
#else
|
||||
#ifdef PNG_USE_PNGGCCRD
|
||||
*compilerID = 2; /* gcc/gas */
|
||||
#else
|
||||
*compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return settable_mmx_flags; /* _theoretically_ settable capabilities only */
|
||||
}
|
||||
|
||||
/* this function was added to libpng 1.2.0 */
|
||||
png_byte PNGAPI
|
||||
png_get_mmx_bitdepth_threshold (png_structp png_ptr)
|
||||
{
|
||||
return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0);
|
||||
}
|
||||
|
||||
/* this function was added to libpng 1.2.0 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_mmx_rowbytes_threshold (png_structp png_ptr)
|
||||
{
|
||||
return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L);
|
||||
}
|
||||
#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
|
||||
|
||||
#ifdef PNG_SET_USER_LIMITS_SUPPORTED
|
||||
/* these functions were added to libpng 1.2.6 */
|
||||
png_uint_32 PNGAPI
|
||||
png_get_user_width_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_width_max : 0);
|
||||
}
|
||||
png_uint_32 PNGAPI
|
||||
png_get_user_height_max (png_structp png_ptr)
|
||||
{
|
||||
return (png_ptr? png_ptr->user_height_max : 0);
|
||||
}
|
||||
#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
|
||||
|
||||
#endif /* ?PNG_1_0_X */
|
595
libpng/pngmem.c
595
libpng/pngmem.c
|
@ -1,595 +0,0 @@
|
|||
|
||||
/* pngmem.c - stub functions for memory allocation
|
||||
*
|
||||
* libpng version 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This file provides a location for all memory allocation. Users who
|
||||
* need special memory handling are expected to supply replacement
|
||||
* functions for png_malloc() and png_free(), and to use
|
||||
* png_create_read_struct_2() and png_create_write_struct_2() to
|
||||
* identify the replacement functions.
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
|
||||
/* Borland DOS special memory handler */
|
||||
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
|
||||
/* if you change this, be sure to change the one in png.h also */
|
||||
|
||||
/* Allocate memory for a png_struct. The malloc and memset can be replaced
|
||||
by a single call to calloc() if this is thought to improve performance. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct(int type)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
|
||||
}
|
||||
|
||||
/* Alternate version of png_create_struct, for use with user-defined malloc. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
png_size_t size;
|
||||
png_voidp struct_ptr;
|
||||
|
||||
if (type == PNG_STRUCT_INFO)
|
||||
size = png_sizeof(png_info);
|
||||
else if (type == PNG_STRUCT_PNG)
|
||||
size = png_sizeof(png_struct);
|
||||
else
|
||||
return (png_get_copyright(NULL));
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if(malloc_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
|
||||
}
|
||||
else
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
struct_ptr = (png_voidp)farmalloc(size);
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
return (struct_ptr);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct(png_voidp struct_ptr)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
|
||||
png_voidp mem_ptr)
|
||||
{
|
||||
#endif
|
||||
if (struct_ptr != NULL)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if(free_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
farfree (struct_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory. For reasonable files, size should never exceed
|
||||
* 64K. However, zlib may allocate more then 64K if you don't tell
|
||||
* it not to. See zconf.h and png.h for more information. zlib does
|
||||
* need to allocate exactly 64K, so whatever you call here must
|
||||
* have the ability to do that.
|
||||
*
|
||||
* Borland seems to have a problem in DOS mode for exactly 64K.
|
||||
* It gives you a segment with an offset of 8 (perhaps to store its
|
||||
* memory stuff). zlib doesn't like this at all, so we have to
|
||||
* detect and deal with it. This code should not be needed in
|
||||
* Windows or OS/2 modes, and only in 16 bit mode. This code has
|
||||
* been updated by Alexander Lehmann for version 0.89 to waste less
|
||||
* memory.
|
||||
*
|
||||
* Note that we can't use png_size_t for the "size" declaration,
|
||||
* since on some systems a png_size_t is a 16-bit quantity, and as a
|
||||
* result, we would be truncating potentially larger memory requests
|
||||
* (which should cause a fatal error) and introducing major problems.
|
||||
*/
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc(png_structp png_ptr, png_uint_32 size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if(png_ptr->malloc_fn != NULL)
|
||||
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
|
||||
else
|
||||
ret = (png_malloc_default(png_ptr, size));
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of memory!");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc_default(png_structp png_ptr, png_uint_32 size)
|
||||
{
|
||||
png_voidp ret;
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
#ifdef PNG_MAX_MALLOC_64K
|
||||
if (size > (png_uint_32)65536L)
|
||||
{
|
||||
png_warning(png_ptr, "Cannot Allocate > 64K");
|
||||
ret = NULL;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (size != (size_t)size)
|
||||
ret = NULL;
|
||||
else if (size == (png_uint_32)65536L)
|
||||
{
|
||||
if (png_ptr->offset_table == NULL)
|
||||
{
|
||||
/* try to see if we need to do any of this fancy stuff */
|
||||
ret = farmalloc(size);
|
||||
if (ret == NULL || ((png_size_t)ret & 0xffff))
|
||||
{
|
||||
int num_blocks;
|
||||
png_uint_32 total_size;
|
||||
png_bytep table;
|
||||
int i;
|
||||
png_byte huge * hptr;
|
||||
|
||||
if (ret != NULL)
|
||||
{
|
||||
farfree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
if(png_ptr->zlib_window_bits > 14)
|
||||
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
|
||||
else
|
||||
num_blocks = 1;
|
||||
if (png_ptr->zlib_mem_level >= 7)
|
||||
num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
|
||||
else
|
||||
num_blocks++;
|
||||
|
||||
total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
|
||||
|
||||
table = farmalloc(total_size);
|
||||
|
||||
if (table == NULL)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
|
||||
else
|
||||
png_warning(png_ptr, "Out Of Memory.");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((png_size_t)table & 0xfff0)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr,
|
||||
"Farmalloc didn't return normalized pointer");
|
||||
else
|
||||
png_warning(png_ptr,
|
||||
"Farmalloc didn't return normalized pointer");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
png_ptr->offset_table = table;
|
||||
png_ptr->offset_table_ptr = farmalloc(num_blocks *
|
||||
png_sizeof (png_bytep));
|
||||
|
||||
if (png_ptr->offset_table_ptr == NULL)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
|
||||
else
|
||||
png_warning(png_ptr, "Out Of memory.");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
hptr = (png_byte huge *)table;
|
||||
if ((png_size_t)hptr & 0xf)
|
||||
{
|
||||
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
|
||||
hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
|
||||
}
|
||||
for (i = 0; i < num_blocks; i++)
|
||||
{
|
||||
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
|
||||
hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
|
||||
}
|
||||
|
||||
png_ptr->offset_table_number = num_blocks;
|
||||
png_ptr->offset_table_count = 0;
|
||||
png_ptr->offset_table_count_free = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
|
||||
else
|
||||
png_warning(png_ptr, "Out of Memory.");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
|
||||
}
|
||||
else
|
||||
ret = farmalloc(size);
|
||||
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if (ret == NULL)
|
||||
{
|
||||
if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
|
||||
else
|
||||
png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
|
||||
}
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* free a pointer allocated by png_malloc(). In the default
|
||||
configuration, png_ptr is not used, but is passed in case it
|
||||
is needed. If ptr is NULL, return without taking any action. */
|
||||
void PNGAPI
|
||||
png_free(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
return;
|
||||
}
|
||||
else png_free_default(png_ptr, ptr);
|
||||
}
|
||||
|
||||
void PNGAPI
|
||||
png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
if (png_ptr->offset_table != NULL)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < png_ptr->offset_table_count; i++)
|
||||
{
|
||||
if (ptr == png_ptr->offset_table_ptr[i])
|
||||
{
|
||||
ptr = NULL;
|
||||
png_ptr->offset_table_count_free++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
|
||||
{
|
||||
farfree(png_ptr->offset_table);
|
||||
farfree(png_ptr->offset_table_ptr);
|
||||
png_ptr->offset_table = NULL;
|
||||
png_ptr->offset_table_ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ptr != NULL)
|
||||
{
|
||||
farfree(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* Not the Borland DOS special memory handler */
|
||||
|
||||
/* Allocate memory for a png_struct or a png_info. The malloc and
|
||||
memset can be replaced by a single call to calloc() if this is thought
|
||||
to improve performance noticably. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct(int type)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
|
||||
}
|
||||
|
||||
/* Allocate memory for a png_struct or a png_info. The malloc and
|
||||
memset can be replaced by a single call to calloc() if this is thought
|
||||
to improve performance noticably. */
|
||||
png_voidp /* PRIVATE */
|
||||
png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
png_size_t size;
|
||||
png_voidp struct_ptr;
|
||||
|
||||
if (type == PNG_STRUCT_INFO)
|
||||
size = png_sizeof(png_info);
|
||||
else if (type == PNG_STRUCT_PNG)
|
||||
size = png_sizeof(png_struct);
|
||||
else
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if(malloc_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
struct_ptr = (*(malloc_fn))(png_ptr, size);
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
return (struct_ptr);
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
struct_ptr = (png_voidp)farmalloc(size);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
struct_ptr = (png_voidp)halloc(size,1);
|
||||
# else
|
||||
struct_ptr = (png_voidp)malloc(size);
|
||||
# endif
|
||||
#endif
|
||||
if (struct_ptr != NULL)
|
||||
png_memset(struct_ptr, 0, size);
|
||||
|
||||
return (struct_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct(png_voidp struct_ptr)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
|
||||
}
|
||||
|
||||
/* Free memory allocated by a png_create_struct() call */
|
||||
void /* PRIVATE */
|
||||
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
|
||||
png_voidp mem_ptr)
|
||||
{
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
if (struct_ptr != NULL)
|
||||
{
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if(free_fn != NULL)
|
||||
{
|
||||
png_struct dummy_struct;
|
||||
png_structp png_ptr = &dummy_struct;
|
||||
png_ptr->mem_ptr=mem_ptr;
|
||||
(*(free_fn))(png_ptr, struct_ptr);
|
||||
return;
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(struct_ptr);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(struct_ptr);
|
||||
# else
|
||||
free(struct_ptr);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate memory. For reasonable files, size should never exceed
|
||||
64K. However, zlib may allocate more then 64K if you don't tell
|
||||
it not to. See zconf.h and png.h for more information. zlib does
|
||||
need to allocate exactly 64K, so whatever you call here must
|
||||
have the ability to do that. */
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc(png_structp png_ptr, png_uint_32 size)
|
||||
{
|
||||
png_voidp ret;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
if(png_ptr->malloc_fn != NULL)
|
||||
ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
|
||||
else
|
||||
ret = (png_malloc_default(png_ptr, size));
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory!");
|
||||
return (ret);
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_malloc_default(png_structp png_ptr, png_uint_32 size)
|
||||
{
|
||||
png_voidp ret;
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
if (png_ptr == NULL || size == 0)
|
||||
return (NULL);
|
||||
|
||||
#ifdef PNG_MAX_MALLOC_64K
|
||||
if (size > (png_uint_32)65536L)
|
||||
{
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Cannot Allocate > 64K");
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check for overflow */
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
if (size != (unsigned long)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = farmalloc(size);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
if (size != (unsigned long)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = halloc(size, 1);
|
||||
# else
|
||||
if (size != (size_t)size)
|
||||
ret = NULL;
|
||||
else
|
||||
ret = malloc((size_t)size);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef PNG_USER_MEM_SUPPORTED
|
||||
if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
|
||||
png_error(png_ptr, "Out of Memory");
|
||||
#endif
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
|
||||
without taking any action. */
|
||||
void PNGAPI
|
||||
png_free(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
if (png_ptr->free_fn != NULL)
|
||||
{
|
||||
(*(png_ptr->free_fn))(png_ptr, ptr);
|
||||
return;
|
||||
}
|
||||
else png_free_default(png_ptr, ptr);
|
||||
}
|
||||
void PNGAPI
|
||||
png_free_default(png_structp png_ptr, png_voidp ptr)
|
||||
{
|
||||
if (png_ptr == NULL || ptr == NULL)
|
||||
return;
|
||||
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
||||
|
||||
#if defined(__TURBOC__) && !defined(__FLAT__)
|
||||
farfree(ptr);
|
||||
#else
|
||||
# if defined(_MSC_VER) && defined(MAXSEG_64K)
|
||||
hfree(ptr);
|
||||
# else
|
||||
free(ptr);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* Not Borland DOS special memory handler */
|
||||
|
||||
#if defined(PNG_1_0_X)
|
||||
# define png_malloc_warn png_malloc
|
||||
#else
|
||||
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
|
||||
* function will set up png_malloc() to issue a png_warning and return NULL
|
||||
* instead of issuing a png_error, if it fails to allocate the requested
|
||||
* memory.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_malloc_warn(png_structp png_ptr, png_uint_32 size)
|
||||
{
|
||||
png_voidp ptr;
|
||||
png_uint_32 save_flags=png_ptr->flags;
|
||||
|
||||
png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
|
||||
ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
|
||||
png_ptr->flags=save_flags;
|
||||
return(ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
|
||||
png_uint_32 length)
|
||||
{
|
||||
png_size_t size;
|
||||
|
||||
size = (png_size_t)length;
|
||||
if ((png_uint_32)size != length)
|
||||
png_error(png_ptr,"Overflow in png_memcpy_check.");
|
||||
|
||||
return(png_memcpy (s1, s2, size));
|
||||
}
|
||||
|
||||
png_voidp PNGAPI
|
||||
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
|
||||
png_uint_32 length)
|
||||
{
|
||||
png_size_t size;
|
||||
|
||||
size = (png_size_t)length;
|
||||
if ((png_uint_32)size != length)
|
||||
png_error(png_ptr,"Overflow in png_memset_check.");
|
||||
|
||||
return (png_memset (s1, value, size));
|
||||
|
||||
}
|
||||
|
||||
#ifdef PNG_USER_MEM_SUPPORTED
|
||||
/* This function is called when the application wants to use another method
|
||||
* of allocating and freeing memory.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
|
||||
malloc_fn, png_free_ptr free_fn)
|
||||
{
|
||||
png_ptr->mem_ptr = mem_ptr;
|
||||
png_ptr->malloc_fn = malloc_fn;
|
||||
png_ptr->free_fn = free_fn;
|
||||
}
|
||||
|
||||
/* This function returns a pointer to the mem_ptr associated with the user
|
||||
* functions. The application should free any memory associated with this
|
||||
* pointer before png_write_destroy and png_read_destroy are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_mem_ptr(png_structp png_ptr)
|
||||
{
|
||||
return ((png_voidp)png_ptr->mem_ptr);
|
||||
}
|
||||
#endif /* PNG_USER_MEM_SUPPORTED */
|
1573
libpng/pngpread.c
1573
libpng/pngpread.c
File diff suppressed because it is too large
Load Diff
1456
libpng/pngread.c
1456
libpng/pngread.c
File diff suppressed because it is too large
Load Diff
161
libpng/pngrio.c
161
libpng/pngrio.c
|
@ -1,161 +0,0 @@
|
|||
|
||||
/* pngrio.c - functions for data input
|
||||
*
|
||||
* libpng 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This file provides a location for all input. Users who need
|
||||
* special handling are expected to write a function that has the same
|
||||
* arguments as this and performs a similar function, but that possibly
|
||||
* has a different input method. Note that you shouldn't change this
|
||||
* function, but rather write a replacement function and then make
|
||||
* libpng use it at run time with png_set_read_fn(...).
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
|
||||
/* Read the data from whatever input you are using. The default routine
|
||||
reads from a file pointer. Note that this routine sometimes gets called
|
||||
with very small lengths, so you should implement some kind of simple
|
||||
buffering if you are using unbuffered reads. This should never be asked
|
||||
to read more then 64K on a 16 bit machine. */
|
||||
void /* PRIVATE */
|
||||
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_debug1(4,"reading %d bytes\n", (int)length);
|
||||
if (png_ptr->read_data_fn != NULL)
|
||||
(*(png_ptr->read_data_fn))(png_ptr, data, length);
|
||||
else
|
||||
png_error(png_ptr, "Call to NULL read function");
|
||||
}
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
/* This is the function that does the actual reading of data. If you are
|
||||
not reading from a standard C stream, you should create a replacement
|
||||
read_data function and use it at run time with png_set_read_fn(), rather
|
||||
than changing the library. */
|
||||
#ifndef USE_FAR_KEYWORD
|
||||
void PNGAPI
|
||||
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_size_t check;
|
||||
|
||||
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
|
||||
* instead of an int, which is what fread() actually returns.
|
||||
*/
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
|
||||
check = 0;
|
||||
#else
|
||||
check = (png_size_t)fread(data, (png_size_t)1, length,
|
||||
(png_FILE_p)png_ptr->io_ptr);
|
||||
#endif
|
||||
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Read Error");
|
||||
}
|
||||
#else
|
||||
/* this is the model-independent version. Since the standard I/O library
|
||||
can't handle far buffers in the medium and small models, we have to copy
|
||||
the data.
|
||||
*/
|
||||
|
||||
#define NEAR_BUF_SIZE 1024
|
||||
#define MIN(a,b) (a <= b ? a : b)
|
||||
|
||||
static void /* PRIVATE */
|
||||
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
int check;
|
||||
png_byte *n_data;
|
||||
png_FILE_p io_ptr;
|
||||
|
||||
/* Check if data really is near. If so, use usual code. */
|
||||
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
|
||||
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
|
||||
if ((png_bytep)n_data == data)
|
||||
{
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
|
||||
check = 0;
|
||||
#else
|
||||
check = fread(n_data, 1, length, io_ptr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte buf[NEAR_BUF_SIZE];
|
||||
png_size_t read, remaining, err;
|
||||
check = 0;
|
||||
remaining = length;
|
||||
do
|
||||
{
|
||||
read = MIN(NEAR_BUF_SIZE, remaining);
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
|
||||
err = 0;
|
||||
#else
|
||||
err = fread(buf, (png_size_t)1, read, io_ptr);
|
||||
#endif
|
||||
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
|
||||
if(err != read)
|
||||
break;
|
||||
else
|
||||
check += err;
|
||||
data += read;
|
||||
remaining -= read;
|
||||
}
|
||||
while (remaining != 0);
|
||||
}
|
||||
if ((png_uint_32)check != (png_uint_32)length)
|
||||
png_error(png_ptr, "read Error");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function allows the application to supply a new input function
|
||||
for libpng if standard C streams aren't being used.
|
||||
|
||||
This function takes as its arguments:
|
||||
png_ptr - pointer to a png input data structure
|
||||
io_ptr - pointer to user supplied structure containing info about
|
||||
the input functions. May be NULL.
|
||||
read_data_fn - pointer to a new input function that takes as its
|
||||
arguments a pointer to a png_struct, a pointer to
|
||||
a location where input data can be stored, and a 32-bit
|
||||
unsigned int that is the number of bytes to be read.
|
||||
To exit and output any fatal error messages the new write
|
||||
function should call png_error(png_ptr, "Error msg"). */
|
||||
void PNGAPI
|
||||
png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
png_rw_ptr read_data_fn)
|
||||
{
|
||||
png_ptr->io_ptr = io_ptr;
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
if (read_data_fn != NULL)
|
||||
png_ptr->read_data_fn = read_data_fn;
|
||||
else
|
||||
png_ptr->read_data_fn = png_default_read_data;
|
||||
#else
|
||||
png_ptr->read_data_fn = read_data_fn;
|
||||
#endif
|
||||
|
||||
/* It is an error to write to a read device */
|
||||
if (png_ptr->write_data_fn != NULL)
|
||||
{
|
||||
png_ptr->write_data_fn = NULL;
|
||||
png_warning(png_ptr,
|
||||
"It's an error to set both read_data_fn and write_data_fn in the ");
|
||||
png_warning(png_ptr,
|
||||
"same structure. Resetting write_data_fn to NULL.");
|
||||
}
|
||||
|
||||
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||
png_ptr->output_flush_fn = NULL;
|
||||
#endif
|
||||
}
|
4177
libpng/pngrtran.c
4177
libpng/pngrtran.c
File diff suppressed because it is too large
Load Diff
3124
libpng/pngrutil.c
3124
libpng/pngrutil.c
File diff suppressed because it is too large
Load Diff
1219
libpng/pngset.c
1219
libpng/pngset.c
File diff suppressed because it is too large
Load Diff
|
@ -1,650 +0,0 @@
|
|||
|
||||
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
|
||||
*
|
||||
* libpng 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
|
||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
/* turn on BGR-to-RGB mapping */
|
||||
void PNGAPI
|
||||
png_set_bgr(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_bgr\n");
|
||||
png_ptr->transformations |= PNG_BGR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
/* turn on 16 bit byte swapping */
|
||||
void PNGAPI
|
||||
png_set_swap(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_swap\n");
|
||||
if (png_ptr->bit_depth == 16)
|
||||
png_ptr->transformations |= PNG_SWAP_BYTES;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
/* turn on pixel packing */
|
||||
void PNGAPI
|
||||
png_set_packing(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_packing\n");
|
||||
if (png_ptr->bit_depth < 8)
|
||||
{
|
||||
png_ptr->transformations |= PNG_PACK;
|
||||
png_ptr->usr_bit_depth = 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
/* turn on packed pixel swapping */
|
||||
void PNGAPI
|
||||
png_set_packswap(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_packswap\n");
|
||||
if (png_ptr->bit_depth < 8)
|
||||
png_ptr->transformations |= PNG_PACKSWAP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
|
||||
{
|
||||
png_debug(1, "in png_set_shift\n");
|
||||
png_ptr->transformations |= PNG_SHIFT;
|
||||
png_ptr->shift = *true_bits;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
||||
int PNGAPI
|
||||
png_set_interlace_handling(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_interlace handling\n");
|
||||
if (png_ptr->interlaced)
|
||||
{
|
||||
png_ptr->transformations |= PNG_INTERLACE;
|
||||
return (7);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||
/* Add a filler byte on read, or remove a filler or alpha byte on write.
|
||||
* The filler type has changed in v0.95 to allow future 2-byte fillers
|
||||
* for 48-bit input data, as well as to avoid problems with some compilers
|
||||
* that don't like bytes as parameters.
|
||||
*/
|
||||
void PNGAPI
|
||||
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
{
|
||||
png_debug(1, "in png_set_filler\n");
|
||||
png_ptr->transformations |= PNG_FILLER;
|
||||
png_ptr->filler = (png_byte)filler;
|
||||
if (filler_loc == PNG_FILLER_AFTER)
|
||||
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
|
||||
else
|
||||
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
|
||||
|
||||
/* This should probably go in the "do_read_filler" routine.
|
||||
* I attempted to do that in libpng-1.0.1a but that caused problems
|
||||
* so I restored it in libpng-1.0.2a
|
||||
*/
|
||||
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_ptr->usr_channels = 4;
|
||||
}
|
||||
|
||||
/* Also I added this in libpng-1.0.2a (what happens when we expand
|
||||
* a less-than-8-bit grayscale to GA? */
|
||||
|
||||
if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
|
||||
{
|
||||
png_ptr->usr_channels = 2;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(PNG_1_0_X)
|
||||
/* Added to libpng-1.2.7 */
|
||||
void PNGAPI
|
||||
png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc)
|
||||
{
|
||||
png_debug(1, "in png_set_add_alpha\n");
|
||||
png_set_filler(png_ptr, filler, filler_loc);
|
||||
png_ptr->transformations |= PNG_ADD_ALPHA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_swap_alpha(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_swap_alpha\n");
|
||||
png_ptr->transformations |= PNG_SWAP_ALPHA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_invert_alpha(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_invert_alpha\n");
|
||||
png_ptr->transformations |= PNG_INVERT_ALPHA;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_invert_mono(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_set_invert_mono\n");
|
||||
png_ptr->transformations |= PNG_INVERT_MONO;
|
||||
}
|
||||
|
||||
/* invert monochrome grayscale data */
|
||||
void /* PRIVATE */
|
||||
png_do_invert(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_invert\n");
|
||||
/* This test removed from libpng version 1.0.13 and 1.2.0:
|
||||
* if (row_info->bit_depth == 1 &&
|
||||
*/
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row == NULL || row_info == NULL)
|
||||
return;
|
||||
#endif
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i++)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
rp++;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=2)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
rp+=2;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = row_info->rowbytes;
|
||||
|
||||
for (i = 0; i < istop; i+=4)
|
||||
{
|
||||
*rp = (png_byte)(~(*rp));
|
||||
*(rp+1) = (png_byte)(~(*(rp+1)));
|
||||
rp+=4;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
/* swaps byte order on 16 bit depth images */
|
||||
void /* PRIVATE */
|
||||
png_do_swap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_swap\n");
|
||||
if (
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
row != NULL && row_info != NULL &&
|
||||
#endif
|
||||
row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop= row_info->width * row_info->channels;
|
||||
|
||||
for (i = 0; i < istop; i++, rp += 2)
|
||||
{
|
||||
png_byte t = *rp;
|
||||
*rp = *(rp + 1);
|
||||
*(rp + 1) = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
static png_byte onebppswaptable[256] = {
|
||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
||||
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
||||
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
||||
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
||||
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
||||
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
||||
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
||||
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
||||
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
||||
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
||||
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
||||
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
||||
};
|
||||
|
||||
static png_byte twobppswaptable[256] = {
|
||||
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
|
||||
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
|
||||
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
|
||||
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
|
||||
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
|
||||
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
|
||||
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
|
||||
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
|
||||
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
|
||||
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
|
||||
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
|
||||
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
|
||||
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
|
||||
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
|
||||
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
|
||||
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
|
||||
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
|
||||
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
|
||||
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
|
||||
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
|
||||
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
|
||||
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
|
||||
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
|
||||
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
|
||||
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
|
||||
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
|
||||
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
|
||||
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
|
||||
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
|
||||
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
|
||||
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
|
||||
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
|
||||
};
|
||||
|
||||
static png_byte fourbppswaptable[256] = {
|
||||
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
|
||||
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
|
||||
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
|
||||
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
|
||||
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
|
||||
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
|
||||
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
|
||||
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
|
||||
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
|
||||
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
|
||||
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
|
||||
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
|
||||
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
|
||||
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
|
||||
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
|
||||
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
|
||||
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
|
||||
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
|
||||
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
|
||||
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
|
||||
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
|
||||
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
|
||||
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
|
||||
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
|
||||
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
|
||||
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
|
||||
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
|
||||
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
|
||||
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
|
||||
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
|
||||
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
|
||||
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
|
||||
};
|
||||
|
||||
/* swaps pixel packing order within bytes */
|
||||
void /* PRIVATE */
|
||||
png_do_packswap(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_packswap\n");
|
||||
if (
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
row != NULL && row_info != NULL &&
|
||||
#endif
|
||||
row_info->bit_depth < 8)
|
||||
{
|
||||
png_bytep rp, end, table;
|
||||
|
||||
end = row + row_info->rowbytes;
|
||||
|
||||
if (row_info->bit_depth == 1)
|
||||
table = onebppswaptable;
|
||||
else if (row_info->bit_depth == 2)
|
||||
table = twobppswaptable;
|
||||
else if (row_info->bit_depth == 4)
|
||||
table = fourbppswaptable;
|
||||
else
|
||||
return;
|
||||
|
||||
for (rp = row; rp < end; rp++)
|
||||
*rp = table[*rp];
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
|
||||
|
||||
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
||||
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
||||
/* remove filler or alpha byte(s) */
|
||||
void /* PRIVATE */
|
||||
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
|
||||
{
|
||||
png_debug(1, "in png_do_strip_filler\n");
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row != NULL && row_info != NULL)
|
||||
#endif
|
||||
{
|
||||
png_bytep sp=row;
|
||||
png_bytep dp=row;
|
||||
png_uint_32 row_width=row_info->width;
|
||||
png_uint_32 i;
|
||||
|
||||
if ((row_info->color_type == PNG_COLOR_TYPE_RGB ||
|
||||
(row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
|
||||
(flags & PNG_FLAG_STRIP_ALPHA))) &&
|
||||
row_info->channels == 4)
|
||||
{
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from RGBX or RGBA to RGB */
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
dp+=3; sp+=4;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
/* This converts from XRGB or ARGB to RGB */
|
||||
else
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 24;
|
||||
row_info->rowbytes = row_width * 3;
|
||||
}
|
||||
else /* if (row_info->bit_depth == 16) */
|
||||
{
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
|
||||
sp += 8; dp += 6;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
/* This could be (although png_memcpy is probably slower):
|
||||
png_memcpy(dp, sp, 6);
|
||||
sp += 8;
|
||||
dp += 6;
|
||||
*/
|
||||
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
/* This could be (although png_memcpy is probably slower):
|
||||
png_memcpy(dp, sp, 6);
|
||||
sp += 8;
|
||||
dp += 6;
|
||||
*/
|
||||
|
||||
sp+=2;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 48;
|
||||
row_info->rowbytes = row_width * 6;
|
||||
}
|
||||
row_info->channels = 3;
|
||||
}
|
||||
else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY ||
|
||||
(row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
||||
(flags & PNG_FLAG_STRIP_ALPHA))) &&
|
||||
row_info->channels == 2)
|
||||
{
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
/* This converts from GX or GA to G */
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
sp++;
|
||||
}
|
||||
}
|
||||
/* This converts from XG or AG to G */
|
||||
else
|
||||
{
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 8;
|
||||
row_info->rowbytes = row_width;
|
||||
}
|
||||
else /* if (row_info->bit_depth == 16) */
|
||||
{
|
||||
if (flags & PNG_FLAG_FILLER_AFTER)
|
||||
{
|
||||
/* This converts from GGXX or GGAA to GG */
|
||||
sp += 4; dp += 2;
|
||||
for (i = 1; i < row_width; i++)
|
||||
{
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
sp += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This converts from XXGG or AAGG to GG */
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
sp += 2;
|
||||
*dp++ = *sp++;
|
||||
*dp++ = *sp++;
|
||||
}
|
||||
}
|
||||
row_info->pixel_depth = 16;
|
||||
row_info->rowbytes = row_width * 2;
|
||||
}
|
||||
row_info->channels = 1;
|
||||
}
|
||||
if (flags & PNG_FLAG_STRIP_ALPHA)
|
||||
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
/* swaps red and blue bytes within a pixel */
|
||||
void /* PRIVATE */
|
||||
png_do_bgr(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_bgr\n");
|
||||
if (
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
row != NULL && row_info != NULL &&
|
||||
#endif
|
||||
(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 3)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 2);
|
||||
*(rp + 2) = save;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 4)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 2);
|
||||
*(rp + 2) = save;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 6)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 4);
|
||||
*(rp + 4) = save;
|
||||
save = *(rp + 1);
|
||||
*(rp + 1) = *(rp + 5);
|
||||
*(rp + 5) = save;
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += 8)
|
||||
{
|
||||
png_byte save = *rp;
|
||||
*rp = *(rp + 4);
|
||||
*(rp + 4) = save;
|
||||
save = *(rp + 1);
|
||||
*(rp + 1) = *(rp + 5);
|
||||
*(rp + 5) = save;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
|
||||
|
||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
|
||||
defined(PNG_LEGACY_SUPPORTED)
|
||||
void PNGAPI
|
||||
png_set_user_transform_info(png_structp png_ptr, png_voidp
|
||||
user_transform_ptr, int user_transform_depth, int user_transform_channels)
|
||||
{
|
||||
png_debug(1, "in png_set_user_transform_info\n");
|
||||
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
|
||||
png_ptr->user_transform_ptr = user_transform_ptr;
|
||||
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
|
||||
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
|
||||
#else
|
||||
if(user_transform_ptr || user_transform_depth || user_transform_channels)
|
||||
png_warning(png_ptr,
|
||||
"This version of libpng does not support user transform info");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function returns a pointer to the user_transform_ptr associated with
|
||||
* the user transform functions. The application should free any memory
|
||||
* associated with this pointer before png_write_destroy and png_read_destroy
|
||||
* are called.
|
||||
*/
|
||||
png_voidp PNGAPI
|
||||
png_get_user_transform_ptr(png_structp png_ptr)
|
||||
{
|
||||
#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
|
||||
return ((png_voidp)png_ptr->user_transform_ptr);
|
||||
#else
|
||||
if(png_ptr)
|
||||
return (NULL);
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
3903
libpng/pngvcrd.c
3903
libpng/pngvcrd.c
File diff suppressed because it is too large
Load Diff
228
libpng/pngwio.c
228
libpng/pngwio.c
|
@ -1,228 +0,0 @@
|
|||
|
||||
/* pngwio.c - functions for data output
|
||||
*
|
||||
* libpng 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*
|
||||
* This file provides a location for all output. Users who need
|
||||
* special handling are expected to write functions that have the same
|
||||
* arguments as these and perform similar functions, but that possibly
|
||||
* use different output methods. Note that you shouldn't change these
|
||||
* functions, but rather write replacement functions and then change
|
||||
* them at run time with png_set_write_fn(...).
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
|
||||
/* Write the data to whatever output you are using. The default routine
|
||||
writes to a file pointer. Note that this routine sometimes gets called
|
||||
with very small lengths, so you should implement some kind of simple
|
||||
buffering if you are using unbuffered writes. This should never be asked
|
||||
to write more than 64K on a 16 bit machine. */
|
||||
|
||||
void /* PRIVATE */
|
||||
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
if (png_ptr->write_data_fn != NULL )
|
||||
(*(png_ptr->write_data_fn))(png_ptr, data, length);
|
||||
else
|
||||
png_error(png_ptr, "Call to NULL write function");
|
||||
}
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
/* This is the function that does the actual writing of data. If you are
|
||||
not writing to a standard C stream, you should create a replacement
|
||||
write_data function and use it at run time with png_set_write_fn(), rather
|
||||
than changing the library. */
|
||||
#ifndef USE_FAR_KEYWORD
|
||||
void PNGAPI
|
||||
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_uint_32 check;
|
||||
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
|
||||
check = 0;
|
||||
#else
|
||||
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
|
||||
#endif
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Write Error");
|
||||
}
|
||||
#else
|
||||
/* this is the model-independent version. Since the standard I/O library
|
||||
can't handle far buffers in the medium and small models, we have to copy
|
||||
the data.
|
||||
*/
|
||||
|
||||
#define NEAR_BUF_SIZE 1024
|
||||
#define MIN(a,b) (a <= b ? a : b)
|
||||
|
||||
void PNGAPI
|
||||
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
png_uint_32 check;
|
||||
png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
|
||||
png_FILE_p io_ptr;
|
||||
|
||||
/* Check if data really is near. If so, use usual code. */
|
||||
near_data = (png_byte *)CVT_PTR_NOCHECK(data);
|
||||
io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
|
||||
if ((png_bytep)near_data == data)
|
||||
{
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
|
||||
check = 0;
|
||||
#else
|
||||
check = fwrite(near_data, 1, length, io_ptr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
png_byte buf[NEAR_BUF_SIZE];
|
||||
png_size_t written, remaining, err;
|
||||
check = 0;
|
||||
remaining = length;
|
||||
do
|
||||
{
|
||||
written = MIN(NEAR_BUF_SIZE, remaining);
|
||||
png_memcpy(buf, data, written); /* copy far buffer to near buffer */
|
||||
#if defined(_WIN32_WCE)
|
||||
if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
|
||||
err = 0;
|
||||
#else
|
||||
err = fwrite(buf, 1, written, io_ptr);
|
||||
#endif
|
||||
if (err != written)
|
||||
break;
|
||||
else
|
||||
check += err;
|
||||
data += written;
|
||||
remaining -= written;
|
||||
}
|
||||
while (remaining != 0);
|
||||
}
|
||||
if (check != length)
|
||||
png_error(png_ptr, "Write Error");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function is called to output any data pending writing (normally
|
||||
to disk). After png_flush is called, there should be no data pending
|
||||
writing in any buffers. */
|
||||
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||
void /* PRIVATE */
|
||||
png_flush(png_structp png_ptr)
|
||||
{
|
||||
if (png_ptr->output_flush_fn != NULL)
|
||||
(*(png_ptr->output_flush_fn))(png_ptr);
|
||||
}
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
void PNGAPI
|
||||
png_default_flush(png_structp png_ptr)
|
||||
{
|
||||
#if !defined(_WIN32_WCE)
|
||||
png_FILE_p io_ptr;
|
||||
io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
|
||||
if (io_ptr != NULL)
|
||||
fflush(io_ptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This function allows the application to supply new output functions for
|
||||
libpng if standard C streams aren't being used.
|
||||
|
||||
This function takes as its arguments:
|
||||
png_ptr - pointer to a png output data structure
|
||||
io_ptr - pointer to user supplied structure containing info about
|
||||
the output functions. May be NULL.
|
||||
write_data_fn - pointer to a new output function that takes as its
|
||||
arguments a pointer to a png_struct, a pointer to
|
||||
data to be written, and a 32-bit unsigned int that is
|
||||
the number of bytes to be written. The new write
|
||||
function should call png_error(png_ptr, "Error msg")
|
||||
to exit and output any fatal error messages.
|
||||
flush_data_fn - pointer to a new flush function that takes as its
|
||||
arguments a pointer to a png_struct. After a call to
|
||||
the flush function, there should be no data in any buffers
|
||||
or pending transmission. If the output method doesn't do
|
||||
any buffering of ouput, a function prototype must still be
|
||||
supplied although it doesn't have to do anything. If
|
||||
PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
|
||||
time, output_flush_fn will be ignored, although it must be
|
||||
supplied for compatibility. */
|
||||
void PNGAPI
|
||||
png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
|
||||
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
|
||||
{
|
||||
png_ptr->io_ptr = io_ptr;
|
||||
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
if (write_data_fn != NULL)
|
||||
png_ptr->write_data_fn = write_data_fn;
|
||||
else
|
||||
png_ptr->write_data_fn = png_default_write_data;
|
||||
#else
|
||||
png_ptr->write_data_fn = write_data_fn;
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
|
||||
#if !defined(PNG_NO_STDIO)
|
||||
if (output_flush_fn != NULL)
|
||||
png_ptr->output_flush_fn = output_flush_fn;
|
||||
else
|
||||
png_ptr->output_flush_fn = png_default_flush;
|
||||
#else
|
||||
png_ptr->output_flush_fn = output_flush_fn;
|
||||
#endif
|
||||
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
|
||||
|
||||
/* It is an error to read while writing a png file */
|
||||
if (png_ptr->read_data_fn != NULL)
|
||||
{
|
||||
png_ptr->read_data_fn = NULL;
|
||||
png_warning(png_ptr,
|
||||
"Attempted to set both read_data_fn and write_data_fn in");
|
||||
png_warning(png_ptr,
|
||||
"the same structure. Resetting read_data_fn to NULL.");
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_FAR_KEYWORD)
|
||||
#if defined(_MSC_VER)
|
||||
void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
|
||||
{
|
||||
void *near_ptr;
|
||||
void FAR *far_ptr;
|
||||
FP_OFF(near_ptr) = FP_OFF(ptr);
|
||||
far_ptr = (void FAR *)near_ptr;
|
||||
if(check != 0)
|
||||
if(FP_SEG(ptr) != FP_SEG(far_ptr))
|
||||
png_error(png_ptr,"segment lost in conversion");
|
||||
return(near_ptr);
|
||||
}
|
||||
# else
|
||||
void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
|
||||
{
|
||||
void *near_ptr;
|
||||
void FAR *far_ptr;
|
||||
near_ptr = (void FAR *)ptr;
|
||||
far_ptr = (void FAR *)near_ptr;
|
||||
if(check != 0)
|
||||
if(far_ptr != ptr)
|
||||
png_error(png_ptr,"segment lost in conversion");
|
||||
return(near_ptr);
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
#endif /* PNG_WRITE_SUPPORTED */
|
1464
libpng/pngwrite.c
1464
libpng/pngwrite.c
File diff suppressed because it is too large
Load Diff
|
@ -1,563 +0,0 @@
|
|||
|
||||
/* pngwtran.c - transforms the data in a row for PNG writers
|
||||
*
|
||||
* libpng version 1.2.8 - December 3, 2004
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 1998-2004 Glenn Randers-Pehrson
|
||||
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
|
||||
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
|
||||
*/
|
||||
|
||||
#define PNG_INTERNAL
|
||||
#include "png.h"
|
||||
#ifdef PNG_WRITE_SUPPORTED
|
||||
|
||||
/* Transform the data according to the user's wishes. The order of
|
||||
* transformations is significant.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_write_transformations(png_structp png_ptr)
|
||||
{
|
||||
png_debug(1, "in png_do_write_transformations\n");
|
||||
|
||||
if (png_ptr == NULL)
|
||||
return;
|
||||
|
||||
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_USER_TRANSFORM)
|
||||
if(png_ptr->write_user_transform_fn != NULL)
|
||||
(*(png_ptr->write_user_transform_fn)) /* user write transform function */
|
||||
(png_ptr, /* png_ptr */
|
||||
&(png_ptr->row_info), /* row_info: */
|
||||
/* png_uint_32 width; width of row */
|
||||
/* png_uint_32 rowbytes; number of bytes in row */
|
||||
/* png_byte color_type; color type of pixels */
|
||||
/* png_byte bit_depth; bit depth of samples */
|
||||
/* png_byte channels; number of channels (1-4) */
|
||||
/* png_byte pixel_depth; bits per pixel (depth*channels) */
|
||||
png_ptr->row_buf + 1); /* start of pixel data for row */
|
||||
#endif
|
||||
#if defined(PNG_WRITE_FILLER_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_FILLER)
|
||||
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
png_ptr->flags);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_PACKSWAP)
|
||||
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_PACK)
|
||||
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
(png_uint_32)png_ptr->bit_depth);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_SWAP_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_SWAP_BYTES)
|
||||
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_SHIFT)
|
||||
png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
|
||||
&(png_ptr->shift));
|
||||
#endif
|
||||
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_INVERT_ALPHA)
|
||||
png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_SWAP_ALPHA)
|
||||
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_BGR_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_BGR)
|
||||
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
#if defined(PNG_WRITE_INVERT_SUPPORTED)
|
||||
if (png_ptr->transformations & PNG_INVERT_MONO)
|
||||
png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
|
||||
* row_info bit depth should be 8 (one pixel per byte). The channels
|
||||
* should be 1 (this only happens on grayscale and paletted images).
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_pack\n");
|
||||
if (row_info->bit_depth == 8 &&
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
row != NULL && row_info != NULL &&
|
||||
#endif
|
||||
row_info->channels == 1)
|
||||
{
|
||||
switch ((int)bit_depth)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int mask, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
mask = 0x80;
|
||||
v = 0;
|
||||
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
if (*sp != 0)
|
||||
v |= mask;
|
||||
sp++;
|
||||
if (mask > 1)
|
||||
mask >>= 1;
|
||||
else
|
||||
{
|
||||
mask = 0x80;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
if (mask != 0x80)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int shift, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
shift = 6;
|
||||
v = 0;
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_byte value;
|
||||
|
||||
value = (png_byte)(*sp & 0x03);
|
||||
v |= (value << shift);
|
||||
if (shift == 0)
|
||||
{
|
||||
shift = 6;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
else
|
||||
shift -= 2;
|
||||
sp++;
|
||||
}
|
||||
if (shift != 6)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
int shift, v;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
sp = row;
|
||||
dp = row;
|
||||
shift = 4;
|
||||
v = 0;
|
||||
for (i = 0; i < row_width; i++)
|
||||
{
|
||||
png_byte value;
|
||||
|
||||
value = (png_byte)(*sp & 0x0f);
|
||||
v |= (value << shift);
|
||||
|
||||
if (shift == 0)
|
||||
{
|
||||
shift = 4;
|
||||
*dp = (png_byte)v;
|
||||
dp++;
|
||||
v = 0;
|
||||
}
|
||||
else
|
||||
shift -= 4;
|
||||
|
||||
sp++;
|
||||
}
|
||||
if (shift != 4)
|
||||
*dp = (png_byte)v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
row_info->bit_depth = (png_byte)bit_depth;
|
||||
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
|
||||
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
|
||||
row_info->width);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
|
||||
/* Shift pixel values to take advantage of whole range. Pass the
|
||||
* true number of bits in bit_depth. The row should be packed
|
||||
* according to row_info->bit_depth. Thus, if you had a row of
|
||||
* bit depth 4, but the pixels only had values from 0 to 7, you
|
||||
* would pass 3 as bit_depth, and this routine would translate the
|
||||
* data to 0 to 15.
|
||||
*/
|
||||
void /* PRIVATE */
|
||||
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
|
||||
{
|
||||
png_debug(1, "in png_do_shift\n");
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row != NULL && row_info != NULL &&
|
||||
#else
|
||||
if (
|
||||
#endif
|
||||
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
int shift_start[4], shift_dec[4];
|
||||
int channels = 0;
|
||||
|
||||
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->red;
|
||||
shift_dec[channels] = bit_depth->red;
|
||||
channels++;
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->green;
|
||||
shift_dec[channels] = bit_depth->green;
|
||||
channels++;
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
|
||||
shift_dec[channels] = bit_depth->blue;
|
||||
channels++;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
|
||||
shift_dec[channels] = bit_depth->gray;
|
||||
channels++;
|
||||
}
|
||||
if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
|
||||
{
|
||||
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
|
||||
shift_dec[channels] = bit_depth->alpha;
|
||||
channels++;
|
||||
}
|
||||
|
||||
/* with low row depths, could only be grayscale, so one channel */
|
||||
if (row_info->bit_depth < 8)
|
||||
{
|
||||
png_bytep bp = row;
|
||||
png_uint_32 i;
|
||||
png_byte mask;
|
||||
png_uint_32 row_bytes = row_info->rowbytes;
|
||||
|
||||
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
|
||||
mask = 0x55;
|
||||
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
|
||||
mask = 0x11;
|
||||
else
|
||||
mask = 0xff;
|
||||
|
||||
for (i = 0; i < row_bytes; i++, bp++)
|
||||
{
|
||||
png_uint_16 v;
|
||||
int j;
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & mask);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep bp = row;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = channels * row_info->width;
|
||||
|
||||
for (i = 0; i < istop; i++, bp++)
|
||||
{
|
||||
|
||||
png_uint_16 v;
|
||||
int j;
|
||||
int c = (int)(i%channels);
|
||||
|
||||
v = *bp;
|
||||
*bp = 0;
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
if (j > 0)
|
||||
*bp |= (png_byte)((v << j) & 0xff);
|
||||
else
|
||||
*bp |= (png_byte)((v >> (-j)) & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
png_bytep bp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 istop = channels * row_info->width;
|
||||
|
||||
for (bp = row, i = 0; i < istop; i++)
|
||||
{
|
||||
int c = (int)(i%channels);
|
||||
png_uint_16 value, v;
|
||||
int j;
|
||||
|
||||
v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
|
||||
value = 0;
|
||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
||||
{
|
||||
if (j > 0)
|
||||
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
|
||||
else
|
||||
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
|
||||
}
|
||||
*bp++ = (png_byte)(value >> 8);
|
||||
*bp++ = (png_byte)(value & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
void /* PRIVATE */
|
||||
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_swap_alpha\n");
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row != NULL && row_info != NULL)
|
||||
#endif
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This converts from ARGB to RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AARRGGBB to RRGGBBAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save[2];
|
||||
save[0] = *(sp++);
|
||||
save[1] = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save[0];
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This converts from AG to GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save;
|
||||
}
|
||||
}
|
||||
/* This converts from AAGG to GGAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
png_byte save[2];
|
||||
save[0] = *(sp++);
|
||||
save[1] = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = save[0];
|
||||
*(dp++) = save[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
||||
void /* PRIVATE */
|
||||
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_invert_alpha\n");
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row != NULL && row_info != NULL)
|
||||
#endif
|
||||
{
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in RGBA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in RRGGBBAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
{
|
||||
/* This inverts the alpha channel in GA */
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
/* This inverts the alpha channel in GGAA */
|
||||
else
|
||||
{
|
||||
png_bytep sp, dp;
|
||||
png_uint_32 i;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
|
||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
||||
{
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = *(sp++);
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
*(dp++) = (png_byte)(255 - *(sp++));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_MNG_FEATURES_SUPPORTED)
|
||||
/* undoes intrapixel differencing */
|
||||
void /* PRIVATE */
|
||||
png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
|
||||
{
|
||||
png_debug(1, "in png_do_write_intrapixel\n");
|
||||
if (
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
row != NULL && row_info != NULL &&
|
||||
#endif
|
||||
(row_info->color_type & PNG_COLOR_MASK_COLOR))
|
||||
{
|
||||
int bytes_per_pixel;
|
||||
png_uint_32 row_width = row_info->width;
|
||||
if (row_info->bit_depth == 8)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
bytes_per_pixel = 3;
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
bytes_per_pixel = 4;
|
||||
else
|
||||
return;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
|
||||
{
|
||||
*(rp) = (png_byte)((*rp - *(rp+1))&0xff);
|
||||
*(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
|
||||
}
|
||||
}
|
||||
else if (row_info->bit_depth == 16)
|
||||
{
|
||||
png_bytep rp;
|
||||
png_uint_32 i;
|
||||
|
||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
||||
bytes_per_pixel = 6;
|
||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
bytes_per_pixel = 8;
|
||||
else
|
||||
return;
|
||||
|
||||
for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
|
||||
{
|
||||
png_uint_32 s0 = (*(rp ) << 8) | *(rp+1);
|
||||
png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3);
|
||||
png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5);
|
||||
png_uint_32 red = (png_uint_32)((s0-s1) & 0xffffL);
|
||||
png_uint_32 blue = (png_uint_32)((s2-s1) & 0xffffL);
|
||||
*(rp ) = (png_byte)((red >> 8) & 0xff);
|
||||
*(rp+1) = (png_byte)(red & 0xff);
|
||||
*(rp+4) = (png_byte)((blue >> 8) & 0xff);
|
||||
*(rp+5) = (png_byte)(blue & 0xff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* PNG_MNG_FEATURES_SUPPORTED */
|
||||
#endif /* PNG_WRITE_SUPPORTED */
|
2730
libpng/pngwutil.c
2730
libpng/pngwutil.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,190 @@
|
|||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
NOTE: This source is derived from an old version taken from the GNU C
|
||||
Library (glibc).
|
||||
|
||||
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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined __STDC__ || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#define GETOPT_INTERFACE_VERSION 2
|
||||
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
|
||||
#include <gnu-versions.h>
|
||||
#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
|
||||
#define ELIDE_CODE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ELIDE_CODE
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* Not ELIDE_CODE. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
Loading…
Reference in New Issue