Shinya Kitaoka 810553
#pragma once
Shinya Kitaoka 810553
Toshihiro Shimizu 890ddd
#ifndef igs_maxmin_multithread_h
Toshihiro Shimizu 890ddd
#define igs_maxmin_multithread_h
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h" /* igs::image::rgba */
Toshihiro Shimizu 890ddd
#include "igs_resource_multithread.h"
Toshihiro Shimizu 890ddd
#include "igs_maxmin_slrender.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace igs {
Shinya Kitaoka 120a6e
namespace maxmin {
Toshihiro Shimizu 890ddd
template <class class="" it,="" rt=""></class>
Shinya Kitaoka 120a6e
class thread
Shinya Kitaoka 120a6e
    : public igs::resource::thread_execute_interface { /* thread単位の実行設定
Shinya Kitaoka 120a6e
                                                          */
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  thread() {}
Shinya Kitaoka 120a6e
  void setup(
Shinya Kitaoka 120a6e
      /* 入出力画像 */
Shinya Kitaoka 120a6e
      const IT *inn, IT *out, int height, int width, int channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Pixel毎に効果の強弱 */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const RT *ref /* 求める画像(out)と同じ高、幅、チャンネル数 */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Action Geometry */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      int y_begin, int y_end, std::vector<int> *lens_offsets_p,</int>
Shinya Kitaoka 120a6e
      std::vector<int> *lens_sizes_p,</int>
Shinya Kitaoka 120a6e
      std::vector<std::vector<double>> *lens_ratio_p</std::vector<double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      double radius, double smooth_outer_range, int polygon_number,
Shinya Kitaoka 120a6e
      double roll_degree
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Action Type */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      bool min_sw, bool alpha_rendering_sw, bool add_blend_sw) {
Shinya Kitaoka 120a6e
    this->inn_      = inn;
Shinya Kitaoka 120a6e
    this->out_      = out;
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->ref_      = ref;
Shinya Kitaoka 120a6e
    this->ref_mode_ = ref_mode;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->y_begin_        = y_begin;
Shinya Kitaoka 120a6e
    this->y_end_          = y_end;
Shinya Kitaoka 120a6e
    this->lens_offsets_p_ = lens_offsets_p;
Shinya Kitaoka 120a6e
    this->lens_sizes_p_   = lens_sizes_p;
Shinya Kitaoka 120a6e
    this->lens_ratio_p_   = lens_ratio_p;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->radius_             = radius;
Shinya Kitaoka 120a6e
    this->smooth_outer_range_ = smooth_outer_range;
Shinya Kitaoka 120a6e
    this->polygon_number_     = polygon_number;
Shinya Kitaoka 120a6e
    this->roll_degree_        = roll_degree;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    this->min_sw_             = min_sw;
Shinya Kitaoka 120a6e
    this->alpha_rendering_sw_ = alpha_rendering_sw;
Shinya Kitaoka 120a6e
    this->add_blend_sw_       = add_blend_sw;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    igs::maxmin::slrender::resize(
Shinya Kitaoka 120a6e
        static_cast<int>(this->lens_offsets_p_->size()), this->width_,</int>
Shinya Kitaoka 120a6e
        (ref != 0 || 4 <= channels) ? true : false, this->pixe_tracks_,
Shinya Kitaoka 120a6e
        this->alpha_ref_, this->result_);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void run(void) { /* threadで実行する部分 */
Shinya Kitaoka 120a6e
    bool rgb_ren_sw = true;
Shinya Kitaoka 120a6e
    bool alp_ren_sw = this->alpha_rendering_sw_;
Shinya Kitaoka 120a6e
    bool add_ble_sw = this->add_blend_sw_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /* 小さいすぎて処理しない */
Shinya Kitaoka 120a6e
    if (this->pixe_tracks_.size() <= 1) {
Shinya Kitaoka 120a6e
      rgb_ren_sw = false;
Shinya Kitaoka 120a6e
      alp_ren_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
    if (igs::image::rgba::siz == this->channels_) {
Shinya Kitaoka 120a6e
      using namespace igs::image::rgba;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, alp, alp_ren_sw, false);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, blu, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, gre, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, red, rgb_ren_sw, add_ble_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 (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, blu, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, gre, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, red, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (1 == this->channels_) { /* grayscale */
Shinya Kitaoka 120a6e
      for (int yy = this->y_begin_; yy <= this->y_end_; ++yy) {
Shinya Kitaoka 120a6e
        this->rendering_sl_ch_(yy, 0, rgb_ren_sw, add_ble_sw);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  void clear(void) {
Shinya Kitaoka 120a6e
    igs::maxmin::slrender::clear(this->pixe_tracks_, this->alpha_ref_,
Shinya Kitaoka 120a6e
                                 this->result_);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  const IT *inn_;
Shinya Kitaoka 120a6e
  IT *out_;
Shinya Kitaoka 120a6e
  int height_;
Shinya Kitaoka 120a6e
  int width_;
Shinya Kitaoka 120a6e
  int channels_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const RT *ref_;
Shinya Kitaoka 120a6e
  int ref_mode_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int y_begin_;
Shinya Kitaoka 120a6e
  int y_end_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<int> *lens_offsets_p_;</int>
Shinya Kitaoka 120a6e
  std::vector<int> *lens_sizes_p_;</int>
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> *lens_ratio_p_;</std::vector<double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double radius_;
Shinya Kitaoka 120a6e
  double smooth_outer_range_;
Shinya Kitaoka 120a6e
  int polygon_number_;
Shinya Kitaoka 120a6e
  double roll_degree_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool min_sw_;
Shinya Kitaoka 120a6e
  bool alpha_rendering_sw_;
Shinya Kitaoka 120a6e
  bool add_blend_sw_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> pixe_tracks_;</std::vector<double>
Shinya Kitaoka 120a6e
  std::vector<double> alpha_ref_;</double>
Shinya Kitaoka 120a6e
  std::vector<double> result_;</double>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void rendering_sl_ch_(const int yy, const int zz, const bool render_sw,
Shinya Kitaoka 120a6e
                        const bool add_blend_sw) {
Shinya Kitaoka 120a6e
    if (!render_sw) {
Shinya Kitaoka 120a6e
      igs::maxmin::getput::copy(this->inn_, this->height_, this->width_,
Shinya Kitaoka 120a6e
                                this->channels_, yy, zz, this->out_);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (yy == this->y_begin_) {
Shinya Kitaoka 120a6e
      igs::maxmin::getput::get_first(
Shinya Kitaoka 120a6e
          this->inn_, this->out_, this->height_, this->width_, this->channels_,
Shinya Kitaoka 120a6e
          this->ref_, this->ref_mode_, yy, zz,
Shinya Kitaoka 120a6e
          static_cast<int>(this->pixe_tracks_.size() / 2), add_blend_sw,</int>
Shinya Kitaoka 120a6e
          this->pixe_tracks_, this->alpha_ref_, this->result_);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      igs::maxmin::slrender::shift(this->pixe_tracks_);
Shinya Kitaoka 120a6e
      igs::maxmin::getput::get_next(
Shinya Kitaoka 120a6e
          this->inn_, this->out_, this->height_, this->width_, this->channels_,
Shinya Kitaoka 120a6e
          this->ref_, this->ref_mode_, yy, zz,
Shinya Kitaoka 120a6e
          static_cast<int>(this->pixe_tracks_.size() / 2), add_blend_sw,</int>
Shinya Kitaoka 120a6e
          this->pixe_tracks_, this->alpha_ref_, this->result_);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    igs::maxmin::slrender::render(
Shinya Kitaoka 120a6e
        this->radius_, this->smooth_outer_range_, this->polygon_number_,
Shinya Kitaoka 120a6e
        this->roll_degree_, this->min_sw_, *(this->lens_offsets_p_),
Shinya Kitaoka 120a6e
        *(this->lens_sizes_p_), *(this->lens_ratio_p_), this->pixe_tracks_,
Shinya Kitaoka 120a6e
        this->alpha_ref_, this->result_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    igs::maxmin::getput::put(this->result_, this->height_, this->width_,
Shinya Kitaoka 120a6e
                             this->channels_, yy, zz, this->out_);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "igs_maxmin_lens_matrix.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace igs {
Shinya Kitaoka 120a6e
namespace maxmin {
Toshihiro Shimizu 890ddd
template <class class="" it,="" rt=""></class>
Shinya Kitaoka 120a6e
class multithread {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  multithread(
Shinya Kitaoka 120a6e
      /* 入出力画像 */
Shinya Kitaoka 120a6e
      const IT *inn, IT *out, const int height, const int width,
Shinya Kitaoka 120a6e
      const int channels
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Pixel毎に効果の強弱 */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const RT *ref /* 求める画像(out)と同じ高、幅、チャンネル数 */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const int ref_mode /* 0=R,1=G,2=B,3=A,4=Luminance,5=Nothing */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Action Geometry */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const double radius /* =1.0  0..100...DOUBLE_MAX */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const double smooth_outer_range /*=1.0  0..100...DOUBLE_MAX */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const int polygon_number /* =2    2...16...INT_MAX */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const double roll_degree /* =0.0  0...360...DOUBLE_MAX */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Action Type */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const bool min_sw /* =false */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const bool alpha_rendering_sw /* =true */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const bool add_blend_sw /* =false */
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      /* Speed up */
Shinya Kitaoka 120a6e
      ,
Shinya Kitaoka 120a6e
      const int number_of_thread /* =1    1...24...INT_MAX */
Shinya Kitaoka 120a6e
      ) {
Shinya Kitaoka 120a6e
    /*--------------メモリ確保--------------------------*/
Shinya Kitaoka 120a6e
    igs::maxmin::alloc_and_shape_lens_matrix(
Shinya Kitaoka 120a6e
        radius, radius + smooth_outer_range, polygon_number, roll_degree,
Shinya Kitaoka 120a6e
        this->lens_offsets_, this->lens_sizes_, this->lens_ratio_);
Shinya Kitaoka 120a6e
    /*-------スレッド毎の処理指定-----------------------*/
Shinya Kitaoka 120a6e
    int thread_num = number_of_thread;
Shinya Kitaoka 120a6e
    /* ゼロ以下の場合強制変更。そもそもGUIでエラーにすべき */
Shinya Kitaoka 120a6e
    if (thread_num < 1) {
Shinya Kitaoka 120a6e
      thread_num = 1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /* 高さより多い場合強制変更。そもそもGUIでエラーにすべき */
Shinya Kitaoka 120a6e
    if (height < thread_num) {
Shinya Kitaoka 120a6e
      thread_num = height;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    /* threadメモリ確保 */
Shinya Kitaoka 120a6e
    this->threads_.resize(thread_num);
Shinya Kitaoka 120a6e
    /* thread set */
Shinya Kitaoka 120a6e
    int yy = 0;
Shinya Kitaoka 120a6e
    for (int ii = 0; ii < thread_num; ++ii) {
Shinya Kitaoka 120a6e
      const int y_end =
Shinya Kitaoka 120a6e
          static_cast<int>(static_cast<double>(height) * (ii + 1) / thread_num +</double></int>
Shinya Kitaoka 120a6e
                           0.999999) -
Shinya Kitaoka 120a6e
          1;
Shinya Kitaoka 120a6e
      this->threads_.at(ii).setup(
Shinya Kitaoka 120a6e
          inn, out, height, width, channels, ref, ref_mode, yy, y_end,
Shinya Kitaoka 120a6e
          &(this->lens_offsets_), &(this->lens_sizes_), &(this->lens_ratio_)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
                                                            ,
Shinya Kitaoka 120a6e
          radius, smooth_outer_range, polygon_number, roll_degree
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          ,
Shinya Kitaoka 120a6e
          min_sw, alpha_rendering_sw, add_blend_sw);
Shinya Kitaoka 120a6e
      yy = y_end;
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_ratio_.clear();
Shinya Kitaoka 120a6e
    this->lens_sizes_.clear();
Shinya Kitaoka 120a6e
    this->lens_offsets_.clear();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  std::vector<int> lens_offsets_;</int>
Shinya Kitaoka 120a6e
  std::vector<int> lens_sizes_;</int>
Shinya Kitaoka 120a6e
  std::vector<std::vector<double>> lens_ratio_;</std::vector<double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<igs::maxmin::thread<it, rt="">> threads_;</igs::maxmin::thread<it,>
Shinya Kitaoka 120a6e
  igs::resource::multithread mthread_;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif /* !igs_maxmin_multithread_h */