image: remove broken downsample code
This commit is contained in:
parent
77a94e227a
commit
97a4e3af1a
156
image.cpp
156
image.cpp
@ -21,101 +21,6 @@
|
|||||||
using util::image::buffer;
|
using util::image::buffer;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
struct box {
|
|
||||||
static constexpr float support = 0.5f;
|
|
||||||
|
|
||||||
static constexpr float weight [[gnu::pure]] (float x)
|
|
||||||
{
|
|
||||||
return (x >= -0.5f && x <= 0.5f) ? 1.f : 0.f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// XXX: Known to cause hard black ringing
|
|
||||||
template <size_t S>
|
|
||||||
struct lanczos {
|
|
||||||
static constexpr float support = float {S};
|
|
||||||
|
|
||||||
static float weight [[gnu::pure]] (float x)
|
|
||||||
{
|
|
||||||
if (x < 0.f)
|
|
||||||
x = -x;
|
|
||||||
|
|
||||||
if (x <= S)
|
|
||||||
return sincn (x) * sincn (x / S);
|
|
||||||
|
|
||||||
return 0.f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template struct lanczos< 3>;
|
|
||||||
template struct lanczos< 4>;
|
|
||||||
template struct lanczos< 6>;
|
|
||||||
template struct lanczos<12>;
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
struct bspline {
|
|
||||||
static constexpr float support = 2.f;
|
|
||||||
|
|
||||||
static float weight [[gnu::pure]] (float x)
|
|
||||||
{
|
|
||||||
if (x < 0.f)
|
|
||||||
x = -x;
|
|
||||||
|
|
||||||
if (x < 1.f)
|
|
||||||
return .5f * x * x * x - x * x + (2.f / 3.f);
|
|
||||||
|
|
||||||
if (x < 2.f) {
|
|
||||||
x = 2.f - x;
|
|
||||||
return (1.f / 6.f) * x * x * x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0.f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// XXX: Known to cause hard black ringing
|
|
||||||
struct mitchell {
|
|
||||||
static constexpr float support = 2.f;
|
|
||||||
|
|
||||||
static float weight [[gnu::pure]] (float x)
|
|
||||||
{
|
|
||||||
return eval (x, 1.f / 3.f, 1.f / 3.f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
static float eval (float x, float B, float C)
|
|
||||||
{
|
|
||||||
if (x < 0.f)
|
|
||||||
x = -x;
|
|
||||||
|
|
||||||
if (x < 1.f) {
|
|
||||||
x = ( 12.f - 9.f * B - 6.f * C) * x * x * x
|
|
||||||
+ (-18.f + 12.f * B + 6.f * C) * x * x
|
|
||||||
+ 6.f - 2.f * B;
|
|
||||||
|
|
||||||
return x / 6.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x < 2.f) {
|
|
||||||
x = ( -1.f * B - 6.f * C) * x * x * x
|
|
||||||
+ ( 6.f * B + 30.f * C) * x * x
|
|
||||||
+ (-12.f * B - 48.f * C) * x
|
|
||||||
+ 8.f * B + 24.f * C;
|
|
||||||
|
|
||||||
return x / 6.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0.f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::image::buffer<T>::buffer (util::extent2u _size):
|
util::image::buffer<T>::buffer (util::extent2u _size):
|
||||||
@ -192,67 +97,6 @@ util::image::buffer<T>::clone (void) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// HACK: This code hasn't really been tested with multiple filters (it is
|
|
||||||
// known to produce dark ringing artefacts with sinc) or robustly with
|
|
||||||
// fractional factors. But... it works more or less.
|
|
||||||
template <typename T>
|
|
||||||
util::image::buffer<T>
|
|
||||||
util::image::buffer<T>::downsample (float factor) const
|
|
||||||
{
|
|
||||||
CHECK_GE (factor, 0);
|
|
||||||
|
|
||||||
using filter = bspline;
|
|
||||||
|
|
||||||
const buffer &src = *this;
|
|
||||||
buffer dst (static_cast<size_t> (w / factor),
|
|
||||||
static_cast<size_t> (h / factor));
|
|
||||||
|
|
||||||
const float scale = float (dst.w) / src.w;
|
|
||||||
const float half_width = filter::support / scale;
|
|
||||||
const int half_pixels = int (std::ceil (half_width));
|
|
||||||
|
|
||||||
// Calculate the weighted sum of the src pixels for each dst pixel
|
|
||||||
for (size_t d_y = 0; d_y < dst.h; ++d_y)
|
|
||||||
for (size_t d_x = 0; d_x < dst.w; ++d_x) {
|
|
||||||
// Initialise value and weight sums
|
|
||||||
float v = 0.f;
|
|
||||||
float m = 0.f;
|
|
||||||
|
|
||||||
// Find the centre of the src pixel
|
|
||||||
float o_y = (d_y + 0.5f) / scale;
|
|
||||||
float o_x = (d_x + 0.5f) / scale;
|
|
||||||
|
|
||||||
// Do a full summation across the window. This isn't using
|
|
||||||
// seperable filtering because:
|
|
||||||
// a) we need high precision with fractional factors
|
|
||||||
// b) it's much easier to implement as is
|
|
||||||
//
|
|
||||||
// TODO: seperable filters
|
|
||||||
for (int s_y = -half_pixels; s_y <= half_pixels; ++s_y)
|
|
||||||
for (int s_x = -half_pixels; s_x <= half_pixels; ++s_x) {
|
|
||||||
float m_x = filter::weight (s_x * scale);
|
|
||||||
float m_y = filter::weight (s_y * scale);
|
|
||||||
float m_ = m_x * m_y;
|
|
||||||
|
|
||||||
// Simple clamp to border for edges
|
|
||||||
int x = int (limit (o_x + s_x - 0.5f, 0, src.w));
|
|
||||||
int y = int (limit (o_y + s_y - 0.5f, 0, src.h));
|
|
||||||
|
|
||||||
// Collection the contribution
|
|
||||||
v += m_ * src.m_data[y * src.s + x];
|
|
||||||
m += m_;
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_NEZ (m);
|
|
||||||
|
|
||||||
dst.m_data[d_y * dst.s + d_x] = uint8_t (v / m);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
template <typename T>
|
template <typename T>
|
||||||
const T&
|
const T&
|
||||||
|
@ -47,8 +47,6 @@ namespace util { namespace image {
|
|||||||
template <typename U = T> buffer<U> clone (void) const;
|
template <typename U = T> buffer<U> clone (void) const;
|
||||||
template <typename U> buffer<U> cast (void) const { return clone<U> (); }
|
template <typename U> buffer<U> cast (void) const { return clone<U> (); }
|
||||||
|
|
||||||
buffer<T> downsample (float factor) const;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
constexpr extent2u extent (void) const;
|
constexpr extent2u extent (void) const;
|
||||||
constexpr vector2u stride (void) const;
|
constexpr vector2u stride (void) const;
|
||||||
|
Loading…
Reference in New Issue
Block a user