Toshihiro Shimizu 890ddd
#include <string></string>
Toshihiro Shimizu 890ddd
#include <vector></vector>
Shinya Kitaoka 120a6e
#include <limits>     // std::numeric_limits</limits>
Shinya Kitaoka 120a6e
#include <stdexcept>  // std::domain_error()</stdexcept>
Shinya Kitaoka 120a6e
#include <algorithm>  // std::max(),std::rotate()</algorithm>
Toshihiro Shimizu 890ddd
#include "igs_resource_multithread.h"
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h"
Toshihiro Shimizu 890ddd
#include "igs_fog.h"
Toshihiro Shimizu 890ddd
#include "igs_attenuation_distribution.cpp"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {  //---------------------------------------------------------
Toshihiro Shimizu 890ddd
void sl_track_render_dark_(
Shinya Kitaoka 120a6e
    double *in_out /* RorGorBorA元かつ結果値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *alpha /* Alpha元値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int width /* 画像幅 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **lens /* lensの外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **track /* 参照画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int *sizes /* lens及び参照scanline毎の長さ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int size /* lens及び参照scanline数 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double power = 1.0 /* 0無  0...1散暗  1強暗  1...2最強暗 */
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < width; ++xx) { /* 画像のScanlineループ */
Shinya Kitaoka 120a6e
    /* Alphaがないか、Alpha値ゼロより大きいと処理しRGB変化 */
Shinya Kitaoka 120a6e
    if ((0 == alpha) || (0.0 < alpha[xx])) {
Shinya Kitaoka 120a6e
      double total = 0.0;
Shinya Kitaoka 120a6e
      for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
        for (int x2 = 0; x2 < sizes[y2]; ++x2) {
Shinya Kitaoka 120a6e
          if (track[y2][x2] < in_out[xx]) {
Shinya Kitaoka 120a6e
            /* より暗いpixelにのみ暗さの影響を受ける */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * track[y2][x2];
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            /* より明るいpixelから影響を受けないようにする */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * in_out[xx];
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /* !!!lensによる値の蓄積が0-1とならなければならない!!! */
Shinya Kitaoka 120a6e
      /* 変化を、強弱を付けて、AlphaでMaskし、元値に加える */
Shinya Kitaoka 120a6e
      total -= in_out[xx]; /* 変化を */
Shinya Kitaoka 120a6e
      total *= power;      /* 強弱を付けて */
Shinya Kitaoka 120a6e
      if ((0 != alpha) && (alpha[xx] < 1.0)) {
Shinya Kitaoka 120a6e
        total *= alpha[xx]; /* AlphaでMaskし */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      total += in_out[xx]; /* 元値に加える */
Shinya Kitaoka 120a6e
      /* 0-1にclampし保存 */
Shinya Kitaoka 120a6e
      in_out[xx] = ((total < 0.0) ? 0.0 : ((1.0 < total) ? 1.0 : total));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
      if (0 < sizes[y2]) {
Shinya Kitaoka 120a6e
        ++track[y2];
Shinya Kitaoka 120a6e
      } /* 次位置へずらしとく */
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void sl_track_render_light_(  // = fog = default
Shinya Kitaoka 120a6e
    double *in_out            /* RorGorBorA元かつ結果値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *alpha /* Alpha元値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int width /* 画像幅 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **lens /* lensの外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **track /* 参照画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int *sizes /* lens及び参照scanline毎の長さ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int size /* lens及び参照scanline数 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double power = 1.0 /* 0無  0...1散光  1強光  1...2最強光 */
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < width; ++xx) { /* 画像のScanlineループ */
Shinya Kitaoka 120a6e
    /* Alphaがないか、Alpha値ゼロより大きいと処理しRGB変化 */
Shinya Kitaoka 120a6e
    if ((0 == alpha) || (0.0 < alpha[xx])) {
Shinya Kitaoka 120a6e
      double total = 0.0;
Shinya Kitaoka 120a6e
      for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
        for (int x2 = 0; x2 < sizes[y2]; ++x2) {
Shinya Kitaoka 120a6e
          if (in_out[xx] < track[y2][x2]) {
Shinya Kitaoka 120a6e
            /* より明るいpixelにのみ明るさの影響を受ける */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * track[y2][x2];
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            /* より暗いpixelから影響を受けないようにする */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * in_out[xx];
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /* !!!lensによる値の蓄積が0-1とならなければならない!!! */
Shinya Kitaoka 120a6e
      /* 変化を、強弱を付けて、AlphaでMaskし、元値に加える */
Shinya Kitaoka 120a6e
      total -= in_out[xx]; /* 変化を */
Shinya Kitaoka 120a6e
      total *= power;      /* 強弱を付けて */
Shinya Kitaoka 120a6e
      if ((0 != alpha) && (alpha[xx] < 1.0)) {
Shinya Kitaoka 120a6e
        total *= alpha[xx]; /* AlphaでMaskし */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      total += in_out[xx]; /* 元値に加える */
Shinya Kitaoka 120a6e
      /* 0-1にclampし保存 */
Shinya Kitaoka 120a6e
      in_out[xx] = ((total < 0.0) ? 0.0 : ((1.0 < total) ? 1.0 : total));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
      if (0 < sizes[y2]) {
Shinya Kitaoka 120a6e
        ++track[y2];
Shinya Kitaoka 120a6e
      } /* 次位置へずらしとく */
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void sl_track_render_threshold_(
Shinya Kitaoka 120a6e
    double *in_out /* RorGorBorA元かつ結果値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *alpha /* Alpha元値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int width /* 画像幅 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **lens /* lensの外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **track /* 参照画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **thres /* 影響画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int *sizes /* lens及び参照scanline毎の長さ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int size /* lens及び参照scanline数 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double power = 1.0 /* 0無  0...1散光  1強光  1...2最強光 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double threshold_min = 0.0 /* 0Cut無 0...1部分 1.01全Cut */
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < width; ++xx) { /* 画像のScanlineループ */
Shinya Kitaoka 120a6e
    /* Alphaがないか、Alpha値ゼロより大きいと処理しRGB変化 */
Shinya Kitaoka 120a6e
    if ((0 == alpha) || (0.0 < alpha[xx])) {
Shinya Kitaoka 120a6e
      double total = 0.0;
Shinya Kitaoka 120a6e
      for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
        for (int x2 = 0; x2 < sizes[y2]; ++x2) {
Shinya Kitaoka 120a6e
          if ((in_out[xx] < track[y2][x2]) &&
Shinya Kitaoka 120a6e
              (threshold_min <= thres[y2][x2])) {
Shinya Kitaoka 120a6e
            /* より明るいpixelにのみ明るさの影響を受ける */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * track[y2][x2];
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            /* より暗いpixelから影響を受けないようにする */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * in_out[xx];
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /* !!!lensによる値の蓄積が0-1とならなければならない!!! */
Shinya Kitaoka 120a6e
      /* 変化を、強弱を付けて、AlphaでMaskし、元値に加える */
Shinya Kitaoka 120a6e
      total -= in_out[xx]; /* 変化を */
Shinya Kitaoka 120a6e
      total *= power;      /* 強弱を付けて */
Shinya Kitaoka 120a6e
      if ((0 != alpha) && (alpha[xx] < 1.0)) {
Shinya Kitaoka 120a6e
        total *= alpha[xx]; /* AlphaでMaskし */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      total += in_out[xx]; /* 元値に加える */
Shinya Kitaoka 120a6e
      /* 0-1にclampし保存 */
Shinya Kitaoka 120a6e
      in_out[xx] = ((total < 0.0) ? 0.0 : ((1.0 < total) ? 1.0 : total));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
      if (0 < sizes[y2]) {
Shinya Kitaoka 120a6e
        ++track[y2]; /* 次の画像位置へずらしとく */
Shinya Kitaoka 120a6e
        ++thres[y2]; /* 次の画像位置へずらしとく */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void sl_track_render_thrminmax_(
Shinya Kitaoka 120a6e
    double *in_out /* RorGorBorA元かつ結果値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *alpha /* Alpha元値(0...1) */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int width /* 画像幅 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **lens /* lensの外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **track /* 参照画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    double **thres /* 影響画外周の左開始位置ポインタ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int *sizes /* lens及び参照scanline毎の長さ配列 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int size /* lens及び参照scanline数 */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double power = 1.0 /* 0無  0...1散光  1強光  1...2最強光 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double threshold_min = 0.0 /* 0Cut無 0...1部分 1.01全Cut */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double threshold_max = 0.0 /* 0Cut無 0...1部分 1.01全Cut */
Shinya Kitaoka 120a6e
    ) {
Shinya Kitaoka 120a6e
  const double thr_range = threshold_max - threshold_min;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < width; ++xx) { /* 画像のScanlineループ */
Shinya Kitaoka 120a6e
    /* Alphaがないか、Alpha値ゼロより大きいと処理しRGB変化 */
Shinya Kitaoka 120a6e
    if ((0 == alpha) || (0.0 < alpha[xx])) {
Shinya Kitaoka 120a6e
      double total = 0.0;
Shinya Kitaoka 120a6e
      for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
        for (int x2 = 0; x2 < sizes[y2]; ++x2) {
Shinya Kitaoka 120a6e
          if ((in_out[xx] < track[y2][x2]) &&
Shinya Kitaoka 120a6e
              (threshold_min <= thres[y2][x2])) {
Shinya Kitaoka 120a6e
            /* より明るくかつminより大きい値のpixelにのみ
Shinya Kitaoka 120a6e
明るさの影響を受ける */
Shinya Kitaoka 120a6e
            if (thres[y2][x2] < threshold_max) {
Shinya Kitaoka 120a6e
              /* maxよりは小さい値のpixelは比で影響する */
Shinya Kitaoka 120a6e
              total += lens[y2][x2] *
Shinya Kitaoka 120a6e
                       (in_out[xx] +
Shinya Kitaoka 120a6e
                        (track[y2][x2] - in_out[xx]) *
Shinya Kitaoka 120a6e
                            (thres[y2][x2] - threshold_min) / thr_range);
Shinya Kitaoka 120a6e
            } else {
Shinya Kitaoka 120a6e
              /* maxより大きい値のpixelは明るさ影響を受ける */
Shinya Kitaoka 120a6e
              total += lens[y2][x2] * track[y2][x2];
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          } else {
Shinya Kitaoka 120a6e
            /* より暗いか、minより小さい値のpixelから
Shinya Kitaoka 120a6e
影響を受けないようにする */
Shinya Kitaoka 120a6e
            total += lens[y2][x2] * in_out[xx];
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /* !!!lensによる値の蓄積が0-1とならなければならない!!! */
Shinya Kitaoka 120a6e
      /* 変化を、強弱を付けて、AlphaでMaskし、元値に加える */
Shinya Kitaoka 120a6e
      total -= in_out[xx]; /* 変化を */
Shinya Kitaoka 120a6e
      total *= power;      /* 強弱を付けて */
Shinya Kitaoka 120a6e
      if ((0 != alpha) && (alpha[xx] < 1.0)) {
Shinya Kitaoka 120a6e
        total *= alpha[xx]; /* AlphaでMaskし */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      total += in_out[xx]; /* 元値に加える */
Shinya Kitaoka 120a6e
      /* 0-1にclampし保存 */
Shinya Kitaoka 120a6e
      in_out[xx] = ((total < 0.0) ? 0.0 : ((1.0 < total) ? 1.0 : total));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (int y2 = 0; y2 < size; ++y2) {
Shinya Kitaoka 120a6e
      if (0 < sizes[y2]) {
Shinya Kitaoka 120a6e
        ++track[y2]; /* 次の画像位置へずらしとく */
Shinya Kitaoka 120a6e
        ++thres[y2]; /* 次の画像位置へずらしとく */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //---------------------------------------------------------
Shinya Kitaoka 120a6e
void sl_track_resize_(const int odd_diameter, const int width,
Shinya Kitaoka 120a6e
                      std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
                      const bool thr_sw,
Shinya Kitaoka 120a6e
                      std::vector<std::vector<double>> &thre_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
                      std::vector<double *=""> &pixe_starts,</double>
Shinya Kitaoka 120a6e
                      std::vector<double *=""> &thre_starts,</double>
Shinya Kitaoka 120a6e
                      std::vector<double> &result,</double>
Shinya Kitaoka 120a6e
                      std::vector<double> &alpha_ref) {</double>
Shinya Kitaoka 120a6e
  pixe_tracks.resize(odd_diameter);
Shinya Kitaoka 120a6e
  for (int yy = 0; yy < odd_diameter; ++yy) {
Shinya Kitaoka 120a6e
    pixe_tracks.at(yy).resize(width + odd_diameter - 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (thr_sw) {
Shinya Kitaoka 120a6e
    thre_tracks.resize(odd_diameter);
Shinya Kitaoka 120a6e
    for (int yy = 0; yy < odd_diameter; ++yy) {
Shinya Kitaoka 120a6e
      thre_tracks.at(yy).resize(width + odd_diameter - 1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  pixe_starts.resize(odd_diameter);
Shinya Kitaoka 120a6e
  thre_starts.resize(odd_diameter);
Shinya Kitaoka 120a6e
  result.resize(width);
Shinya Kitaoka 120a6e
  alpha_ref.clear(); /* 今はクリア!!!あとで使うとき確保!!! */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void sl_track_render_(
Shinya Kitaoka 120a6e
    // std::vector< std::vector<double> >&lens_matrix</double>
Shinya Kitaoka 120a6e
    std::vector<int> &lens_offsets, std::vector<double *=""> &lens_starts,</double></int>
Shinya Kitaoka 120a6e
    std::vector<int> &lens_sizes</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
    std::vector<std::vector<double>> &thre_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
    const std::vector<double> &alpha_ref, std::vector<double> &result,</double></double>
Shinya Kitaoka 120a6e
    std::vector<double *=""> &pixe_starts, std::vector<double *=""> &thre_starts</double></double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double power, const double threshold_min,
Shinya Kitaoka 120a6e
    const double threshold_max) {
Shinya Kitaoka 120a6e
  /*--- scanline初期位置 ---*/
Shinya Kitaoka 120a6e
  for (unsigned int yy = 0; yy < pixe_starts.size(); ++yy) {
Shinya Kitaoka 120a6e
    if (lens_offsets.at(yy) < 0) {
Shinya Kitaoka 120a6e
      pixe_starts.at(yy) = 0;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      pixe_starts.at(yy) = &pixe_tracks.at(yy).at(lens_offsets.at(yy));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (0 < thre_tracks.size()) {
Shinya Kitaoka 120a6e
    for (unsigned int yy = 0; yy < thre_starts.size(); ++yy) {
Shinya Kitaoka 120a6e
      if (lens_offsets.at(yy) < 0) {
Shinya Kitaoka 120a6e
        thre_starts.at(yy) = 0;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        thre_starts.at(yy) = &thre_tracks.at(yy).at(lens_offsets.at(yy));
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 自分より暗いpixelから収光 ---*/
Shinya Kitaoka 120a6e
  if (power < 0.0) {
Shinya Kitaoka 120a6e
    sl_track_render_dark_(&result.at(0),
Shinya Kitaoka 120a6e
                          ((0 < alpha_ref.size()) ? &alpha_ref.at(0) : 0),
Shinya Kitaoka 120a6e
                          static_cast<int>(result.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                              ,
Shinya Kitaoka 120a6e
                          &lens_starts.at(0), &pixe_starts.at(0),
Shinya Kitaoka 120a6e
                          &lens_sizes.at(0), static_cast<int>(lens_sizes.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                                 ,
Shinya Kitaoka 120a6e
                          -power);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 自分より明るいpixelから収光し光量によってfogが変化 ---*/
Shinya Kitaoka 120a6e
  if ((0.0 < threshold_min) || (0.0 < threshold_max)) {
Shinya Kitaoka 120a6e
    if (threshold_min < threshold_max) {
Shinya Kitaoka 120a6e
      sl_track_render_thrminmax_(
Shinya Kitaoka 120a6e
          &result.at(0), ((0 < alpha_ref.size()) ? &alpha_ref.at(0) : 0),
Shinya Kitaoka 120a6e
          static_cast<int>(result.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              ,
Shinya Kitaoka 120a6e
          &lens_starts.at(0), &pixe_starts.at(0), &thre_starts.at(0),
Shinya Kitaoka 120a6e
          &lens_sizes.at(0), static_cast<int>(lens_sizes.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                 ,
Shinya Kitaoka 120a6e
          power, threshold_min, threshold_max);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      /*--- 自分より明るいpixelから収光し、
Shinya Kitaoka 120a6e
ある光量以上からいきなりfogがかかる ---*/
Shinya Kitaoka 120a6e
      sl_track_render_threshold_(
Shinya Kitaoka 120a6e
          &result.at(0), ((0 < alpha_ref.size()) ? &alpha_ref.at(0) : 0),
Shinya Kitaoka 120a6e
          static_cast<int>(result.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              ,
Shinya Kitaoka 120a6e
          &lens_starts.at(0), &pixe_starts.at(0), &thre_starts.at(0),
Shinya Kitaoka 120a6e
          &lens_sizes.at(0), static_cast<int>(lens_sizes.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                 ,
Shinya Kitaoka 120a6e
          power, threshold_min);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 自分より明るいpixelから収光 ---*/
Shinya Kitaoka 120a6e
  sl_track_render_light_(&result.at(0),
Shinya Kitaoka 120a6e
                         ((0 < alpha_ref.size()) ? &alpha_ref.at(0) : 0),
Shinya Kitaoka 120a6e
                         static_cast<int>(result.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                             ,
Shinya Kitaoka 120a6e
                         &lens_starts.at(0), &pixe_starts.at(0),
Shinya Kitaoka 120a6e
                         &lens_sizes.at(0), static_cast<int>(lens_sizes.size())</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                                ,
Shinya Kitaoka 120a6e
                         power);
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void sl_track_shift_(std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
                     std::vector<std::vector<double>> &thre_tracks) {</std::vector<double>
Shinya Kitaoka 120a6e
  std::rotate(pixe_tracks.begin(), pixe_tracks.end() - 1, pixe_tracks.end());
Shinya Kitaoka 120a6e
  if (0 < thre_tracks.size()) {
Shinya Kitaoka 120a6e
    std::rotate(thre_tracks.begin(), thre_tracks.end() - 1, thre_tracks.end());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
void sl_track_clear_(std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
                     std::vector<std::vector<double>> &thre_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
                     std::vector<double *=""> &pixe_starts,</double>
Shinya Kitaoka 120a6e
                     std::vector<double *=""> &thre_starts,</double>
Shinya Kitaoka 120a6e
                     std::vector<double> &result,</double>
Shinya Kitaoka 120a6e
                     std::vector<double> &alpha_ref) {</double>
Shinya Kitaoka 120a6e
  if (!alpha_ref.empty()) {
Shinya Kitaoka 120a6e
    alpha_ref.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!result.empty()) {
Shinya Kitaoka 120a6e
    result.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!thre_starts.empty()) {
Shinya Kitaoka 120a6e
    thre_starts.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!pixe_starts.empty()) {
Shinya Kitaoka 120a6e
    pixe_starts.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!thre_tracks.empty()) {
Shinya Kitaoka 120a6e
    thre_tracks.clear();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!pixe_tracks.empty()) {
Shinya Kitaoka 120a6e
    pixe_tracks.clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //--------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void rgb_to_lightness_image_(const T *image, const int height, const int width,
Shinya Kitaoka 120a6e
                             const int channels, double *lightness) {
Shinya Kitaoka 120a6e
  const double val_max = static_cast<double>(std::numeric_limits<t>::max());</t></double>
Shinya Kitaoka 120a6e
  for (int yy = 0; yy < height; ++yy) {
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < width; ++xx, image += channels, ++lightness) {
Shinya Kitaoka 120a6e
      if (1 == channels) {
Shinya Kitaoka 120a6e
        *lightness = static_cast<double>(image[0]) / val_max;</double>
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        const double red = static_cast<double>(image[0]) / val_max;</double>
Shinya Kitaoka 120a6e
        const double gre = static_cast<double>(image[1]) / val_max;</double>
Shinya Kitaoka 120a6e
        const double blu = static_cast<double>(image[2]) / val_max;</double>
Shinya Kitaoka 120a6e
        /* rgb --> hls のl(明度(lightness))のみの計算 */
Shinya Kitaoka 120a6e
        *lightness = (std::max(std::max(red, gre), blu) +
Shinya Kitaoka 120a6e
                      std::min(std::min(red, gre), blu)) /
Shinya Kitaoka 120a6e
                     2.0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //--------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
        画像配列の高さ位置を、実際の範囲内にclampし、scanlineの先頭を返す
Shinya Kitaoka 120a6e
        TP is 'unsigned char *' or 'unsigned short *'
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
template <class tp=""></class>
Shinya Kitaoka 120a6e
TP sl_top_clamped_in_h_(TP sl, const int height, const int width,
Shinya Kitaoka 120a6e
                        const int channels, const int yy) {
Shinya Kitaoka 120a6e
  if (height <= yy) {
Shinya Kitaoka 120a6e
    return sl + (channels * width * (height - 1));
Shinya Kitaoka 120a6e
  } else if (yy < 0) {
Shinya Kitaoka 120a6e
    return sl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return sl + (channels * width * yy);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
        trackの左右の余白を画像の端の色で塗りつぶす
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void paint_margin_(const int width, const int margin, std::vector<t> &track) {</t>
Shinya Kitaoka 120a6e
  if (width <= (margin * 2)) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } /* 余白太すぎ */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < margin; ++xx) {
Shinya Kitaoka 120a6e
    track.at(xx) = track.at(margin); /* 始点側の余白を塗る */
Shinya Kitaoka 120a6e
    track.at(track.size() - 1 - xx) =
Shinya Kitaoka 120a6e
        track.at(track.size() - margin - 1); /* 終端側の余白を塗る */
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //--------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
        T is 'unsigned char' or 'unsigned short'
Shinya Kitaoka 120a6e
        alphaは先に処理して結果(out_image_array)に入れ、
Shinya Kitaoka 120a6e
                その後rgbのために参照する
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void get_first_sl_ch_(
Shinya Kitaoka 120a6e
    const T *in_image_array,
Shinya Kitaoka 120a6e
    const T *out_image_array /* 処理結果alpha値の参照のため必要 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *ref_thres_array /* threshold値の参照のため必要 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int hh, const int ww, const int ch, const int yy, const int zz,
Shinya Kitaoka 120a6e
    const int margin, std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
    std::vector<std::vector<double>> &thre_tracks, std::vector<double> &result,</double></std::vector<double>
Shinya Kitaoka 120a6e
    std::vector<double> &alpha_ref) {</double>
Shinya Kitaoka 120a6e
  const double val_max = static_cast<double>(std::numeric_limits<t>::max());</t></double>
Shinya Kitaoka 120a6e
  /*--- 入力画像を(マージン含めた1scanline分)得る ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int yp = -margin + yy;
Shinya Kitaoka 120a6e
    int ii = margin * 2;
Shinya Kitaoka 120a6e
    for (; yp <= margin + yy; ++yp, --ii) {
Shinya Kitaoka 120a6e
      const T *ss = sl_top_clamped_in_h_(in_image_array, hh, ww, ch, yp) + zz;
Shinya Kitaoka 120a6e
      std::vector<double> &track = pixe_tracks.at(ii);</double>
Shinya Kitaoka 120a6e
      for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
        track.at(margin + xx) = static_cast<double>(ss[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      paint_margin_(ww, margin, track);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- (閾値として)参照する画像を(マージン含めた1scanline分)得る -*/
Shinya Kitaoka 120a6e
  if ((0 != ref_thres_array) && (0 < thre_tracks.size())) {
Shinya Kitaoka 120a6e
    int yp = -margin + yy;
Shinya Kitaoka 120a6e
    int ii = margin * 2;
Shinya Kitaoka 120a6e
    for (; yp <= margin + yy; ++yp, --ii) {
Shinya Kitaoka 120a6e
      const double *ss = sl_top_clamped_in_h_(ref_thres_array, hh, ww, 1, yp);
Shinya Kitaoka 120a6e
      std::vector<double> &track = thre_tracks.at(ii);</double>
Shinya Kitaoka 120a6e
      for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
        track.at(margin + xx) = ss[xx * 1];
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      paint_margin_(ww, margin, track);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 入力画像を保存画像エリアに1scanline分入れる ---*/
Shinya Kitaoka 120a6e
  const T *ss = sl_top_clamped_in_h_(in_image_array, hh, ww, ch, yy) + zz;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    result.at(xx) = static_cast<double>(ss[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 処理結果としてのalpha画像エリアを1scanline分入れる ---*/
Shinya Kitaoka 120a6e
  if ((alpha_ref.size() <= 0) || (ch < 4)) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  const T *dd = sl_top_clamped_in_h_(out_image_array, hh, ww, ch, yy) + 3;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    alpha_ref.at(xx) = static_cast<double>(dd[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void get_next_sl_ch_(
Shinya Kitaoka 120a6e
    const T *in_image_array,
Shinya Kitaoka 120a6e
    const T *out_image_array /* 処理結果alpha値の参照のため必要 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const double *ref_thres_array /* threshold値の参照のため必要 */
Shinya Kitaoka 120a6e
    ,
Shinya Kitaoka 120a6e
    const int hh, const int ww, const int ch, const int yy, const int zz,
Shinya Kitaoka 120a6e
    const int margin, std::vector<std::vector<double>> &pixe_tracks,</std::vector<double>
Shinya Kitaoka 120a6e
    std::vector<std::vector<double>> &thre_tracks, std::vector<double> &result,</double></std::vector<double>
Shinya Kitaoka 120a6e
    std::vector<double> &alpha_ref) {</double>
Shinya Kitaoka 120a6e
  const double val_max = static_cast<double>(std::numeric_limits<t>::max());</t></double>
Shinya Kitaoka 120a6e
  /*--- 入力画像を(1scanline分)得る ---*/
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    const T *mm =
Shinya Kitaoka 120a6e
        sl_top_clamped_in_h_(in_image_array, hh, ww, ch, yy + margin) + zz;
Shinya Kitaoka 120a6e
    std::vector<double> &track = pixe_tracks.at(0);</double>
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
      track.at(margin + xx) = static_cast<double>(mm[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    paint_margin_(ww, margin, track);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- (閾値として)参照する画像を(1scanline分)得る --*/
Shinya Kitaoka 120a6e
  if ((0 != ref_thres_array) && (0 < thre_tracks.size())) {
Shinya Kitaoka 120a6e
    const double *mm =
Shinya Kitaoka 120a6e
        sl_top_clamped_in_h_(ref_thres_array, hh, ww, 1, yy + margin);
Shinya Kitaoka 120a6e
    std::vector<double> &track = thre_tracks.at(0);</double>
Shinya Kitaoka 120a6e
    for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
      track.at(margin + xx) = mm[xx * 1];
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    paint_margin_(ww, margin, track);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 入力画像を保存画像エリアに1scanline分入れる ---*/
Shinya Kitaoka 120a6e
  const T *ss = sl_top_clamped_in_h_(in_image_array, hh, ww, ch, yy) + zz;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    result.at(xx) = static_cast<double>(ss[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  /*--- 処理結果としてのalpha画像エリアを1scanline分入れる ---*/
Shinya Kitaoka 120a6e
  if ((alpha_ref.size() <= 0) || (ch < 4)) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  const T *dd = sl_top_clamped_in_h_(out_image_array, hh, ww, ch, yy) + 3;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    alpha_ref.at(xx) = static_cast<double>(dd[xx * ch]) / val_max;</double>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class tp=""></class>
Shinya Kitaoka 120a6e
void copy_sl_ch_(const TP in_image_array, TP out_image_array, const int hh,
Shinya Kitaoka 120a6e
                 const int ww, const int ch, const int yy, const int zz) {
Shinya Kitaoka 120a6e
  const TP ss = sl_top_clamped_in_h_(in_image_array, hh, ww, ch, yy) + zz;
Shinya Kitaoka 120a6e
  TP dd       = sl_top_clamped_in_h_(out_image_array, hh, ww, ch, yy) + zz;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    dd[ch * xx] = ss[ch * xx];
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void put_sl_ch_(std::vector<double> &result, const int hh, const int ww,</double>
Shinya Kitaoka 120a6e
                const int ch, const int yy, const int zz, T *out_image_array) {
Shinya Kitaoka 120a6e
  const double val_max = static_cast<double>(std::numeric_limits<t>::max());</t></double>
Shinya Kitaoka 120a6e
  T *dd = sl_top_clamped_in_h_(out_image_array, hh, ww, ch, yy) + zz;
Shinya Kitaoka 120a6e
  for (int xx = 0; xx < ww; ++xx) {
Shinya Kitaoka 120a6e
    dd[ch * xx] = static_cast<t>(result.at(xx) * (val_max + 0.999999));</t>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //--------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
class one_thread_
Shinya Kitaoka 120a6e
    : public igs::resource::thread_execute_interface { /* thread単位の実行設定
Shinya Kitaoka 120a6e
                                                          */
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  one_thread_() {}
Shinya Kitaoka 120a6e
  void setup(T in_image, T out_image, double *ref_thresh
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const int height, const int width, const int channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const int y_begin, const int y_end
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
             // , std::vector< std::vector<double> > *lens_matrix_p</double>
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             std::vector<int> *lens_offsets_p,</int>
Shinya Kitaoka 120a6e
             std::vector<double *=""> *lens_starts_p,</double>
Shinya Kitaoka 120a6e
             std::vector<int> *lens_sizes_p</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
             ,
Shinya Kitaoka 120a6e
             const double power, const double threshold_min,
Shinya Kitaoka 120a6e
             const double threshold_max, const bool alpha_rendering_sw) {
Shinya Kitaoka 120a6e
    this->in_image_   = in_image;
Shinya Kitaoka 120a6e
    this->out_image_  = out_image;
Shinya Kitaoka 120a6e
    this->ref_thresh_ = ref_thresh;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->height_   = height;
Shinya Kitaoka 120a6e
    this->width_    = width;
Shinya Kitaoka 120a6e
    this->channels_ = channels;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->y_begin_ = y_begin;
Shinya Kitaoka 120a6e
    this->y_end_   = y_end;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // this->lens_matrix_p_ = lens_matrix_p;
Shinya Kitaoka 120a6e
    this->lens_offsets_p_ = lens_offsets_p;
Shinya Kitaoka 120a6e
    this->lens_starts_p_  = lens_starts_p;
Shinya Kitaoka 120a6e
    this->lens_sizes_p_   = lens_sizes_p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->power_              = power;
Shinya Kitaoka 120a6e
    this->threshold_min_      = threshold_min;
Shinya Kitaoka 120a6e
    this->threshold_max_      = threshold_max;
Shinya Kitaoka 120a6e
    this->alpha_rendering_sw_ = alpha_rendering_sw;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    sl_track_resize_(static_cast<int>(this->lens_offsets_p_->size()),</int>
Shinya Kitaoka 120a6e
                     this->width_, this->pixe_tracks_,
Shinya Kitaoka 120a6e
                     ((0 == ref_thresh) ? false : true), this->thre_tracks_,
Shinya Kitaoka 120a6e
                     this->pixe_starts_, this->thre_starts_, this->result_,
Shinya Kitaoka 120a6e
                     this->alpha_ref_);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 473e70
  void run(void) override {
Shinya Kitaoka 120a6e
    bool rgb_rendering_sw   = true;
Shinya Kitaoka 120a6e
    bool alpha_rendering_sw = this->alpha_rendering_sw_;
Shinya Kitaoka 120a6e
    if (this->pixe_tracks_.size() <= 1) {
Shinya Kitaoka 120a6e
      rgb_rendering_sw   = false;
Shinya Kitaoka 120a6e
      alpha_rendering_sw = false;
Shinya Kitaoka 120a6e
    }  // not render,then copy
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* first scanline-->next scanlineで処理するので
Shinya Kitaoka 120a6e
かならすchannel毎にまとめてループする */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int yy;
Shinya Kitaoka 120a6e
    if (igs::image::rgba::siz == this->channels_) {
Shinya Kitaoka 120a6e
      using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, alp, alpha_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      /* alpha処理後にalpha参照用設定をする */
Shinya Kitaoka 120a6e
      this->alpha_ref_.resize(this->width_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, blu, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, gre, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, red, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (igs::image::rgb::siz == this->channels_) {
Shinya Kitaoka 120a6e
      using namespace igs::image::rgb;
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, blu, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, gre, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, red, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (1 == this->channels_) { /* grayscale */
Shinya Kitaoka 120a6e
      for (yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, 0, rgb_rendering_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void clear(void) {
Shinya Kitaoka 120a6e
    sl_track_clear_(this->pixe_tracks_, this->thre_tracks_, this->pixe_starts_,
Shinya Kitaoka 120a6e
                    this->thre_starts_, this->result_, this->alpha_ref_);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  T in_image_;
Shinya Kitaoka 120a6e
  T out_image_;
Shinya Kitaoka 120a6e
  double *ref_thresh_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int height_;
Shinya Kitaoka 120a6e
  int width_;
Shinya Kitaoka 120a6e
  int channels_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int y_begin_;
Shinya Kitaoka 120a6e
  int y_end_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // std::vector< std::vector<double> > *lens_matrix_p_;</double>
Shinya Kitaoka 120a6e
  std::vector<int> *lens_offsets_p_;</int>
Shinya Kitaoka 120a6e
  std::vector<double *=""> *lens_starts_p_;</double>
Shinya Kitaoka 120a6e
  std::vector<int> *lens_sizes_p_;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double power_;
Shinya Kitaoka 120a6e
  double threshold_min_;
Shinya Kitaoka 120a6e
  double threshold_max_;
Shinya Kitaoka 120a6e
  bool alpha_rendering_sw_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> pixe_tracks_;</std::vector<double>
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> thre_tracks_;</std::vector<double>
Shinya Kitaoka 120a6e
  std::vector<double *=""> pixe_starts_;</double>
Shinya Kitaoka 120a6e
  std::vector<double *=""> thre_starts_;</double>
Shinya Kitaoka 120a6e
  std::vector<double> result_;</double>
Shinya Kitaoka 120a6e
  std::vector<double> alpha_ref_;</double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void rendering_sl_ch_(int yy, int zz, bool rendering_sw) {
Shinya Kitaoka 120a6e
    if (!rendering_sw) {
Shinya Kitaoka 120a6e
      copy_sl_ch_(this->in_image_, this->out_image_, this->height_,
Shinya Kitaoka 120a6e
                  this->width_, this->channels_, yy, zz);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (yy == this->y_begin_) {
Shinya Kitaoka 120a6e
      get_first_sl_ch_(this->in_image_, this->out_image_, this->ref_thresh_,
Shinya Kitaoka 120a6e
                       this->height_, this->width_, this->channels_, yy, zz,
Shinya Kitaoka 120a6e
                       static_cast<int>(this->pixe_tracks_.size() / 2),</int>
Shinya Kitaoka 120a6e
                       this->pixe_tracks_, this->thre_tracks_, this->result_,
Shinya Kitaoka 120a6e
                       this->alpha_ref_);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      sl_track_shift_(this->pixe_tracks_, this->thre_tracks_);
Shinya Kitaoka 120a6e
      get_next_sl_ch_(this->in_image_, this->out_image_, this->ref_thresh_,
Shinya Kitaoka 120a6e
                      this->height_, this->width_, this->channels_, yy, zz,
Shinya Kitaoka 120a6e
                      static_cast<int>(this->pixe_tracks_.size() / 2),</int>
Shinya Kitaoka 120a6e
                      this->pixe_tracks_, this->thre_tracks_, this->result_,
Shinya Kitaoka 120a6e
                      this->alpha_ref_);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    sl_track_render_(
Shinya Kitaoka 120a6e
        //  *(this->lens_matrix_p_)
Shinya Kitaoka 120a6e
        *(this->lens_offsets_p_), *(this->lens_starts_p_),
Shinya Kitaoka 120a6e
        *(this->lens_sizes_p_)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            ,
Shinya Kitaoka 120a6e
        this->pixe_tracks_, this->thre_tracks_, this->alpha_ref_
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        ,
Shinya Kitaoka 120a6e
        this->result_
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        ,
Shinya Kitaoka 120a6e
        this->pixe_starts_, this->thre_starts_
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        ,
Shinya Kitaoka 120a6e
        this->power_, this->threshold_min_, this->threshold_max_);
Shinya Kitaoka 120a6e
    put_sl_ch_(this->result_, this->height_, this->width_, this->channels_, yy,
Shinya Kitaoka 120a6e
               zz, this->out_image_);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
namespace {  //--------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
class multi_thread_ {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  multi_thread_(T in_image, T out_image, double *ref_thres, const int height,
Shinya Kitaoka 120a6e
                const int width, const int channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const int number_of_thread  // 1 ... INT_MAX
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double radius  // 25.0(0...100(DOUBLE_MAX))
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double curve  // 1.00(0.01 ... 100)
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const int polygon_number  // 2(2 ... 16(INT_MAX))
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double degree  // 0(0 ... DOUBLE_MAX)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double power  // 1.00(-2.00 ... 2.00)
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double threshold_min  // 0.00(0.00 ... 1.01)
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const double threshold_max  // 0.00(0.00 ... 1.01)
Shinya Kitaoka 120a6e
                ,
Shinya Kitaoka 120a6e
                const bool alpha_rendering_sw  // false(true,false)
Shinya Kitaoka 120a6e
                ) {
Shinya Kitaoka 120a6e
    /*--------------スレッド数の設定--------------------*/
Shinya Kitaoka 120a6e
    int thread_num = number_of_thread;
Shinya Kitaoka 120a6e
    if ((thread_num < 1) || (height < thread_num)) {
Shinya Kitaoka 120a6e
      thread_num = 1;
Shinya Kitaoka 120a6e
    } /* ゼロ以下か、高さより多い */
Shinya Kitaoka 120a6e
    /*--------------メモリ確保--------------------------*/
Shinya Kitaoka 120a6e
    int odd_diameter = 0;
Shinya Kitaoka 120a6e
    attenuation_distribution_(this->lens_matrix_, this->lens_offsets_,
Shinya Kitaoka 120a6e
                              this->lens_starts_, this->lens_sizes_,
Shinya Kitaoka 120a6e
                              odd_diameter,
Shinya Kitaoka 120a6e
                              radius /* 直径(radiusの2倍)1以下ならエラーthrow */
Shinya Kitaoka 120a6e
                              ,
Shinya Kitaoka 120a6e
                              curve /* curveがゼロならエラーthrow */
Shinya Kitaoka 120a6e
                              ,
Shinya Kitaoka 120a6e
                              polygon_number, degree);
Shinya Kitaoka 120a6e
    this->threads_.resize(thread_num);
Shinya Kitaoka 120a6e
    /*-------スレッド毎の処理指定-----------------------*/
Shinya Kitaoka 120a6e
    int h_sub = height / thread_num;
Shinya Kitaoka 120a6e
    if (0 != (height % thread_num)) {
Shinya Kitaoka 120a6e
      ++h_sub; /* 割り切れないときは一つ増やす */
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    int yy = 0;
Shinya Kitaoka 120a6e
    for (int ii = 0; ii < thread_num; ++ii, yy += h_sub) {
Shinya Kitaoka 120a6e
      /*
Shinya Kitaoka 120a6e
      5 h_scanline,4 thread --> h_count is 2
Shinya Kitaoka 120a6e
      thread	1	2	3	4
Shinya Kitaoka 120a6e
      h_count	2	2	1	0
Shinya Kitaoka 120a6e
      */
Shinya Kitaoka 120a6e
      if (height < (yy + h_sub)) {
Shinya Kitaoka 120a6e
        h_sub = height - yy;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      this->threads_.at(ii).setup(
Shinya Kitaoka 120a6e
          in_image, out_image, ref_thres
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          ,
Shinya Kitaoka 120a6e
          height, width, channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          ,
Shinya Kitaoka 120a6e
          yy, yy + h_sub - 1
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // , &(this->lens_matrix_)
Shinya Kitaoka 120a6e
          ,
Shinya Kitaoka 120a6e
          &(this->lens_offsets_), &(this->lens_starts_), &(this->lens_sizes_)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                                             ,
Shinya Kitaoka 120a6e
          power, threshold_min, threshold_max, alpha_rendering_sw);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /*------スレッド毎のスレッド指定------*/
Shinya Kitaoka 120a6e
    for (int ii = 0; ii < thread_num; ++ii) {
Shinya Kitaoka 120a6e
      this->mthread_.add(&(this->threads_.at(ii)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void run(void) { this->mthread_.run(); }
Shinya Kitaoka 120a6e
  void clear() {
Shinya Kitaoka 120a6e
    this->mthread_.clear();
Shinya Kitaoka 120a6e
    this->threads_.clear();
Shinya Kitaoka 120a6e
    this->lens_sizes_.clear();
Shinya Kitaoka 120a6e
    this->lens_starts_.clear();
Shinya Kitaoka 120a6e
    this->lens_offsets_.clear();
Shinya Kitaoka 120a6e
    this->lens_matrix_.clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> lens_matrix_;</std::vector<double>
Shinya Kitaoka 120a6e
  std::vector<int> lens_offsets_;</int>
Shinya Kitaoka 120a6e
  std::vector<double *=""> lens_starts_;</double>
Shinya Kitaoka 120a6e
  std::vector<int> lens_sizes_;</int>
Shinya Kitaoka 120a6e
  std::vector<one_thread_<t>> threads_;</one_thread_<t>
Shinya Kitaoka 120a6e
  igs::resource::multithread mthread_;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/* パラメータの指定を見て、画像に変化の無い場合、
Toshihiro Shimizu 890ddd
呼び出し側で、fog処理するか判断する。fog処理しないときの処理も忘れずに */
Shinya Kitaoka 120a6e
bool igs::fog::have_change(const double radius  // 25.0(0 ... 100(DOUBLE_MAX))
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
                           const double power  // 1.00(-2.00 ... 2.00)
Shinya Kitaoka 120a6e
                           ,
Shinya Kitaoka 120a6e
                           const double threshold_min  // 0.00(0.00 ... 1.01)
Shinya Kitaoka 120a6e
                           ) {
Shinya Kitaoka 120a6e
  /* 収光(変化)しない
Shinya Kitaoka 120a6e
          場合1  直径が1以下
Shinya Kitaoka 120a6e
          場合2  powerがゼロ(マイナスは有効としている)
Shinya Kitaoka 120a6e
          場合3  powerがプラスで、threshold_minが1よりも大きい
Shinya Kitaoka 120a6e
  */
Shinya Kitaoka 120a6e
  if ((static_cast<int>(ceil(radius * 2.0)) <= 1) || (0.0 == power) ||</int>
Shinya Kitaoka 120a6e
      ((0.0 < power) && (1.0 < threshold_min))) {
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/* fog処理する */
Shinya Kitaoka 120a6e
void igs::fog::convert(void *in  // no margin
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       void *out  // no margin
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       double *buffer  // no margin
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const int height, const int width, const int channels,
Shinya Kitaoka 120a6e
                       const int bits
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const int number_of_thread  // 1 ... INT_MAX
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double radius  // 25.0(0 ... 100(DOUBLE_MAX))
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double curve  // 1.00(0.01 ... 100)
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const int polygon_number  // 2(2 ... 16(INT_MAX))
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double degree  // 0(0 ... DOUBLE_MAX)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double power  // 1.00(-2.00 ... 2.00)
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double threshold_min  // 0.00(0.00 ... 1.01)
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const double threshold_max  // 0.00(0.00 ... 1.01)
Shinya Kitaoka 120a6e
                       ,
Shinya Kitaoka 120a6e
                       const bool alpha_rendering_sw  // false(true,false)
Shinya Kitaoka 120a6e
                       ) {
Shinya Kitaoka 120a6e
  if ((igs::image::rgba::siz != channels) &&
Shinya Kitaoka 120a6e
      (igs::image::rgb::siz != channels) && (1 != channels) /* grayscale */
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
    if (0 != buffer) {
Shinya Kitaoka 120a6e
      rgb_to_lightness_image_(static_cast<const *="" char="" unsigned="">(in), height,</const>
Shinya Kitaoka 120a6e
                              width, channels, buffer);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    multi_thread_<unsigned *="" char=""> mthread(</unsigned>
Shinya Kitaoka 120a6e
        static_cast<unsigned *="" char="">(in), static_cast<unsigned *="" char="">(out),</unsigned></unsigned>
Shinya Kitaoka 120a6e
        buffer, height, width, channels, number_of_thread, radius, curve,
Shinya Kitaoka 120a6e
        polygon_number, degree, power, threshold_min, threshold_max,
Shinya Kitaoka 120a6e
        alpha_rendering_sw);
Shinya Kitaoka 120a6e
    mthread.run();
Shinya Kitaoka 120a6e
    mthread.clear();
Shinya Kitaoka 120a6e
  } else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
Shinya Kitaoka 120a6e
    if (0 != buffer) {
Shinya Kitaoka 120a6e
      rgb_to_lightness_image_(static_cast<const *="" short="" unsigned="">(in), height,</const>
Shinya Kitaoka 120a6e
                              width, channels, buffer);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    multi_thread_<unsigned *="" short=""> mthread(</unsigned>
Shinya Kitaoka 120a6e
        static_cast<unsigned *="" short="">(in), static_cast<unsigned *="" short="">(out),</unsigned></unsigned>
Shinya Kitaoka 120a6e
        buffer, height, width, channels, number_of_thread, radius, curve,
Shinya Kitaoka 120a6e
        polygon_number, degree, power, threshold_min, threshold_max,
Shinya Kitaoka 120a6e
        alpha_rendering_sw);
Shinya Kitaoka 120a6e
    mthread.run();
Shinya Kitaoka 120a6e
    mthread.clear();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    throw std::domain_error("Bad bits,Not uchar/ushort");
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}