|
Shinya Kitaoka |
120a6e |
#include <vector> // std::vector</vector>
|
|
Shinya Kitaoka |
120a6e |
#include <cmath> // cos(),sin(),sqrt()</cmath>
|
|
Shinya Kitaoka |
120a6e |
#include <limits> // std::numeric_limits<t></t></limits>
|
|
Shinya Kitaoka |
120a6e |
#include <stdexcept> // std::domain_error()</stdexcept>
|
|
Toshihiro Shimizu |
890ddd |
#include "igs_ifx_common.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "igs_radial_blur.h"
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class radial_ {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
radial_(const T *in_top, const int height, const int width,
|
|
Shinya Kitaoka |
120a6e |
const int channels, const double xc, const double yc,
|
|
Shinya Kitaoka |
120a6e |
const double sub_size, const int imax, const double dmax,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 平均値ぼかし強度 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
)
|
|
Shinya Kitaoka |
120a6e |
: in_top_(in_top)
|
|
Shinya Kitaoka |
120a6e |
, hh_(height)
|
|
Shinya Kitaoka |
120a6e |
, ww_(width)
|
|
Shinya Kitaoka |
120a6e |
, cc_(channels)
|
|
Shinya Kitaoka |
120a6e |
, xc_(xc)
|
|
Shinya Kitaoka |
120a6e |
, yc_(yc)
|
|
Shinya Kitaoka |
120a6e |
, sub_size_(sub_size)
|
|
Shinya Kitaoka |
120a6e |
, imax_(imax)
|
|
Shinya Kitaoka |
120a6e |
, dmax_(dmax)
|
|
Shinya Kitaoka |
120a6e |
, intensity_(intensity)
|
|
Shinya Kitaoka |
120a6e |
, radius_(radius) {}
|
|
Shinya Kitaoka |
120a6e |
void pixel_value(const T *in_current_pixel, const int xx, const int yy,
|
|
Shinya Kitaoka |
120a6e |
const int z1, const int z2, const double ref_increase_val,
|
|
Shinya Kitaoka |
120a6e |
const double ref_decrease_val,
|
|
Shinya Kitaoka |
120a6e |
const double each_pixel_blur_ratio, T *result_pixel) {
|
|
Shinya Kitaoka |
120a6e |
/* Pixel位置(0.5 1.5 2.5 ...) */
|
|
Shinya Kitaoka |
120a6e |
const double xp = static_cast<double>(xx) + 0.5;</double>
|
|
Shinya Kitaoka |
120a6e |
const double yp = static_cast<double>(yy) + 0.5;</double>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からPixel位置へのベクトルと長さ */
|
|
Shinya Kitaoka |
120a6e |
const double xv = xp - this->xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yv = yp - this->yc_;
|
|
Shinya Kitaoka |
120a6e |
const double dist = sqrt(xv * xv + yv * yv);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 指定半径の範囲内なら何もしない */
|
|
Shinya Kitaoka |
120a6e |
if (dist <= this->radius_) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = in_current_pixel[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からPixel位置への単位ベクトル */
|
|
Shinya Kitaoka |
120a6e |
const double cosval = xv / dist;
|
|
Shinya Kitaoka |
120a6e |
const double sinval = yv / dist;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Radial方向のSamplingの開始位置と終了位置 */
|
|
Shinya Kitaoka |
120a6e |
double scale = this->intensity_;
|
|
Shinya Kitaoka |
120a6e |
if (0.0 <= each_pixel_blur_ratio) {
|
|
Shinya Kitaoka |
120a6e |
scale *= each_pixel_blur_ratio;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
const double length = (dist - this->radius_) * scale;
|
|
Shinya Kitaoka |
120a6e |
const double count_half = floor(length / 2.0 / this->sub_size_);
|
|
Shinya Kitaoka |
120a6e |
const double sub_sta = -this->sub_size_ * count_half;
|
|
Shinya Kitaoka |
120a6e |
const double sub_end = this->sub_size_ * count_half;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 積算値と積算回数 */
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> accum_val(this->cc_);</double>
|
|
Shinya Kitaoka |
120a6e |
int accum_counter = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 円周接線方向Samplingの相対位置 */
|
|
Shinya Kitaoka |
120a6e |
for (double ss = this->sub_size_ / 2.0 - 0.5; ss < 0.5;
|
|
Shinya Kitaoka |
120a6e |
ss += this->sub_size_) {
|
|
Shinya Kitaoka |
120a6e |
/* 円周接線方向Sampling位置 */
|
|
Shinya Kitaoka |
120a6e |
const double xps = xp + ss * sinval;
|
|
Shinya Kitaoka |
120a6e |
const double yps = yp + ss * cosval;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からSampling位置へのベクトルと長さ */
|
|
Shinya Kitaoka |
120a6e |
const double xvs = xps - this->xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yvs = yps - this->yc_;
|
|
Shinya Kitaoka |
120a6e |
const double dists = sqrt(xvs * xvs + yvs * yvs);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からSampling位置への単位ベクトル */
|
|
Shinya Kitaoka |
120a6e |
const double cosvals = xvs / dists;
|
|
Shinya Kitaoka |
120a6e |
const double sinvals = yvs / dists;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Radial方向のSampling */
|
|
Shinya Kitaoka |
120a6e |
for (double tt = sub_sta; tt <= sub_end; tt += this->sub_size_) {
|
|
Shinya Kitaoka |
120a6e |
/* Sampling位置からPixel位置を得る */
|
|
Shinya Kitaoka |
120a6e |
int xi = static_cast<int>(xps + tt * cosvals);</int>
|
|
Shinya Kitaoka |
120a6e |
int yi = static_cast<int>(yps + tt * sinvals);</int>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* clamp */
|
|
Shinya Kitaoka |
120a6e |
xi = (xi < 0) ? 0 : ((this->ww_ <= xi) ? this->ww_ - 1 : xi);
|
|
Shinya Kitaoka |
120a6e |
yi = (yi < 0) ? 0 : ((this->hh_ <= yi) ? this->hh_ - 1 : yi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 画像のPixel位置 */
|
|
Shinya Kitaoka |
120a6e |
const T *in_current =
|
|
Shinya Kitaoka |
120a6e |
this->in_top_ + this->cc_ * this->ww_ * yi + this->cc_ * xi;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 積算 */
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] += static_cast<double>(in_current[zz]);</double>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++accum_counter;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* 積算しなかったとき(念のためのCheck) */
|
|
Shinya Kitaoka |
120a6e |
if (accum_counter <= 0) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = in_current_pixel[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* ここで画像Pixelに保存 */
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] /= static_cast<double>(accum_counter);</double>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= ref_increase_val) && (in_current_pixel[zz] < accum_val[zz])) {
|
|
Shinya Kitaoka |
120a6e |
/* 増分のみMask! */
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] =
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(in_current_pixel[zz]) +</double>
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] - in_current_pixel[zz]) * ref_increase_val;
|
|
Shinya Kitaoka |
120a6e |
} else if ((0 <= ref_decrease_val) &&
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] < in_current_pixel[zz])) {
|
|
Shinya Kitaoka |
120a6e |
/* 減分のみMask! */
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] =
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(in_current_pixel[zz]) +</double>
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] - in_current_pixel[zz]) * ref_decrease_val;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] += 0.5; /* 誤差対策 */
|
|
Shinya Kitaoka |
120a6e |
if (this->dmax_ < accum_val[zz]) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = static_cast<t>(this->imax_);</t>
|
|
Shinya Kitaoka |
120a6e |
} else if (accum_val[zz] < 0) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = 0;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = static_cast<t>(accum_val[zz]);</t>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
radial_() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const T *in_top_;
|
|
Shinya Kitaoka |
120a6e |
const int hh_;
|
|
Shinya Kitaoka |
120a6e |
const int ww_;
|
|
Shinya Kitaoka |
120a6e |
const int cc_;
|
|
Shinya Kitaoka |
120a6e |
const double xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yc_;
|
|
Shinya Kitaoka |
120a6e |
const double sub_size_;
|
|
Shinya Kitaoka |
120a6e |
const int imax_;
|
|
Shinya Kitaoka |
120a6e |
const double dmax_;
|
|
Shinya Kitaoka |
120a6e |
const double intensity_;
|
|
Shinya Kitaoka |
120a6e |
const double radius_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* copy constructorを無効化 */
|
|
Shinya Kitaoka |
120a6e |
radial_(const radial_ &);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 代入演算子を無効化 */
|
|
Shinya Kitaoka |
120a6e |
radial_ &operator=(const radial_ &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" it,="" rt=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void radial_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
const IT *in, const int margin /* 参照画像(in)がもつ余白 */
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const RT *ref /* 求める画像(out)と同じ高さ、幅、チャンネル数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_bits, const int ref_mode // R,G,B,A,luminance
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
IT *out, const int hh /* 求める画像(out)の高さ */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ww /* 求める画像(out)の幅 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int cc, const double xc, const double yc,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 強度。ゼロより大きく2以下 */
|
|
Shinya Kitaoka |
120a6e |
/* radius円境界での平均値ぼかしゼロとするためintensityは2より小さい */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int sub_div /* 1ならJaggy、2以上はAntialias */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const bool alpha_rendering_sw) {
|
|
Shinya Kitaoka |
120a6e |
ref_bits; // for warning
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 強度のないとき、または、サブ分割がないとき、なにもしない */
|
|
Shinya Kitaoka |
120a6e |
if (intensity <= 0.0 || sub_div <= 0) {
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
radial_<it> cl_ra(</it>
|
|
Shinya Kitaoka |
120a6e |
in, hh + margin * 2, ww + margin * 2, cc, xc + margin, yc + margin,
|
|
Shinya Kitaoka |
120a6e |
1.0 / sub_div, std::numeric_limits<it>::max() /* サンプリング値 */</it>
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(std::numeric_limits<it>::max()), intensity, radius);</it></double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined RGBA_ORDER_OF_TOONZ6
|
|
Shinya Kitaoka |
120a6e |
const int z1 = igs::image::rgba::blu;
|
|
Shinya Kitaoka |
120a6e |
const int z2 = igs::image::rgba::red;
|
|
Toshihiro Shimizu |
890ddd |
#elif defined RGBA_ORDER_OF_OPENGL
|
|
Shinya Kitaoka |
120a6e |
const int z1 = igs::image::rgba::red;
|
|
Shinya Kitaoka |
120a6e |
const int z2 = igs::image::rgba::blu;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
Must be define / DRGBA_ORDER_OF_TOONZ6 or
|
|
Shinya Kitaoka |
120a6e |
/ DRGBA_ORDER_OF_OPENGL
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
const IT *p_in = in + margin * (ww + margin * 2) * cc + margin * cc;
|
|
Shinya Kitaoka |
120a6e |
IT *pout = out;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (0 == ref) { /* 参照なし */
|
|
Shinya Kitaoka |
120a6e |
if (igs::image::rgba::siz == cc) {
|
|
Shinya Kitaoka |
120a6e |
using namespace igs::image::rgba;
|
|
Shinya Kitaoka |
120a6e |
if (alpha_rendering_sw) { /* Alphaも処理する */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, alp, alp, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, z1, z2, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alpha処理しない、RGB増分をAlphaでMaskする */
|
|
Shinya Kitaoka |
120a6e |
const unsigned int val_max = std::numeric_limits<it>::max();</it>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
pout[alp] = p_in[alp];
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* Alpha値あるならRGB増分のみAlphaでMaskする */
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, z1, z2,
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(p_in[alp]) / val_max, -1.0,</double>
|
|
Shinya Kitaoka |
120a6e |
-1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alphaがない, RGB/Grayscale... */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin; ++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, 0, cc - 1, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* 参照あり */
|
|
Shinya Kitaoka |
120a6e |
const RT *refe = ref;
|
|
Shinya Kitaoka |
120a6e |
const int r_max = std::numeric_limits<rt>::max();</rt>
|
|
Shinya Kitaoka |
120a6e |
if (igs::image::rgba::siz == cc) {
|
|
Shinya Kitaoka |
120a6e |
using namespace igs::image::rgba;
|
|
Shinya Kitaoka |
120a6e |
if (alpha_rendering_sw) { /* Alpha処理する */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv =
|
|
Shinya Kitaoka |
120a6e |
igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, alp, alp, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, z1, z2, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alpha処理しない、RGB増分をAlphaでMaskする */
|
|
Shinya Kitaoka |
120a6e |
const unsigned int val_max = std::numeric_limits<it>::max();</it>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv =
|
|
Shinya Kitaoka |
120a6e |
igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pout[alp] = p_in[alp];
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, z1, z2,
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(p_in[alp]) / val_max, -1.0,</double>
|
|
Shinya Kitaoka |
120a6e |
refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alphaがない, RGB/Grayscale... */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv = igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cl_ra.pixel_value(p_in, xx, yy, 0, cc - 1, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
class twist_ {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
twist_(const int height, const double xc, const double yc,
|
|
Shinya Kitaoka |
120a6e |
const double twist_radian, const double twist_radius)
|
|
Shinya Kitaoka |
120a6e |
: xc_(xc)
|
|
Shinya Kitaoka |
120a6e |
, yc_(yc)
|
|
Shinya Kitaoka |
120a6e |
, twist_xp_(0)
|
|
Shinya Kitaoka |
120a6e |
, twist_yp_(0)
|
|
Shinya Kitaoka |
120a6e |
, twist_radian_(twist_radian)
|
|
Shinya Kitaoka |
120a6e |
, twist_radius_(twist_radius)
|
|
Shinya Kitaoka |
120a6e |
, current_xp_(0)
|
|
Shinya Kitaoka |
120a6e |
, current_yp_(0)
|
|
Shinya Kitaoka |
120a6e |
, current_radian_(0)
|
|
Shinya Kitaoka |
120a6e |
, current_cos_(0)
|
|
Shinya Kitaoka |
120a6e |
, current_sin_(0)
|
|
Shinya Kitaoka |
120a6e |
, current_radius_(0) {
|
|
Shinya Kitaoka |
120a6e |
/* twist_radiusは、Twist曲線上半径1のPixel画像上半径 */
|
|
Shinya Kitaoka |
120a6e |
/* twist_radiusはゼロのとき、高さの半分を設定する */
|
|
Shinya Kitaoka |
120a6e |
if (this->twist_radius_ <= 0.0) {
|
|
Shinya Kitaoka |
120a6e |
this->twist_radius_ = height / 2.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* ゼロだと計算不能になる */
|
|
Shinya Kitaoka |
120a6e |
if (this->twist_radius_ <= 0.0) {
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("twist_radius is equal less than zero");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void current_pos(const double xp, const double yp) {
|
|
Shinya Kitaoka |
120a6e |
/* 現在位置 */
|
|
Shinya Kitaoka |
120a6e |
this->current_xp_ = xp;
|
|
Shinya Kitaoka |
120a6e |
this->current_yp_ = yp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からの距離 */
|
|
Shinya Kitaoka |
120a6e |
const double xv = xp - this->xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yv = yp - this->yc_;
|
|
Shinya Kitaoka |
120a6e |
this->current_radius_ = sqrt(xv * xv + yv * yv);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 基準からの距離比 */
|
|
Shinya Kitaoka |
120a6e |
const double tt = this->current_radius_ / this->twist_radius_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Twist曲線上の位置 */
|
|
Shinya Kitaoka |
120a6e |
const double xx = tt * cos(tt * this->twist_radian_);
|
|
Shinya Kitaoka |
120a6e |
const double yy = tt * sin(tt * this->twist_radian_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Twist曲線の回転角度 */
|
|
Shinya Kitaoka |
120a6e |
this->current_radian_ = atan2(yv, xv) - atan2(yy, xx);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Twist曲線上の位置を回転角度に傾けた位置 */
|
|
Shinya Kitaoka |
120a6e |
this->current_cos_ = cos(this->current_radian_);
|
|
Shinya Kitaoka |
120a6e |
this->current_sin_ = sin(this->current_radian_);
|
|
Shinya Kitaoka |
120a6e |
this->twist_xp_ = xx * this->current_cos_ - yy * this->current_sin_;
|
|
Shinya Kitaoka |
120a6e |
this->twist_yp_ = xx * this->current_sin_ + yy * this->current_cos_;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
void twist_pos(const double pixel_pos, int &xi, int &yi) {
|
|
Shinya Kitaoka |
120a6e |
/* 基準半径からの比 */
|
|
Shinya Kitaoka |
120a6e |
const double tt = (this->current_radius_ + pixel_pos) / this->twist_radius_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Twist曲線上の比による位置 */
|
|
Shinya Kitaoka |
120a6e |
const double xx = tt * cos(tt * this->twist_radian_);
|
|
Shinya Kitaoka |
120a6e |
const double yy = tt * sin(tt * this->twist_radian_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* その位置の角度に傾ける */
|
|
Shinya Kitaoka |
120a6e |
double x2 = xx * this->current_cos_ - yy * this->current_sin_;
|
|
Shinya Kitaoka |
120a6e |
double y2 = xx * this->current_sin_ + yy * this->current_cos_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Twist曲線上の位置の差 */
|
|
Shinya Kitaoka |
120a6e |
x2 = (x2 - this->twist_xp_);
|
|
Shinya Kitaoka |
120a6e |
y2 = (y2 - this->twist_yp_);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Pixel画像上の位置の差 */
|
|
Shinya Kitaoka |
120a6e |
x2 *= this->twist_radius_;
|
|
Shinya Kitaoka |
120a6e |
y2 *= this->twist_radius_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Pixel画像上の位置 */
|
|
Shinya Kitaoka |
120a6e |
x2 += this->current_xp_;
|
|
Shinya Kitaoka |
120a6e |
y2 += this->current_yp_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
xi = static_cast<int>(x2);</int>
|
|
Shinya Kitaoka |
120a6e |
yi = static_cast<int>(y2);</int>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
twist_();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const double xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yc_;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double twist_xp_;
|
|
Shinya Kitaoka |
120a6e |
double twist_yp_;
|
|
Shinya Kitaoka |
120a6e |
double twist_radian_;
|
|
Shinya Kitaoka |
120a6e |
double twist_radius_;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double current_xp_;
|
|
Shinya Kitaoka |
120a6e |
double current_yp_;
|
|
Shinya Kitaoka |
120a6e |
double current_radian_;
|
|
Shinya Kitaoka |
120a6e |
double current_cos_;
|
|
Shinya Kitaoka |
120a6e |
double current_sin_;
|
|
Shinya Kitaoka |
120a6e |
double current_radius_;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* copy constructorを無効化 */
|
|
Shinya Kitaoka |
120a6e |
twist_(const twist_ &);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/* 代入演算子を無効化 */
|
|
Shinya Kitaoka |
120a6e |
twist_ &operator=(const twist_ &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class radial_twist_ {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
radial_twist_(const T *in_top, const int height /* 求める画像(out)の高さ */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int width /* 求める画像(out)の幅 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int channels, const double xc, const double yc,
|
|
Shinya Kitaoka |
120a6e |
const double sub_size, const int imax, const double dmax,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 平均値ぼかし強度 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double twist_radian, const double twist_radius)
|
|
Shinya Kitaoka |
120a6e |
: in_top_(in_top)
|
|
Shinya Kitaoka |
120a6e |
, hh_(height)
|
|
Shinya Kitaoka |
120a6e |
, ww_(width)
|
|
Shinya Kitaoka |
120a6e |
, cc_(channels)
|
|
Shinya Kitaoka |
120a6e |
, xc_(xc)
|
|
Shinya Kitaoka |
120a6e |
, yc_(yc)
|
|
Shinya Kitaoka |
120a6e |
, sub_size_(sub_size)
|
|
Shinya Kitaoka |
120a6e |
, imax_(imax)
|
|
Shinya Kitaoka |
120a6e |
, dmax_(dmax)
|
|
Shinya Kitaoka |
120a6e |
, intensity_(intensity)
|
|
Shinya Kitaoka |
120a6e |
, radius_(radius)
|
|
Shinya Kitaoka |
120a6e |
, cl_tw_(height, xc, yc, twist_radian, twist_radius) {}
|
|
Shinya Kitaoka |
120a6e |
void pixel_value(const T *in_current_pixel, const int xx, const int yy,
|
|
Shinya Kitaoka |
120a6e |
const int z1, const int z2, const double ref_increase_val,
|
|
Shinya Kitaoka |
120a6e |
const double ref_decrease_val,
|
|
Shinya Kitaoka |
120a6e |
const double each_pixel_blur_ratio, T *result_pixel) {
|
|
Shinya Kitaoka |
120a6e |
/* Pixel位置(0.5 1.5 2.5 ...) */
|
|
Shinya Kitaoka |
120a6e |
const double xp = static_cast<double>(xx) + 0.5;</double>
|
|
Shinya Kitaoka |
120a6e |
const double yp = static_cast<double>(yy) + 0.5;</double>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 中心からPixel位置へのベクトルと長さ */
|
|
Shinya Kitaoka |
120a6e |
const double xv = xp - this->xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yv = yp - this->yc_;
|
|
Shinya Kitaoka |
120a6e |
const double dist = sqrt(xv * xv + yv * yv);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 指定半径の範囲内なら何もしない */
|
|
Shinya Kitaoka |
120a6e |
if (dist <= this->radius_) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = in_current_pixel[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Radial方向のSamplingの開始位置と終了位置 */
|
|
Shinya Kitaoka |
120a6e |
double scale = this->intensity_;
|
|
Shinya Kitaoka |
120a6e |
if (0.0 <= each_pixel_blur_ratio) {
|
|
Shinya Kitaoka |
120a6e |
scale *= each_pixel_blur_ratio;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
const double length = (dist - this->radius_) * scale;
|
|
Shinya Kitaoka |
120a6e |
const double count_half = floor(length / 2.0 / this->sub_size_);
|
|
Shinya Kitaoka |
120a6e |
const double sub_sta = -this->sub_size_ * count_half;
|
|
Shinya Kitaoka |
120a6e |
const double sub_end = this->sub_size_ * count_half;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 積算値と積算回数 */
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> accum_val(this->cc_);</double>
|
|
Shinya Kitaoka |
120a6e |
int accum_counter = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* SubPixelによるSamplingの相対位置 */
|
|
Shinya Kitaoka |
120a6e |
for (double xsub = this->sub_size_ / 2.0 - 0.5; xsub < 0.5;
|
|
Shinya Kitaoka |
120a6e |
xsub += this->sub_size_) {
|
|
Shinya Kitaoka |
120a6e |
for (double ysub = this->sub_size_ / 2.0 - 0.5; ysub < 0.5;
|
|
Shinya Kitaoka |
120a6e |
ysub += this->sub_size_) {
|
|
Shinya Kitaoka |
120a6e |
/* Sampling位置をセット */
|
|
Shinya Kitaoka |
120a6e |
this->cl_tw_.current_pos(xp + xsub, yp + ysub);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* Radial&Twist方向のSampling */
|
|
Shinya Kitaoka |
120a6e |
for (double tt = sub_sta; tt <= sub_end; tt += this->sub_size_) {
|
|
Shinya Kitaoka |
120a6e |
/* Sampling位置からPixel位置を得る */
|
|
Shinya Kitaoka |
120a6e |
int xi = 0;
|
|
Shinya Kitaoka |
120a6e |
int yi = 0;
|
|
Shinya Kitaoka |
120a6e |
this->cl_tw_.twist_pos(tt, xi, yi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* clamp */
|
|
Shinya Kitaoka |
120a6e |
xi = (xi < 0) ? 0 : ((this->ww_ <= xi) ? this->ww_ - 1 : xi);
|
|
Shinya Kitaoka |
120a6e |
yi = (yi < 0) ? 0 : ((this->hh_ <= yi) ? this->hh_ - 1 : yi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 画像のPixel位置 */
|
|
Shinya Kitaoka |
120a6e |
const T *in_current =
|
|
Shinya Kitaoka |
120a6e |
this->in_top_ + this->cc_ * this->ww_ * yi + this->cc_ * xi;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 積算 */
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] += static_cast<double>(in_current[zz]);</double>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++accum_counter;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* 積算しなかったとき(念のためのCheck) */
|
|
Shinya Kitaoka |
120a6e |
if (accum_counter <= 0) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = in_current_pixel[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/* ここで画像Pixelに保存 */
|
|
Shinya Kitaoka |
120a6e |
for (int zz = z1; zz <= z2; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] /= static_cast<double>(accum_counter);</double>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((0 <= ref_increase_val) && (in_current_pixel[zz] < accum_val[zz])) {
|
|
Shinya Kitaoka |
120a6e |
/* 増分のみMask! */
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] =
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(in_current_pixel[zz]) +</double>
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] - in_current_pixel[zz]) * ref_increase_val;
|
|
Shinya Kitaoka |
120a6e |
} else if ((0 <= ref_decrease_val) &&
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] < in_current_pixel[zz])) {
|
|
Shinya Kitaoka |
120a6e |
/* 減分のみMask! */
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] =
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(in_current_pixel[zz]) +</double>
|
|
Shinya Kitaoka |
120a6e |
(accum_val[zz] - in_current_pixel[zz]) * ref_decrease_val;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
accum_val[zz] += 0.5; /* 誤差対策 */
|
|
Shinya Kitaoka |
120a6e |
if (this->dmax_ < accum_val[zz]) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = static_cast<t>(this->imax_);</t>
|
|
Shinya Kitaoka |
120a6e |
} else if (accum_val[zz] < 0) {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = 0;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
result_pixel[zz] = static_cast<t>(accum_val[zz]);</t>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
radial_twist_() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const T *in_top_;
|
|
Shinya Kitaoka |
120a6e |
const int hh_;
|
|
Shinya Kitaoka |
120a6e |
const int ww_;
|
|
Shinya Kitaoka |
120a6e |
const int cc_;
|
|
Shinya Kitaoka |
120a6e |
const double xc_;
|
|
Shinya Kitaoka |
120a6e |
const double yc_;
|
|
Shinya Kitaoka |
120a6e |
const double sub_size_;
|
|
Shinya Kitaoka |
120a6e |
const int imax_;
|
|
Shinya Kitaoka |
120a6e |
const double dmax_;
|
|
Shinya Kitaoka |
120a6e |
const double intensity_;
|
|
Shinya Kitaoka |
120a6e |
const double radius_;
|
|
Shinya Kitaoka |
120a6e |
twist_ cl_tw_;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* copy constructorを無効化 */
|
|
Shinya Kitaoka |
120a6e |
radial_twist_(const radial_twist_ &);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 代入演算子を無効化 */
|
|
Shinya Kitaoka |
120a6e |
radial_twist_ &operator=(const radial_twist_ &);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" it,="" rt=""></class>
|
|
Toshihiro Shimizu |
890ddd |
void twist_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
const IT *in, const int margin /* 参照画像(in)がもつ余白 */
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const RT *ref /* 求める画像(out)と同じ高さ、幅、チャンネル数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_bits, const int ref_mode // R,G,B,A,luminance
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
IT *out, const int hh /* 求める画像(out)の高さ */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ww /* 求める画像(out)の幅 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int cc, const double xc, const double yc, const double twist_radian,
|
|
Shinya Kitaoka |
120a6e |
const double twist_radius,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 強度。ゼロより大きく2以下 */
|
|
Shinya Kitaoka |
120a6e |
/* radius円境界での平均値ぼかしゼロとするためintensityは2より小さい */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int sub_div /* 1ならJaggy、2以上はAntialias */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const bool alpha_rendering_sw) {
|
|
Shinya Kitaoka |
120a6e |
ref_bits; // for warning
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 強度のないとき、または、サブ分割がないとき、なにもしない */
|
|
Shinya Kitaoka |
120a6e |
if (intensity <= 0.0 || sub_div <= 0) {
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
radial_twist_<it> cl_ratw(in, hh + margin * 2, ww + margin * 2, cc,</it>
|
|
Shinya Kitaoka |
120a6e |
xc + margin, yc + margin, 1.0 / sub_div,
|
|
Shinya Kitaoka |
120a6e |
std::numeric_limits<it>::max(),</it>
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(std::numeric_limits<it>::max()),</it></double>
|
|
Shinya Kitaoka |
120a6e |
intensity, radius, twist_radian, twist_radius);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined RGBA_ORDER_OF_TOONZ6
|
|
Shinya Kitaoka |
120a6e |
const int z1 = igs::image::rgba::blu;
|
|
Shinya Kitaoka |
120a6e |
const int z2 = igs::image::rgba::red;
|
|
Toshihiro Shimizu |
890ddd |
#elif defined RGBA_ORDER_OF_OPENGL
|
|
Shinya Kitaoka |
120a6e |
const int z1 = igs::image::rgba::red;
|
|
Shinya Kitaoka |
120a6e |
const int z2 = igs::image::rgba::blu;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
Must be define / DRGBA_ORDER_OF_TOONZ6 or
|
|
Shinya Kitaoka |
120a6e |
/ DRGBA_ORDER_OF_OPENGL
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
const IT *p_in = in + margin * (ww + margin * 2) * cc + margin * cc;
|
|
Shinya Kitaoka |
120a6e |
IT *pout = out;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (0 == ref) { /* 参照なし */
|
|
Shinya Kitaoka |
120a6e |
if (igs::image::rgba::siz == cc) {
|
|
Shinya Kitaoka |
120a6e |
using namespace igs::image::rgba;
|
|
Shinya Kitaoka |
120a6e |
if (alpha_rendering_sw) { /* Alphaも処理する */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, alp, alp, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, z1, z2, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alpha処理しない、RGB増分をAlphaでMaskする */
|
|
Shinya Kitaoka |
120a6e |
const unsigned int val_max = std::numeric_limits<it>::max();</it>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
pout[alp] = p_in[alp];
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, z1, z2,
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(p_in[alp]) / val_max, -1.0,</double>
|
|
Shinya Kitaoka |
120a6e |
-1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alphaがない, RGB/Grayscale... */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin; ++xx, p_in += cc, pout += cc) {
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, 0, cc - 1, -1.0, -1.0, -1.0, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* 参照あり */
|
|
Shinya Kitaoka |
120a6e |
const RT *refe = ref;
|
|
Shinya Kitaoka |
120a6e |
const int r_max = std::numeric_limits<rt>::max();</rt>
|
|
Shinya Kitaoka |
120a6e |
if (igs::image::rgba::siz == cc) {
|
|
Shinya Kitaoka |
120a6e |
using namespace igs::image::rgba;
|
|
Shinya Kitaoka |
120a6e |
if (alpha_rendering_sw) { /* Alphaも処理する */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv =
|
|
Shinya Kitaoka |
120a6e |
igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, alp, alp, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, z1, z2, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alpha処理しない、RGB増分をAlphaでMaskする */
|
|
Shinya Kitaoka |
120a6e |
const unsigned int val_max = std::numeric_limits<it>::max();</it>
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv =
|
|
Shinya Kitaoka |
120a6e |
igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pout[alp] = p_in[alp];
|
|
Shinya Kitaoka |
120a6e |
if (0 == pout[alp]) {
|
|
Shinya Kitaoka |
120a6e |
pout[red] = p_in[red];
|
|
Shinya Kitaoka |
120a6e |
pout[gre] = p_in[gre];
|
|
Shinya Kitaoka |
120a6e |
pout[blu] = p_in[blu];
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, z1, z2,
|
|
Shinya Kitaoka |
120a6e |
static_cast<double>(p_in[alp]) / val_max, -1.0,</double>
|
|
Shinya Kitaoka |
120a6e |
refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* Alphaがない, RGB/Grayscale... */
|
|
Shinya Kitaoka |
120a6e |
for (int yy = margin; yy < hh + margin; ++yy, p_in += 2 * margin * cc) {
|
|
Shinya Kitaoka |
120a6e |
for (int xx = margin; xx < ww + margin;
|
|
Shinya Kitaoka |
120a6e |
++xx, p_in += cc, pout += cc, refe += cc) {
|
|
Shinya Kitaoka |
120a6e |
const double refv = igs::color::ref_value(refe, cc, r_max, ref_mode);
|
|
Shinya Kitaoka |
120a6e |
if (0 == refv) {
|
|
Shinya Kitaoka |
120a6e |
for (int zz = 0; zz < cc; ++zz) {
|
|
Shinya Kitaoka |
120a6e |
pout[zz] = p_in[zz];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cl_ratw.pixel_value(p_in, xx, yy, 0, cc - 1, -1.0, -1.0, refv, pout);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
void igs::radial_blur::convert(
|
|
Shinya Kitaoka |
120a6e |
const unsigned char *in, const int margin /* 参照画像(in)がもつ余白 */
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const unsigned char *ref /* outと同じ高さ、幅、チャンネル数 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int ref_bits, const int ref_mode // R,G,B,A,luminance
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
unsigned char *out
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int height /* 求める画像(out)の高さ */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int width /* 求める画像(out)の幅 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int channels, const int bits
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double xc, const double yc, const double twist_radian,
|
|
Shinya Kitaoka |
120a6e |
const double twist_radius
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Toshihiro Shimizu |
890ddd |
Twist Radius
|
|
Shinya Kitaoka |
120a6e |
ひねりの基準半径を指定します。
|
|
Shinya Kitaoka |
120a6e |
単位はミリメートルです。
|
|
Shinya Kitaoka |
120a6e |
最小は0。最大1000mm(1m)です。
|
|
Shinya Kitaoka |
120a6e |
初期値は0でひねりはありません。
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 強度。ゼロより大きく2以下 */
|
|
Shinya Kitaoka |
120a6e |
/* radius円境界での平均値ぼかしゼロとするためintensityは2より小さい */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int sub_div /* 1ならJaggy、2以上はAntialias */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const bool alpha_rendering_sw) {
|
|
Shinya Kitaoka |
120a6e |
if ((igs::image::rgba::siz != channels) &&
|
|
Shinya Kitaoka |
120a6e |
(igs::image::rgb::siz != channels) && (1 != channels) /* bit(monoBW) */
|
|
Shinya Kitaoka |
120a6e |
) {
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("Bad channels,Not rgba/rgb/grayscale");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((std::numeric_limits<unsigned char="">::digits != bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<unsigned short="">::digits != bits)) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("Bad in bits,Not uchar/ushort");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if ((0 != ref) && (std::numeric_limits<unsigned char="">::digits != ref_bits) &&</unsigned>
|
|
Shinya Kitaoka |
120a6e |
(std::numeric_limits<unsigned short="">::digits != ref_bits)) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
throw std::domain_error("Bad ref bits,Not uchar/ushort");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 強度のないとき、または、サブ分割がないとき */
|
|
Shinya Kitaoka |
120a6e |
if (intensity <= 0.0 || sub_div <= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
igs::image::copy_except_margin(in, margin, out, height, width, channels);
|
|
Shinya Kitaoka |
120a6e |
} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
igs::image::copy_except_margin(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in), margin,</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out), height, width, channels);</unsigned>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (0.0 == twist_radian) {
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == ref_bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
radial_convert_template_(in, margin, ref, ref_bits, ref_mode, out,
|
|
Shinya Kitaoka |
120a6e |
height, width, channels, xc, yc, intensity,
|
|
Shinya Kitaoka |
120a6e |
radius, sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
radial_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in), margin, ref, ref_bits,</const>
|
|
Shinya Kitaoka |
120a6e |
ref_mode, reinterpret_cast<unsigned *="" short="">(out), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, xc, yc, intensity, radius, sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* ref_bitsがゼロでも(refがなくても)ここにくる */
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
radial_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
in, margin, reinterpret_cast<const *="" short="" unsigned="">(ref), ref_bits,</const>
|
|
Shinya Kitaoka |
120a6e |
ref_mode, out, height, width, channels, xc, yc, intensity, radius,
|
|
Shinya Kitaoka |
120a6e |
sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
radial_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in), margin,</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(ref), ref_bits, ref_mode,</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out), height, width, channels,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
xc, yc, intensity, radius, sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == ref_bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
twist_convert_template_(in, margin, ref, ref_bits, ref_mode, out,
|
|
Shinya Kitaoka |
120a6e |
height, width, channels, xc, yc, twist_radian,
|
|
Shinya Kitaoka |
120a6e |
twist_radius, intensity, radius, sub_div,
|
|
Shinya Kitaoka |
120a6e |
alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
twist_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in), margin, ref, ref_bits,</const>
|
|
Shinya Kitaoka |
120a6e |
ref_mode, reinterpret_cast<unsigned *="" short="">(out), height, width,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
channels, xc, yc, twist_radian, twist_radius, intensity, radius,
|
|
Shinya Kitaoka |
120a6e |
sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else { /* ref_bitsがゼロでも(refがなくても)ここにくる */
|
|
Shinya Kitaoka |
120a6e |
if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
twist_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
in, margin, reinterpret_cast<const *="" short="" unsigned="">(ref), ref_bits,</const>
|
|
Shinya Kitaoka |
120a6e |
ref_mode, out, height, width, channels, xc, yc, twist_radian,
|
|
Shinya Kitaoka |
120a6e |
twist_radius, intensity, radius, sub_div, alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
|
|
Shinya Kitaoka |
120a6e |
twist_convert_template_(
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(in), margin,</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<const *="" short="" unsigned="">(ref), ref_bits, ref_mode,</const>
|
|
Shinya Kitaoka |
120a6e |
reinterpret_cast<unsigned *="" short="">(out), height, width, channels,</unsigned>
|
|
Shinya Kitaoka |
120a6e |
xc, yc, twist_radian, twist_radius, intensity, radius, sub_div,
|
|
Shinya Kitaoka |
120a6e |
alpha_rendering_sw);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
#if 0 //-------------------- comment out start ------------------------
|
|
Toshihiro Shimizu |
890ddd |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
double enlarge_margin_length_(
|
|
Toshihiro Shimizu |
890ddd |
const double xc
|
|
Toshihiro Shimizu |
890ddd |
,const double yc
|
|
Toshihiro Shimizu |
890ddd |
,const double xp
|
|
Toshihiro Shimizu |
890ddd |
,const double yp
|
|
Toshihiro Shimizu |
890ddd |
,const double intensity
|
|
Toshihiro Shimizu |
890ddd |
,const double radius
|
|
Toshihiro Shimizu |
890ddd |
,const double sub_size
|
|
Toshihiro Shimizu |
890ddd |
) {
|
|
Toshihiro Shimizu |
890ddd |
const double xv = xp - xc;
|
|
Toshihiro Shimizu |
890ddd |
const double yv = yp - yc;
|
|
Toshihiro Shimizu |
890ddd |
const double dist = sqrt(xv*xv + yv*yv);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* "dist = len - (len - radius) * intensity / 2.0;"より */
|
|
Toshihiro Shimizu |
890ddd |
const double len = (2.0 * dist - radius * intensity) /
|
|
Toshihiro Shimizu |
890ddd |
(2.0-intensity);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/***const double length = (len - radius) * intensity;
|
|
Toshihiro Shimizu |
890ddd |
const double count_half = floor(length / sub_size);
|
|
Toshihiro Shimizu |
890ddd |
return sub_size * count_half;***/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (len <= radius) { return 0; }
|
|
Toshihiro Shimizu |
890ddd |
return (len - radius) * intensity / 2.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
int igs::radial_blur::enlarge_margin( /* Twist時は正確ではない... */
|
|
Toshihiro Shimizu |
890ddd |
const int height
|
|
Toshihiro Shimizu |
890ddd |
,const int width
|
|
Toshihiro Shimizu |
890ddd |
,const double xc
|
|
Toshihiro Shimizu |
890ddd |
,const double yc
|
|
Toshihiro Shimizu |
890ddd |
,const double twist_radian
|
|
Toshihiro Shimizu |
890ddd |
,const double twist_radius
|
|
Toshihiro Shimizu |
890ddd |
,const double intensity/* 強度。ゼロより大きく2以下 */
|
|
Toshihiro Shimizu |
890ddd |
/* radius円境界での平均値ぼかしゼロとするためintensityは2より小さい */
|
|
Toshihiro Shimizu |
890ddd |
,const double radius /* 平均値ぼかしの始まる半径 */
|
|
Toshihiro Shimizu |
890ddd |
,const int sub_div /* 1ならJaggy、2以上はAntialias */
|
|
Toshihiro Shimizu |
890ddd |
) {
|
|
Toshihiro Shimizu |
890ddd |
/* 強度のないとき、2以上のとき、または、サブ分割がないとき、
|
|
Toshihiro Shimizu |
890ddd |
なにもしない */
|
|
Toshihiro Shimizu |
890ddd |
if (intensity <= 0.0 || 2.0 <= intensity || sub_div <= 0) {
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double margin1 = 0;
|
|
Toshihiro Shimizu |
890ddd |
double margin2 = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
margin1 = enlarge_margin_length_(
|
|
Toshihiro Shimizu |
890ddd |
xc,yc,-width/2.0,-height/2.0,intensity,radius,1.0/sub_div);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
margin2 = enlarge_margin_length_(
|
|
Toshihiro Shimizu |
890ddd |
xc,yc,-width/2.0, height/2.0,intensity,radius,1.0/sub_div);
|
|
Toshihiro Shimizu |
890ddd |
if (margin1 < margin2) { margin1 = margin2; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
margin2 = enlarge_margin_length_(
|
|
Toshihiro Shimizu |
890ddd |
xc,yc, width/2.0,-height/2.0,intensity,radius,1.0/sub_div);
|
|
Toshihiro Shimizu |
890ddd |
if (margin1 < margin2) { margin1 = margin2; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
margin2 = enlarge_margin_length_(
|
|
Toshihiro Shimizu |
890ddd |
xc,yc, width/2.0, height/2.0,intensity,radius,1.0/sub_div);
|
|
Toshihiro Shimizu |
890ddd |
if (margin1 < margin2) { margin1 = margin2; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return static_cast<int>(ceil(margin1));</int>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
#endif //-------------------- comment out end -------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
double reference_margin_length_(const double xc, const double yc,
|
|
Shinya Kitaoka |
120a6e |
const double xp, const double yp,
|
|
Shinya Kitaoka |
120a6e |
const double intensity, const double radius,
|
|
Shinya Kitaoka |
120a6e |
const double sub_size) {
|
|
Shinya Kitaoka |
120a6e |
const double xv = xp - xc;
|
|
Shinya Kitaoka |
120a6e |
const double yv = yp - yc;
|
|
Shinya Kitaoka |
120a6e |
const double dist = sqrt(xv * xv + yv * yv);
|
|
Shinya Kitaoka |
120a6e |
if (dist <= radius) {
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
const double half_length = (dist - radius) * intensity / 2.0;
|
|
Shinya Kitaoka |
120a6e |
const double count_half = floor(half_length / sub_size);
|
|
Shinya Kitaoka |
120a6e |
return sub_size * count_half;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
int igs::radial_blur::
|
|
Shinya Kitaoka |
120a6e |
reference_margin(/* Twist時は正確ではない... */
|
|
Shinya Kitaoka |
120a6e |
const int height, const int width, const double xc,
|
|
Shinya Kitaoka |
120a6e |
const double yc, const double twist_radian,
|
|
Shinya Kitaoka |
120a6e |
const double twist_radius,
|
|
Shinya Kitaoka |
120a6e |
const double intensity /* 強度。ゼロより大きく2以下 */
|
|
Shinya Kitaoka |
120a6e |
/* radius円境界での平均値ぼかしゼロとするためintensityは2より小さい
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const double radius /* 平均値ぼかしの始まる半径 */
|
|
Shinya Kitaoka |
120a6e |
,
|
|
Shinya Kitaoka |
120a6e |
const int sub_div /* 1ならJaggy、2以上はAntialias */
|
|
Shinya Kitaoka |
120a6e |
) {
|
|
Shinya Kitaoka |
120a6e |
twist_radius; // for warning
|
|
Shinya Kitaoka |
120a6e |
twist_radian; // for warning
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* 強度のないとき、2以上のとき、または、サブ分割がないとき、
|
|
Shinya Kitaoka |
120a6e |
なにもしない */
|
|
Shinya Kitaoka |
120a6e |
if (intensity <= 0.0 || 2.0 <= intensity || sub_div <= 0) {
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double margin1 = 0;
|
|
Shinya Kitaoka |
120a6e |
double margin2 = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
四隅から参照する外部への最大マージンを計算する
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
margin1 = reference_margin_length_(xc, yc, -width / 2.0, -height / 2.0,
|
|
Shinya Kitaoka |
120a6e |
intensity, radius, 1.0 / sub_div);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
margin2 = reference_margin_length_(xc, yc, -width / 2.0, height / 2.0,
|
|
Shinya Kitaoka |
120a6e |
intensity, radius, 1.0 / sub_div);
|
|
Shinya Kitaoka |
120a6e |
if (margin1 < margin2) {
|
|
Shinya Kitaoka |
120a6e |
margin1 = margin2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
margin2 = reference_margin_length_(xc, yc, width / 2.0, -height / 2.0,
|
|
Shinya Kitaoka |
120a6e |
intensity, radius, 1.0 / sub_div);
|
|
Shinya Kitaoka |
120a6e |
if (margin1 < margin2) {
|
|
Shinya Kitaoka |
120a6e |
margin1 = margin2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
margin2 = reference_margin_length_(xc, yc, width / 2.0, height / 2.0,
|
|
Shinya Kitaoka |
120a6e |
intensity, radius, 1.0 / sub_div);
|
|
Shinya Kitaoka |
120a6e |
if (margin1 < margin2) {
|
|
Shinya Kitaoka |
120a6e |
margin1 = margin2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return static_cast<int>(ceil(margin1));</int>
|
|
Toshihiro Shimizu |
890ddd |
}
|