Toshihiro Shimizu 890ddd
#include <cmath></cmath>
Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
#include <limits> /* std::numeric_limits */</limits>
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h"
Toshihiro Shimizu 890ddd
#include "igs_warp.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
shun-iwasawa 481b59
void hori_change_(float* image, const int height, const int width,
shun-iwasawa 481b59
                  const int channels,
shun-iwasawa 481b59
                  const float* refer,  // same as height,width,channels
shun-iwasawa 481b59
                  const int refchannels, const int refcc, const double maxlen,
shun-iwasawa 481b59
                  const bool alpha_rendering_sw, const bool anti_aliasing_sw) {
shun-iwasawa 481b59
  std::vector<std::vector<float>> buf_s(channels);</std::vector<float>
Shinya Kitaoka 120a6e
  for (int zz = 0; zz < channels; ++zz) {
shun-iwasawa 481b59
    buf_s.at(zz).resize(width);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::vector<double> buf_r(width);</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  refer += refcc; /* 参照画像の参照色チャンネル */
Shinya Kitaoka 120a6e
  for (int yy = 0; yy < height;
Shinya Kitaoka 120a6e
       ++yy, image += channels * width, refer += refchannels * width) {
shun-iwasawa 481b59
    // buf_sにSourceのスキャンラインのピクセル値をいれる
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < width; ++xx) {
Shinya Kitaoka 120a6e
      for (int zz = 0; zz < channels; ++zz) {
shun-iwasawa 481b59
        buf_s.at(zz).at(xx) = image[xx * channels + zz];
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
shun-iwasawa 481b59
    // buf_rに参照画像の指定チャンネルの値を入れる
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < width; ++xx) {  // reference red of refer[]
shun-iwasawa 481b59
      float pos = refer[xx * refchannels];
shun-iwasawa 481b59
      // clamp 0.f to 1.f in case using TPixelF
shun-iwasawa 481b59
      pos          = std::min(1.f, std::max(0.f, pos));
shun-iwasawa 481b59
      buf_r.at(xx) = (pos - 0.5f) * maxlen;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (anti_aliasing_sw) {
Shinya Kitaoka 120a6e
      for (int xx = 0; xx < width; ++xx) {
shun-iwasawa 481b59
        float pos  = buf_r.at(xx);
Shinya Kitaoka 120a6e
        int fl_pos = xx + static_cast<int>(std::floor(pos));</int>
Shinya Kitaoka 120a6e
        int ce_pos = xx + static_cast<int>(std::ceil(pos));</int>
shun-iwasawa 481b59
        float div  = pos - floor(pos);
shun-iwasawa 481b59
shun-iwasawa 481b59
        // clamp
shun-iwasawa 481b59
        if (fl_pos < 0)
Shinya Kitaoka 120a6e
          fl_pos = 0;
shun-iwasawa 481b59
        else if (width <= fl_pos)
Shinya Kitaoka 120a6e
          fl_pos = width - 1;
shun-iwasawa 481b59
shun-iwasawa 481b59
        if (ce_pos < 0)
Shinya Kitaoka 120a6e
          ce_pos = 0;
shun-iwasawa 481b59
        else if (width <= ce_pos)
Shinya Kitaoka 120a6e
          ce_pos = width - 1;
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
        for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
          if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
shun-iwasawa 481b59
            image[xx * channels + zz] = buf_s.at(zz).at(xx);
Shinya Kitaoka 120a6e
          } else {
shun-iwasawa 481b59
            image[xx * channels + zz] = buf_s.at(zz).at(fl_pos) * (1.0 - div) +
shun-iwasawa 481b59
                                        buf_s.at(zz).at(ce_pos) * div;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      for (int xx = 0; xx < width; ++xx) {
Shinya Kitaoka 120a6e
        int pos = xx + static_cast<int>(floor(buf_r.at(xx) + 0.5));</int>
shun-iwasawa 481b59
        // clamp
shun-iwasawa 481b59
        if (pos < 0)
Shinya Kitaoka 120a6e
          pos = 0;
shun-iwasawa 481b59
        else if (width <= pos)
Shinya Kitaoka 120a6e
          pos = width - 1;
shun-iwasawa 481b59
Shinya Kitaoka 120a6e
        for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
          if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
shun-iwasawa 481b59
            image[xx * channels + zz] = buf_s.at(zz).at(xx);
Shinya Kitaoka 120a6e
          } else {
shun-iwasawa 481b59
            image[xx * channels + zz] = buf_s.at(zz).at(pos);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
}  // namespace
shun-iwasawa 481b59
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
shun-iwasawa 481b59
void igs::warp::hori_change(float* image, const int height, const int width,
shun-iwasawa 481b59
                            const int channels,
shun-iwasawa 481b59
                            const float* refer,  // by height,width,channels
shun-iwasawa 481b59
                            const int refchannels, const int refcc,
shun-iwasawa 481b59
                            const double maxlen, const bool alpha_rendering_sw,
shun-iwasawa 481b59
                            const bool anti_aliasing_sw) {
shun-iwasawa 481b59
  hori_change_(image, height, width, channels, refer, refchannels, refcc,
shun-iwasawa 481b59
               maxlen, alpha_rendering_sw, anti_aliasing_sw);
shun-iwasawa 481b59
}