Some fixes to image resize and Color constructors

--HG--
branch : dev
This commit is contained in:
Martín Lucas Golini
2019-08-11 18:16:21 -03:00
parent cc5d5a7630
commit 78a66ea0fa
5 changed files with 53 additions and 67 deletions

View File

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

View File

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

View File

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

View File

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

View File

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