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