tahoma2d/toonz/sources/stdfx/igs_warp_hori.cpp
2023-02-25 20:59:02 -05:00

94 lines
3.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <cmath>
#include <vector>
#include <limits> /* std::numeric_limits */
#include "igs_ifx_common.h"
#include "igs_warp.h"
namespace {
void hori_change_(float* image, const int height, const int width,
const int channels,
const float* refer, // same as height,width,channels
const int refchannels, const int refcc, const double maxlen,
const bool alpha_rendering_sw, const bool anti_aliasing_sw) {
std::vector<std::vector<float>> buf_s(channels);
for (int zz = 0; zz < channels; ++zz) {
buf_s.at(zz).resize(width);
}
std::vector<double> buf_r(width);
refer += refcc; /* 参照画像の参照色チャンネル */
for (int yy = 0; yy < height;
++yy, image += channels * width, refer += refchannels * width) {
// buf_s縺ォSource縺ョ繧ケ繧ュ繝」繝ウ繝ゥ繧、繝ウ縺ョ繝斐け繧サ繝ォ蛟、繧偵繧後
for (int xx = 0; xx < width; ++xx) {
for (int zz = 0; zz < channels; ++zz) {
buf_s.at(zz).at(xx) = image[xx * channels + zz];
}
}
// buf_r縺ォ蜿ら・逕サ蜒上・謖・ョ壹メ繝」繝ウ繝阪Ν縺ョ蛟、繧貞・繧後
for (int xx = 0; xx < width; ++xx) { // reference red of refer[]
float pos = refer[xx * refchannels];
// clamp 0.f to 1.f in case using TPixelF
pos = std::min(1.f, std::max(0.f, pos));
buf_r.at(xx) = (pos - 0.5f) * maxlen;
}
if (anti_aliasing_sw) {
for (int xx = 0; xx < width; ++xx) {
float pos = buf_r.at(xx);
int fl_pos = xx + static_cast<int>(std::floor(pos));
int ce_pos = xx + static_cast<int>(std::ceil(pos));
float div = pos - floor(pos);
// clamp
if (fl_pos < 0)
fl_pos = 0;
else if (width <= fl_pos)
fl_pos = width - 1;
if (ce_pos < 0)
ce_pos = 0;
else if (width <= ce_pos)
ce_pos = width - 1;
for (int zz = 0; zz < channels; ++zz) {
if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
image[xx * channels + zz] = buf_s.at(zz).at(xx);
} else {
image[xx * channels + zz] = buf_s.at(zz).at(fl_pos) * (1.0 - div) +
buf_s.at(zz).at(ce_pos) * div;
}
}
}
} else {
for (int xx = 0; xx < width; ++xx) {
int pos = xx + static_cast<int>(floor(buf_r.at(xx) + 0.5));
// clamp
if (pos < 0)
pos = 0;
else if (width <= pos)
pos = width - 1;
for (int zz = 0; zz < channels; ++zz) {
if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
image[xx * channels + zz] = buf_s.at(zz).at(xx);
} else {
image[xx * channels + zz] = buf_s.at(zz).at(pos);
}
}
}
}
}
}
} // namespace
//--------------------------------------------------------------------
void igs::warp::hori_change(float* image, const int height, const int width,
const int channels,
const float* refer, // by height,width,channels
const int refchannels, const int refcc,
const double maxlen, const bool alpha_rendering_sw,
const bool anti_aliasing_sw) {
hori_change_(image, height, width, channels, refer, refchannels, refcc,
maxlen, alpha_rendering_sw, anti_aliasing_sw);
}