mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-07-18 16:52:53 +03:00
Some fixes to image resize and Color constructors
--HG-- branch : dev
This commit is contained in:
@@ -166,23 +166,23 @@ class tColor {
|
||||
}
|
||||
|
||||
tColor<T> operator+( const tColor<T>& Col ) const {
|
||||
return tColor<T>( eemin( this->r + Col.r , 255 ),
|
||||
eemin( this->g + Col.g , 255 ),
|
||||
eemin( this->b + Col.b , 255 ),
|
||||
eemin( this->a + Col.a , 255 )
|
||||
return tColor<T>( std::abs( this->r + Col.r ),
|
||||
std::abs( this->g + Col.g ),
|
||||
std::abs( this->b + Col.b ),
|
||||
std::abs( this->a + Col.a )
|
||||
);
|
||||
}
|
||||
|
||||
tColor<T> operator-( const tColor<T>& Col ) const {
|
||||
return tColor<T>( eemax( this->r - Col.r , 0 ),
|
||||
eemax( this->g - Col.g , 0 ),
|
||||
eemax( this->b - Col.b , 0 ),
|
||||
eemax( this->a - Col.a , 0 )
|
||||
return tColor<T>( std::abs( this->r - Col.r ),
|
||||
std::abs( this->g - Col.g ),
|
||||
std::abs( this->b - Col.b ),
|
||||
std::abs( this->a - Col.a )
|
||||
);
|
||||
}
|
||||
|
||||
tColor<T> operator*( const tColor<T>& Col ) const {
|
||||
return tColor<T>( ( this->r * Col.r / 255 ),
|
||||
return tColor<T>( ( this->r * Col.r / 255 ),
|
||||
( this->g * Col.g / 255 ),
|
||||
( this->b * Col.b / 255 ),
|
||||
( this->a * Col.a / 255 )
|
||||
|
||||
@@ -46,8 +46,7 @@ static const char * get_resampler_name( Image::ResamplerFilter filter ) {
|
||||
static unsigned char * resample_image( unsigned char* pSrc_image, int src_width, int src_height, int n, int dst_width, int dst_height, Image::ResamplerFilter filter ) {
|
||||
const int max_components = 4;
|
||||
|
||||
if ((std::max(src_width, src_height) > RESAMPLER_MAX_DIMENSION) || (n > max_components))
|
||||
{
|
||||
if ((std::max(src_width, src_height) > RESAMPLER_MAX_DIMENSION) || (n > max_components)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -69,8 +68,7 @@ static unsigned char * resample_image( unsigned char* pSrc_image, int src_width,
|
||||
const float inv_linear_to_srgb_table_size = 1.0f / linear_to_srgb_table_size;
|
||||
const float inv_source_gamma = 1.0f / source_gamma;
|
||||
|
||||
for (int i = 0; i < linear_to_srgb_table_size; ++i)
|
||||
{
|
||||
for (int i = 0; i < linear_to_srgb_table_size; ++i) {
|
||||
int k = (int)(255.0f * pow(i * inv_linear_to_srgb_table_size, inv_source_gamma) + .5f);
|
||||
if (k < 0) k = 0; else if (k > 255) k = 255;
|
||||
linear_to_srgb[i] = (unsigned char)k;
|
||||
@@ -81,8 +79,7 @@ static unsigned char * resample_image( unsigned char* pSrc_image, int src_width,
|
||||
|
||||
resamplers[0] = new Resampler(src_width, src_height, dst_width, dst_height, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, NULL, NULL, filter_scale, filter_scale);
|
||||
samples[0].resize(src_width);
|
||||
for (int i = 1; i < n; i++)
|
||||
{
|
||||
for (int i = 1; i < n; i++) {
|
||||
resamplers[i] = new Resampler(src_width, src_height, dst_width, dst_height, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, resamplers[0]->get_clist_x(), resamplers[0]->get_clist_y(), filter_scale, filter_scale);
|
||||
samples[i].resize(src_width);
|
||||
}
|
||||
@@ -93,14 +90,11 @@ static unsigned char * resample_image( unsigned char* pSrc_image, int src_width,
|
||||
const int dst_pitch = dst_width * n;
|
||||
int dst_y = 0;
|
||||
|
||||
for (int src_y = 0; src_y < src_height; src_y++)
|
||||
{
|
||||
for (int src_y = 0; src_y < src_height; src_y++) {
|
||||
const unsigned char* pSrc = &pSrc_image[src_y * src_pitch];
|
||||
|
||||
for (int x = 0; x < src_width; x++)
|
||||
{
|
||||
for (int c = 0; c < n; c++)
|
||||
{
|
||||
for (int x = 0; x < src_width; x++) {
|
||||
for (int c = 0; c < n; c++) {
|
||||
if ((c == 3) || ((n == 2) && (c == 1)))
|
||||
samples[c][x] = *pSrc++ * (1.0f/255.0f);
|
||||
else
|
||||
@@ -108,19 +102,15 @@ static unsigned char * resample_image( unsigned char* pSrc_image, int src_width,
|
||||
}
|
||||
}
|
||||
|
||||
for (int c = 0; c < n; c++)
|
||||
{
|
||||
if (!resamplers[c]->put_line(&samples[c][0]))
|
||||
{
|
||||
for (int c = 0; c < n; c++) {
|
||||
if (!resamplers[c]->put_line(&samples[c][0])) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
for ( ; ; ) {
|
||||
int c;
|
||||
for (c = 0; c < n; c++)
|
||||
{
|
||||
for (c = 0; c < n; c++) {
|
||||
const float* pOutput_samples = resamplers[c]->get_line();
|
||||
if (!pOutput_samples)
|
||||
break;
|
||||
@@ -129,16 +119,12 @@ static unsigned char * resample_image( unsigned char* pSrc_image, int src_width,
|
||||
eeASSERT(dst_y < dst_height);
|
||||
unsigned char* pDst = &dst_image[dst_y * dst_pitch + c];
|
||||
|
||||
for (int x = 0; x < dst_width; x++)
|
||||
{
|
||||
if (alpha_channel)
|
||||
{
|
||||
for (int x = 0; x < dst_width; x++) {
|
||||
if (alpha_channel) {
|
||||
int c = (int)(255.0f * pOutput_samples[x] + .5f);
|
||||
if (c < 0) c = 0; else if (c > 255) c = 255;
|
||||
*pDst = (unsigned char)c;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int j = (int)(linear_to_srgb_table_size * pOutput_samples[x] + .5f);
|
||||
if (j < 0) j = 0; else if (j >= linear_to_srgb_table_size) j = linear_to_srgb_table_size - 1;
|
||||
*pDst = linear_to_srgb[j];
|
||||
@@ -620,9 +606,9 @@ Color Image::getPixel( const unsigned int& x, const unsigned int& y ) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
void Image::setPixel(const unsigned int& x, const unsigned int& y, const Color& Color) {
|
||||
void Image::setPixel(const unsigned int& x, const unsigned int& y, const Color& color) {
|
||||
eeASSERT( !( mPixels == NULL || x > mWidth || y > mHeight ) );
|
||||
memcpy( &mPixels[ ( ( x + y * mWidth ) * mChannels ) ], &Color, mChannels );
|
||||
memcpy( &mPixels[ ( ( x + y * mWidth ) * mChannels ) ], &color, mChannels );
|
||||
}
|
||||
|
||||
void Image::create( const Uint32& Width, const Uint32& Height, const Uint32& Channels, const Color& DefaultColor, const bool& initWithDefaultColor ) {
|
||||
|
||||
@@ -256,8 +256,8 @@ const Uint8 * Texture::getPixelsPtr() {
|
||||
return Image::getPixelsPtr();
|
||||
}
|
||||
|
||||
void Texture::setPixel( const unsigned int& x, const unsigned int& y, const Color& Color ) {
|
||||
Image::setPixel( x, y, Color );
|
||||
void Texture::setPixel( const unsigned int& x, const unsigned int& y, const Color& color ) {
|
||||
Image::setPixel( x, y, color );
|
||||
|
||||
mFlags |= TEX_FLAG_MODIFIED;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ Color::Color( std::string colorString ) {
|
||||
}
|
||||
|
||||
Color::Color(Uint8 r, Uint8 g, Uint8 b, Uint8 a) :
|
||||
tColor<Uint8>(r,g,b,a)
|
||||
tColor<Uint8>(r, g, b, a)
|
||||
{}
|
||||
|
||||
Color::Color( const tRGB<Uint8>& Col ) :
|
||||
@@ -119,7 +119,7 @@ Color::Color( const tColor<Uint8> & Col, Uint8 a ) :
|
||||
{}
|
||||
|
||||
Color::Color( const tColor<Uint8>& Col ) :
|
||||
tColor<Uint8>( Col.Value )
|
||||
tColor<Uint8>( Col.r, Col.g, Col.b, Col.a )
|
||||
{}
|
||||
|
||||
Color::Color( const Uint32& Col ) :
|
||||
|
||||
50
src/thirdparty/imageresampler/resampler.cpp
vendored
50
src/thirdparty/imageresampler/resampler.cpp
vendored
@@ -14,7 +14,7 @@
|
||||
|
||||
#define resampler_assert assert
|
||||
|
||||
static inline int resampler_range_check(int v, int h) { resampler_assert((v >= 0) && (v < h)); return v; }
|
||||
static inline int resampler_range_check(int v, int h) { resampler_assert((v >= 0) && (v < h)); return v; }
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
@@ -58,15 +58,15 @@ static inline int posmod(int x, int y)
|
||||
}
|
||||
}
|
||||
|
||||
// To add your own filter, insert the new function below and update the filter table.
|
||||
// There is no need to make the filter function particularly fast, because it's
|
||||
// To add your own filter, insert the new function below and update the filter table.
|
||||
// There is no need to make the filter function particularly fast, because it's
|
||||
// only called during initializing to create the X and Y axis contributor tables.
|
||||
|
||||
#define BOX_FILTER_SUPPORT (0.5f)
|
||||
static Resample_Real box_filter(Resample_Real t) /* pulse/Fourier window */
|
||||
{
|
||||
// make_clist() calls the filter function with t inverted (pos = left, neg = right)
|
||||
if ((t >= -0.5f) && (t < 0.5f))
|
||||
if ((t >= -0.5f) && (t < 0.5f))
|
||||
return 1.0f;
|
||||
else
|
||||
return 0.0f;
|
||||
@@ -124,18 +124,18 @@ static Resample_Real B_spline_filter(Resample_Real t) /* box (*) box (*) box (*
|
||||
return (0.0f);
|
||||
}
|
||||
|
||||
// Dodgson, N., "Quadratic Interpolation for Image Resampling"
|
||||
// Dodgson, N., "Quadratic Interpolation for Image Resampling"
|
||||
#define QUADRATIC_SUPPORT 1.5f
|
||||
static Resample_Real quadratic(Resample_Real t, const Resample_Real R)
|
||||
{
|
||||
if (t < 0.0f)
|
||||
t = -t;
|
||||
t = -t;
|
||||
if (t < QUADRATIC_SUPPORT)
|
||||
{
|
||||
Resample_Real tt = t * t;
|
||||
if (t <= .5f)
|
||||
return (-2.0f * R) * tt + .5f * (R + 1.0f);
|
||||
else
|
||||
else
|
||||
return (R * tt) + (-2.0f * R - .5f) * t + (3.0f / 4.0f) * (R + 1.0f);
|
||||
}
|
||||
else
|
||||
@@ -157,10 +157,10 @@ static Resample_Real quadratic_mix_filter(Resample_Real t)
|
||||
return quadratic(t, .8f);
|
||||
}
|
||||
|
||||
// Mitchell, D. and A. Netravali, "Reconstruction Filters in Computer Graphics."
|
||||
// Mitchell, D. and A. Netravali, "Reconstruction Filters in Computer Graphics."
|
||||
// Computer Graphics, Vol. 22, No. 4, pp. 221-228.
|
||||
// (B, C)
|
||||
// (1/3, 1/3) - Defaults recommended by Mitchell and Netravali
|
||||
// (1/3, 1/3) - Defaults recommended by Mitchell and Netravali
|
||||
// (1, 0) - Equivalent to the Cubic B-Spline
|
||||
// (0, 0.5) - Equivalent to the Catmull-Rom Spline
|
||||
// (0, C) - The family of Cardinal Cubic Splines
|
||||
@@ -226,7 +226,7 @@ static Resample_Real clean(double t)
|
||||
}
|
||||
|
||||
//static double blackman_window(double x)
|
||||
//{
|
||||
//{
|
||||
// return .42f + .50f * cos(M_PI*x) + .08f * cos(2.0f*M_PI*x);
|
||||
//}
|
||||
|
||||
@@ -308,7 +308,7 @@ static Resample_Real lanczos12_filter(Resample_Real t)
|
||||
return (0.0f);
|
||||
}
|
||||
|
||||
static double bessel0(double x)
|
||||
static double bessel0(double x)
|
||||
{
|
||||
const double EPSILON_RATIO = 1E-16;
|
||||
double xh, sum, pow, ds;
|
||||
@@ -331,7 +331,7 @@ static double bessel0(double x)
|
||||
}
|
||||
|
||||
static const Resample_Real KAISER_ALPHA = 4.0;
|
||||
static double kaiser(double alpha, double half_width, double x)
|
||||
static double kaiser(double alpha, double half_width, double x)
|
||||
{
|
||||
const double ratio = (x / half_width);
|
||||
return bessel0(alpha * sqrt(1 - ratio * ratio)) / bessel0(alpha);
|
||||
@@ -346,14 +346,14 @@ static Resample_Real kaiser_filter(Resample_Real t)
|
||||
if (t < KAISER_SUPPORT)
|
||||
{
|
||||
// db atten
|
||||
const Resample_Real att = 40.0f;
|
||||
const Resample_Real att = 40.0f;
|
||||
const Resample_Real alpha = (Resample_Real)(exp(log((double)0.58417 * (att - 20.96)) * 0.4) + 0.07886 * (att - 20.96));
|
||||
//const Resample_Real alpha = KAISER_ALPHA;
|
||||
return (Resample_Real)clean(sinc(t) * kaiser(alpha, KAISER_SUPPORT, t));
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
// filters[] is a list of all the available filter functions.
|
||||
static struct
|
||||
@@ -424,7 +424,7 @@ int Resampler::reflect(const int j, const int src_x, const Boundary_Op boundary_
|
||||
return n;
|
||||
}
|
||||
|
||||
// The make_clist() method generates, for all destination samples,
|
||||
// The make_clist() method generates, for all destination samples,
|
||||
// the list of all source samples with non-zero weighted contributions.
|
||||
Resampler::Contrib_List* Resampler::make_clist(
|
||||
int src_x, int dst_x, Boundary_Op boundary_op,
|
||||
@@ -518,7 +518,7 @@ Resampler::Contrib_List* Resampler::make_clist(
|
||||
Pcontrib[i].n = 0;
|
||||
Pcontrib[i].p = Pcpool_next;
|
||||
Pcpool_next += (right - left + 1);
|
||||
resampler_assert ((Pcpool_next - Pcpool) <= n);
|
||||
//resampler_assert ((Pcpool_next - Pcpool) <= n);
|
||||
|
||||
total_weight = 0;
|
||||
|
||||
@@ -569,13 +569,13 @@ Resampler::Contrib_List* Resampler::make_clist(
|
||||
|
||||
//resampler_assert(Pcontrib[i].n);
|
||||
//resampler_assert(max_k != -1);
|
||||
if ((max_k == -1) || (Pcontrib[i].n == 0))
|
||||
if ((max_k == -1) || (Pcontrib[i].n == 0))
|
||||
{
|
||||
free(Pcpool);
|
||||
free(Pcontrib);
|
||||
free(Pcontrib_bounds);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_weight != 1.0f)
|
||||
Pcontrib[i].p[max_k].weight += 1.0f - total_weight;
|
||||
@@ -659,7 +659,7 @@ Resampler::Contrib_List* Resampler::make_clist(
|
||||
|
||||
n = reflect(j, src_x, boundary_op);
|
||||
|
||||
#if RESAMPLER_DEBUG
|
||||
#if RESAMPLER_DEBUG
|
||||
printf("%i(%f), ", n, weight);
|
||||
#endif
|
||||
|
||||
@@ -689,13 +689,13 @@ Resampler::Contrib_List* Resampler::make_clist(
|
||||
//resampler_assert(Pcontrib[i].n);
|
||||
//resampler_assert(max_k != -1);
|
||||
|
||||
if ((max_k == -1) || (Pcontrib[i].n == 0))
|
||||
if ((max_k == -1) || (Pcontrib[i].n == 0))
|
||||
{
|
||||
free(Pcpool);
|
||||
free(Pcontrib);
|
||||
free(Pcontrib_bounds);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (total_weight != 1.0f)
|
||||
Pcontrib[i].p[max_k].weight += 1.0f - total_weight;
|
||||
@@ -929,12 +929,12 @@ Resampler::~Resampler()
|
||||
printf("actual ops: %i\n", total_ops);
|
||||
#endif
|
||||
|
||||
free(m_Pdst_buf);
|
||||
free(m_Pdst_buf);
|
||||
m_Pdst_buf = NULL;
|
||||
|
||||
if (m_Ptmp_buf)
|
||||
{
|
||||
free(m_Ptmp_buf);
|
||||
free(m_Ptmp_buf);
|
||||
m_Ptmp_buf = NULL;
|
||||
}
|
||||
|
||||
@@ -977,7 +977,7 @@ void Resampler::restart()
|
||||
if (STATUS_OKAY != m_status)
|
||||
return;
|
||||
|
||||
m_cur_src_y = m_cur_dst_y = 0;
|
||||
m_cur_src_y = m_cur_dst_y = 0;
|
||||
|
||||
int i, j;
|
||||
for (i = 0; i < m_resample_src_y; i++)
|
||||
@@ -1008,7 +1008,7 @@ Resampler::Resampler(int src_x, int src_y,
|
||||
const char* Pfilter_name,
|
||||
Contrib_List* Pclist_x,
|
||||
Contrib_List* Pclist_y,
|
||||
Resample_Real filter_x_scale,
|
||||
Resample_Real filter_x_scale,
|
||||
Resample_Real filter_y_scale,
|
||||
Resample_Real src_x_ofs,
|
||||
Resample_Real src_y_ofs)
|
||||
|
||||
Reference in New Issue
Block a user