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 {
Toshihiro Shimizu 890ddd
template <class class="" rt="" st,=""></class>
Shinya Kitaoka 120a6e
void vert_change_template_(ST *image, const int height, const int width,
Shinya Kitaoka 120a6e
                           const int channels
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
                           const RT *refer  // same as height,width,channels
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
                           const int refchannels, const int refcc
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
                           const double offset, const double maxlen,
Shinya Kitaoka 120a6e
                           const bool alpha_rendering_sw,
Shinya Kitaoka 120a6e
                           const bool anti_aliasing_sw) {
Shinya Kitaoka 120a6e
  const double smax = std::numeric_limits<st>::max();</st>
Shinya Kitaoka 120a6e
  const double rmax = std::numeric_limits<rt>::max();</rt>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> buf_s1(channels), buf_s2(channels);</std::vector<double>
Shinya Kitaoka 120a6e
  for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
    buf_s1.at(zz).resize(height);
Shinya Kitaoka 120a6e
    buf_s2.at(zz).resize(height);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  std::vector<double> buf_r(height);</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  refer += refcc; /* 参照画像の参照色チャンネル */
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < width; ++xx, image += channels, refer += refchannels) {
Shinya Kitaoka 120a6e
    for (int yy = 0; yy < height; ++yy) {
Shinya Kitaoka 120a6e
      for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
        buf_s1.at(zz).at(yy) = image[yy * width * channels + zz] / smax;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (int yy = 0; yy < height; ++yy) {  // reference red of refer[]
Shinya Kitaoka 120a6e
      double pos   = static_cast<double>(refer[yy * width * refchannels]);</double>
Shinya Kitaoka 120a6e
      buf_r.at(yy) = ((pos / rmax) - offset) * maxlen;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (anti_aliasing_sw) {
Shinya Kitaoka 120a6e
      for (int yy = 0; yy < height; ++yy) {
Shinya Kitaoka 120a6e
        double pos = buf_r.at(yy);
Shinya Kitaoka 120a6e
        int fl_pos = yy + static_cast<int>(std::floor(pos));</int>
Shinya Kitaoka 120a6e
        int ce_pos = yy + static_cast<int>(std::ceil(pos));</int>
Shinya Kitaoka 120a6e
        double div = pos - floor(pos);
Shinya Kitaoka 120a6e
        if (fl_pos < 0) {
Shinya Kitaoka 120a6e
          fl_pos = 0;
Shinya Kitaoka 120a6e
        } else if (height <= fl_pos) {
Shinya Kitaoka 120a6e
          fl_pos = height - 1;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (ce_pos < 0) {
Shinya Kitaoka 120a6e
          ce_pos = 0;
Shinya Kitaoka 120a6e
        } else if (height <= ce_pos) {
Shinya Kitaoka 120a6e
          ce_pos = height - 1;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
          if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
Shinya Kitaoka 120a6e
            buf_s2.at(zz).at(yy) = buf_s1.at(zz).at(yy);
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            buf_s2.at(zz).at(yy) = buf_s1.at(zz).at(fl_pos) * (1.0 - div) +
Shinya Kitaoka 120a6e
                                   buf_s1.at(zz).at(ce_pos) * div;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      for (int yy = 0; yy < height; ++yy) {
Shinya Kitaoka 120a6e
        int pos = yy + static_cast<int>(floor(buf_r.at(yy) + 0.5));</int>
Shinya Kitaoka 120a6e
        if (pos < 0) {
Shinya Kitaoka 120a6e
          pos = 0;
Shinya Kitaoka 120a6e
        } else if (height <= pos) {
Shinya Kitaoka 120a6e
          pos = height - 1;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
          if (!alpha_rendering_sw && (igs::image::rgba::alp == zz)) {
Shinya Kitaoka 120a6e
            buf_s2.at(zz).at(yy) = buf_s1.at(zz).at(yy);
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            buf_s2.at(zz).at(yy) = buf_s1.at(zz).at(pos);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (int yy = 0; yy < height; ++yy) {
Shinya Kitaoka 120a6e
      for (int zz = 0; zz < channels; ++zz) {
Shinya Kitaoka 120a6e
        image[yy * width * channels + zz] =
Shinya Kitaoka 120a6e
            static_cast<st>(buf_s2.at(zz).at(yy) * (smax + 0.999999));</st>
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void igs::warp::vert_change(
Shinya Kitaoka 120a6e
    unsigned char *image, const int height, const int width, const int channels,
Shinya Kitaoka 120a6e
    const int bits
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const unsigned char *refer  // by height,width,channels
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int refchannels, const int refcc, const int refbit
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double offset, const double maxlen, const bool alpha_rendering_sw,
Shinya Kitaoka 120a6e
    const bool anti_aliasing_sw) {
Shinya Kitaoka 120a6e
  const int ucharb  = std::numeric_limits<unsigned char="">::digits;</unsigned>
Shinya Kitaoka 120a6e
  const int ushortb = std::numeric_limits<unsigned short="">::digits;</unsigned>
Shinya Kitaoka 120a6e
  if ((ushortb == bits) && (ushortb == refbit)) {
Shinya Kitaoka 120a6e
    vert_change_template_(
Shinya Kitaoka 120a6e
        reinterpret_cast<unsigned *="" short="">(image), height, width, channels,</unsigned>
Shinya Kitaoka 120a6e
        reinterpret_cast<const *="" short="" unsigned="">(refer), refchannels, refcc,</const>
Shinya Kitaoka 120a6e
        offset, maxlen, alpha_rendering_sw, anti_aliasing_sw);
Shinya Kitaoka 120a6e
  } else if ((ushortb == bits) && (ucharb == refbit)) {
Shinya Kitaoka 120a6e
    vert_change_template_(reinterpret_cast<unsigned *="" short="">(image), height,</unsigned>
Shinya Kitaoka 120a6e
                          width, channels, refer, refchannels, refcc, offset,
Shinya Kitaoka 120a6e
                          maxlen, alpha_rendering_sw, anti_aliasing_sw);
Shinya Kitaoka 120a6e
  } else if ((ucharb == bits) && (ushortb == refbit)) {
Shinya Kitaoka 120a6e
    vert_change_template_(image, height, width, channels,
Shinya Kitaoka 120a6e
                          reinterpret_cast<const *="" short="" unsigned="">(refer),</const>
Shinya Kitaoka 120a6e
                          refchannels, refcc, offset, maxlen,
Shinya Kitaoka 120a6e
                          alpha_rendering_sw, anti_aliasing_sw);
Shinya Kitaoka 120a6e
  } else if ((ucharb == bits) && (ucharb == refbit)) {
Shinya Kitaoka 120a6e
    vert_change_template_(image, height, width, channels, refer, refchannels,
Shinya Kitaoka 120a6e
                          refcc, offset, maxlen, alpha_rendering_sw,
Shinya Kitaoka 120a6e
                          anti_aliasing_sw);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}