Toshihiro Shimizu 890ddd
#include <vector></vector>
Toshihiro Shimizu 890ddd
#include <stdexcept>		/* std::domain_error(-) */</stdexcept>
Toshihiro Shimizu 890ddd
#include <limits>			/* std::numeric_limits */</limits>
Toshihiro Shimizu 890ddd
#include <cmath>			/* pow(-),abs(-) */</cmath>
Campbell Barton 107701
#include <cstring>			/* memmove */</cstring>
Toshihiro Shimizu 890ddd
#include "igs_ifx_common.h" /* igs::image::rgba */
Toshihiro Shimizu 890ddd
#include "igs_motion_blur.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// #include <numeric> /* std::accumulate(-) */</numeric>
Toshihiro Shimizu 890ddd
#if 0  //------comment out-----------------------------------------------
Toshihiro Shimizu 890ddd
namespace {
Toshihiro Shimizu 890ddd
 void dda_array_(
Toshihiro Shimizu 890ddd
	const int dx,	/* = abs(x_vector = x2 - x1) */
Toshihiro Shimizu 890ddd
	const int dy, /* = abs(y_vector = y2 - y1) = array_size - 1 */
Toshihiro Shimizu 890ddd
	std::vector<int>&y_array	/* array_size(0...dy)個ある */</int>
Toshihiro Shimizu 890ddd
 ) {
Toshihiro Shimizu 890ddd
	/* ここではy方向に傾いている場合(dx <= dy)のみ扱う
Toshihiro Shimizu 890ddd
	    y +      *
Toshihiro Shimizu 890ddd
	  (dy)|     *
Toshihiro Shimizu 890ddd
	      |    *
Toshihiro Shimizu 890ddd
	      |   *
Toshihiro Shimizu 890ddd
	  OUT +   *
Toshihiro Shimizu 890ddd
	      |  *
Toshihiro Shimizu 890ddd
	      | *
Toshihiro Shimizu 890ddd
	      |*
Toshihiro Shimizu 890ddd
	    0 +---+---+---+
Toshihiro Shimizu 890ddd
	      0           x(dx)
Toshihiro Shimizu 890ddd
		   IN
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	if (dy < dx) { return; } /* x方向に傾いていると処理できない */
Toshihiro Shimizu 890ddd
	if (dy <= 0) { return; } /* y長さがないと処理しない */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	y_array.at(0) = 0; /* 始めは原点なのでインクリメントはゼロ */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* 線分ループ */
Toshihiro Shimizu 890ddd
	const int incr1 = 2 * dx;
Toshihiro Shimizu 890ddd
	const int incr2 = 2 * (dx - dy);
Toshihiro Shimizu 890ddd
	int dd = (2 * dx) - dy;
Toshihiro Shimizu 890ddd
	for (int ii = 1; ii <= dy; ++ii) {
Toshihiro Shimizu 890ddd
		if (dd < 0) { dd += incr1; y_array.at(ii) = 0; }
Toshihiro Shimizu 890ddd
		else        { dd += incr2; y_array.at(ii) = 1; }
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
 }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
namespace {
Toshihiro Shimizu 890ddd
 void set_position_(
Toshihiro Shimizu 890ddd
	const int x_vector,
Toshihiro Shimizu 890ddd
	const int y_vector,/* 絶対値の大きいほうが"size-1" */
Toshihiro Shimizu 890ddd
	std::vector<int>&x_array,</int>
Toshihiro Shimizu 890ddd
	std::vector<int>&y_array /* 位置格納配列size個ある */</int>
Toshihiro Shimizu 890ddd
 ) {
Toshihiro Shimizu 890ddd
	int dx = abs(x_vector);/* 線分の幅、ゼロ以上の大きさの数 */
Toshihiro Shimizu 890ddd
	int dy = abs(y_vector);/* 線分の高さ、ゼロ以上の大きさの数 */
Toshihiro Shimizu 890ddd
	int count = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* x方向に傾いている場合(dy < dx)
Toshihiro Shimizu 890ddd
	     y +        *
Toshihiro Shimizu 890ddd
	   (dy)|       *
Toshihiro Shimizu 890ddd
	       |      *
Toshihiro Shimizu 890ddd
	       |     *
Toshihiro Shimizu 890ddd
	   OUT +   *
Toshihiro Shimizu 890ddd
	       |  *
Toshihiro Shimizu 890ddd
	       | *
Toshihiro Shimizu 890ddd
	       |*
Toshihiro Shimizu 890ddd
	     0 +---+---+---+
Toshihiro Shimizu 890ddd
	       0           x(dx)
Toshihiro Shimizu 890ddd
                    IN
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	if (dy < dx) {
Toshihiro Shimizu 890ddd
	 for (int ii=0;ii<=dx;++ii) {x_array.at(ii) = ii;}
Toshihiro Shimizu 890ddd
	 dda_array_( dy, dx, y_array );
Toshihiro Shimizu 890ddd
	 for (int ii=1;ii<=dx;++ii) {y_array.at(ii)+=y_array.at(ii-1);}
Toshihiro Shimizu 890ddd
	 count = dx;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* y方向に傾いている場合(dx <= dy)
Toshihiro Shimizu 890ddd
	    y +      *
Toshihiro Shimizu 890ddd
	  (dy)|     *
Toshihiro Shimizu 890ddd
	      |    *
Toshihiro Shimizu 890ddd
	      |   *
Toshihiro Shimizu 890ddd
	  OUT +   *
Toshihiro Shimizu 890ddd
	      |  *
Toshihiro Shimizu 890ddd
	      | *
Toshihiro Shimizu 890ddd
	      |*
Toshihiro Shimizu 890ddd
	    0 +---+---+---+
Toshihiro Shimizu 890ddd
	      0           x(dx)
Toshihiro Shimizu 890ddd
                   IN
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
	 for (int ii=0;ii<=dy;++ii) {y_array.at(ii) = ii;}
Toshihiro Shimizu 890ddd
	 dda_array_( dx, dy, x_array );
Toshihiro Shimizu 890ddd
	 for (int ii=1;ii<=dy;++ii) {x_array.at(ii)+=x_array.at(ii-1);}
Toshihiro Shimizu 890ddd
	 count = dy;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* マイナス方向の場合は反転 */
Toshihiro Shimizu 890ddd
	if (x_vector < 0) {
Toshihiro Shimizu 890ddd
	 for (int ii=1;ii<=count;++ii){x_array.at(ii)=-x_array.at(ii);}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (y_vector < 0) {
Toshihiro Shimizu 890ddd
	 for (int ii=1;ii<=count;++ii){y_array.at(ii)=-y_array.at(ii);}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
 }
Toshihiro Shimizu 890ddd
 void set_ratio_(
Toshihiro Shimizu 890ddd
	const double curve,
Toshihiro Shimizu 890ddd
	std::vector<double>&ratio_array</double>
Toshihiro Shimizu 890ddd
 ) {
Toshihiro Shimizu 890ddd
	const int size = ratio_array.size();
Toshihiro Shimizu 890ddd
	/* リニア配置をする */
Toshihiro Shimizu 890ddd
	for (int ii = 0; ii < size; ++ii) {
Toshihiro Shimizu 890ddd
		ratio_array.at(ii) = ((double)(size-ii))/(double)(size);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* カーブを設定(ガンマ計算) */
Toshihiro Shimizu 890ddd
	if (curve <= 0.0) {
Toshihiro Shimizu 890ddd
	 for (int ii = 1; ii < size; ++ii) { ratio_array.at(ii) = 0.0; }
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
	if (1.0 != curve) {
Toshihiro Shimizu 890ddd
	 for (int ii = 1; ii < size; ++ii) {
Toshihiro Shimizu 890ddd
		ratio_array.at(ii)=pow(ratio_array.at(ii),1.0/curve);
Toshihiro Shimizu 890ddd
	 }
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 正規化 */
Toshihiro Shimizu 890ddd
	double accum = 0;
Toshihiro Shimizu 890ddd
	for (int ii = 0; ii < size; ++ii) { accum+=ratio_array.at(ii);}
Toshihiro Shimizu 890ddd
	for (int ii = 0; ii < size; ++ii) { ratio_array.at(ii)/=accum;}
Toshihiro Shimizu 890ddd
 }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
namespace {
Toshihiro Shimizu 890ddd
 void set_jaggy_(
Toshihiro Shimizu 890ddd
	const double x_vector,
Toshihiro Shimizu 890ddd
	const double y_vector,
Toshihiro Shimizu 890ddd
	const double vector_scale,
Toshihiro Shimizu 890ddd
	const double curve,
Toshihiro Shimizu 890ddd
	std::vector<double>&ratio_array,</double>
Toshihiro Shimizu 890ddd
	std::vector<int>&x_array,</int>
Toshihiro Shimizu 890ddd
	std::vector<int>&y_array</int>
Toshihiro Shimizu 890ddd
 ) {
Toshihiro Shimizu 890ddd
	if (curve <= 0.0) { return; } /* blur効果なしならなにもしない */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int xv = static_cast<int>(x_vector * vector_scale + 0.5);</int>
Toshihiro Shimizu 890ddd
	int yv = static_cast<int>(y_vector * vector_scale + 0.5);</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int size;
Toshihiro Shimizu 890ddd
	if (abs(xv) <= abs(yv))	{ size = abs(yv) + 1; }
Toshihiro Shimizu 890ddd
	else			{ size = abs(xv) + 1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ratio_array.resize(size);
Toshihiro Shimizu 890ddd
	x_array.resize(size);
Toshihiro Shimizu 890ddd
	y_array.resize(size);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	set_ratio_( curve, ratio_array );
Toshihiro Shimizu 890ddd
	set_position_( xv, yv, x_array,y_array );
Toshihiro Shimizu 890ddd
 }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif //------comment out----------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifndef M_PI
Toshihiro Shimizu 890ddd
#define M_PI 3.14159265358979323846
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
void vec_poi_to_len_pos_(
Toshihiro Shimizu 890ddd
	const double xv,
Toshihiro Shimizu 890ddd
	const double yv, /* vector */
Toshihiro Shimizu 890ddd
	const double xp,
Toshihiro Shimizu 890ddd
	const double yp, /* point */
Toshihiro Shimizu 890ddd
	double &len,	 /* vectorからpointまでの距離 */
Toshihiro Shimizu 890ddd
	double &pos		 /* vector方向でvector原点からpointまでの距離 */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	 * ベクトルの角度を求める
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double radian = 0.0;
Toshihiro Shimizu 890ddd
	/* ゼロエラー */
Toshihiro Shimizu 890ddd
	if ((0.0 == xv) && (0.0 == yv)) {
Toshihiro Shimizu 890ddd
		len = 0.0;
Toshihiro Shimizu 890ddd
		pos = 0.0;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 第1象限(0 <= degree < 90)*/
Toshihiro Shimizu 890ddd
	else if ((0.0 < xv) && (0.0 <= yv)) {
Toshihiro Shimizu 890ddd
		radian = atan(yv / xv);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 第2象限(90 <= degree < 180) */
Toshihiro Shimizu 890ddd
	else if ((xv <= 0.0) && (0.0 < yv)) {
Toshihiro Shimizu 890ddd
		radian = atan(-xv / yv) + M_PI / 2.0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 第3象限(180 <= degree < 270) */
Toshihiro Shimizu 890ddd
	else if ((xv < 0.0) && (yv <= 0.0)) {
Toshihiro Shimizu 890ddd
		radian = atan(yv / xv) + M_PI;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 第4象限(270 <= degree < 360(=0)) */
Toshihiro Shimizu 890ddd
	else if ((0.0 <= xv) && (yv < 0.0)) {
Toshihiro Shimizu 890ddd
		radian = atan(xv / -yv) + M_PI + M_PI / 2.0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	 * 逆回転し、ベクトルを+X軸上に置く
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* ベクトルを逆回転し、x軸プラス上に置く */
Toshihiro Shimizu 890ddd
	double xv_rot = xv * cos(-radian) - yv * sin(-radian);
Toshihiro Shimizu 890ddd
	// double yv_rot = xv * sin(-radian) + yv * cos(-radian);
Toshihiro Shimizu 890ddd
	/* ターゲット点も同様に逆回転する */
Toshihiro Shimizu 890ddd
	double xp_rot = xp * cos(-radian) - yp * sin(-radian);
Toshihiro Shimizu 890ddd
	double yp_rot = xp * sin(-radian) + yp * cos(-radian);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	 * vectorからpointまでの距離
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* マイナス(原点より小さい)の場合、ベクトル始点からの距離 */
Toshihiro Shimizu 890ddd
	if (xp_rot < 0.0) {
Toshihiro Shimizu 890ddd
		len = sqrt((xp * xp) + (yp * yp));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* ベクトルより大きい場合、ベクトル終点からの距離 */
Toshihiro Shimizu 890ddd
	else if (xv_rot < xp_rot) {
Toshihiro Shimizu 890ddd
		len = sqrt((xp - xv) * (xp - xv) +
Toshihiro Shimizu 890ddd
				   (yp - yv) * (yp - yv));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* ベクトルの横範囲内なら、上下位置が距離となる */
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		len = fabs(yp_rot);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	 * vector方向でvector原点からpointまでの距離
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pos = xp_rot;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
/* ベクトルからの指定範囲でサブピクセルがどのくらい含むかカウントする
Toshihiro Shimizu 890ddd
	ピクセルの位置は以下の図参照
Toshihiro Shimizu 890ddd
	  y
Toshihiro Shimizu 890ddd
	  ^
Toshihiro Shimizu 890ddd
	  |
Toshihiro Shimizu 890ddd
	  |
Toshihiro Shimizu 890ddd
	  |
Toshihiro Shimizu 890ddd
	  |
Toshihiro Shimizu 890ddd
	+---+
Toshihiro Shimizu 890ddd
	| | |
Toshihiro Shimizu 890ddd
	| +-|-------------------> x
Toshihiro Shimizu 890ddd
	|   |
Toshihiro Shimizu 890ddd
	+---+
Toshihiro Shimizu 890ddd
 */
Toshihiro Shimizu 890ddd
int count_nearly_vector_(
Toshihiro Shimizu 890ddd
	const double xv,
Toshihiro Shimizu 890ddd
	const double yv, /* vector */
Toshihiro Shimizu 890ddd
	const double x_tgt,
Toshihiro Shimizu 890ddd
	const double y_tgt, /* 調査(vectorの原点からの)pixel位置 */
Toshihiro Shimizu 890ddd
	const long x_div,
Toshihiro Shimizu 890ddd
	const long y_div,	  /* 調査pixelを分割する(サブpixel)数 */
Toshihiro Shimizu 890ddd
	const double valid_len /* vectorからの有効距離 */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = 0;
Toshihiro Shimizu 890ddd
	for (int yy = 0; yy < y_div; ++yy) {
Toshihiro Shimizu 890ddd
		for (int xx = 0; xx < x_div; ++xx) {
Toshihiro Shimizu 890ddd
			double xp = x_tgt + (double)xx / x_div - (0.5 - 0.5 / x_div);
Toshihiro Shimizu 890ddd
			double yp = y_tgt + (double)yy / y_div - (0.5 - 0.5 / y_div);
Toshihiro Shimizu 890ddd
			double len = 0.0;
Toshihiro Shimizu 890ddd
			double pos = 0.0;
Toshihiro Shimizu 890ddd
			vec_poi_to_len_pos_(xv, yv, xp, yp, len, pos);
Toshihiro Shimizu 890ddd
			if (len < valid_len) {
Toshihiro Shimizu 890ddd
				++count;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return count;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/* リニア減衰計算 */
Toshihiro Shimizu 890ddd
double liner_decrement_(
Toshihiro Shimizu 890ddd
	const double xv,
Toshihiro Shimizu 890ddd
	const double yv, /* vector */
Toshihiro Shimizu 890ddd
	const double x_tgt,
Toshihiro Shimizu 890ddd
	const double y_tgt, /* 調査(vectorの原点からの)pixel位置 */
Toshihiro Shimizu 890ddd
	const long x_div,
Toshihiro Shimizu 890ddd
	const long y_div,	  /* 調査pixelを分割する(サブpixel)数 */
Toshihiro Shimizu 890ddd
	const double valid_len /* vectorからの有効距離 */
Toshihiro Shimizu 890ddd
	)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = 0;
Toshihiro Shimizu 890ddd
	double accum = 0.0;
Toshihiro Shimizu 890ddd
	const double line_len = sqrt(xv * xv + yv * yv) + valid_len;
Toshihiro Shimizu 890ddd
	for (int yy = 0; yy < y_div; ++yy) {
Toshihiro Shimizu 890ddd
		for (int xx = 0; xx < x_div; ++xx) {
Toshihiro Shimizu 890ddd
			double xp = x_tgt + (double)xx / x_div - (0.5 - 0.5 / x_div);
Toshihiro Shimizu 890ddd
			double yp = y_tgt + (double)yy / y_div - (0.5 - 0.5 / y_div);
Toshihiro Shimizu 890ddd
			double len = 0.0;
Toshihiro Shimizu 890ddd
			double pos = 0.0;
Toshihiro Shimizu 890ddd
			vec_poi_to_len_pos_(xv, yv, xp, yp, len, pos);
Toshihiro Shimizu 890ddd
			if (len < valid_len) {
Toshihiro Shimizu 890ddd
				++count;
Toshihiro Shimizu 890ddd
				/* 下の式ではマイナスにはならない */
Toshihiro Shimizu 890ddd
				accum += 1.0 - fabs(pos) / line_len;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (count <= 0) {
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	} /* 念のためチェック */
Toshihiro Shimizu 890ddd
	return accum / (double)count;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
/* ぶれ画像計算 */
Toshihiro Shimizu 890ddd
double bure_decrement_(
Toshihiro Shimizu 890ddd
	const double xv,
Toshihiro Shimizu 890ddd
	const double yv, /* vector */
Toshihiro Shimizu 890ddd
	const double x_tgt,
Toshihiro Shimizu 890ddd
	const double y_tgt, /* 調査(vectorの原点からの)pixel位置 */
Toshihiro Shimizu 890ddd
	const long x_div,
Toshihiro Shimizu 890ddd
	const long y_div,		/* 調査pixelを分割する(サブpixel)数 */
Toshihiro Shimizu 890ddd
	const double valid_len, /* vectorからの有効距離 */
Toshihiro Shimizu 890ddd
	const int zanzo_length)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	long count_in = 0;
Toshihiro Shimizu 890ddd
	long count_out = 0;
Toshihiro Shimizu 890ddd
	double pos = 0.0;
Toshihiro Shimizu 890ddd
	for (int yy = 0; yy < y_div; ++yy) {
Toshihiro Shimizu 890ddd
		for (int xx = 0; xx < x_div; ++xx) {
Toshihiro Shimizu 890ddd
			double xp = x_tgt + (double)xx / x_div - (0.5 - 0.5 / x_div);
Toshihiro Shimizu 890ddd
			double yp = y_tgt + (double)yy / y_div - (0.5 - 0.5 / y_div);
Toshihiro Shimizu 890ddd
			double len = 0.0;
Toshihiro Shimizu 890ddd
			pos = 0.0;
Toshihiro Shimizu 890ddd
			vec_poi_to_len_pos_(xv, yv, xp, yp, len, pos);
Toshihiro Shimizu 890ddd
			if (len < valid_len) {
Toshihiro Shimizu 890ddd
				if (0 == ((int)pos % zanzo_length)) {
Toshihiro Shimizu 890ddd
					++count_in;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					++count_out;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* 有効距離内にない場合ゼロを返す。念のためチェック */
Toshihiro Shimizu 890ddd
	if ((count_in + count_out) <= 0) {
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* 距離で計算するのでマイナス位置では意味がない */
Toshihiro Shimizu 890ddd
	if (pos < 0.0) {
Toshihiro Shimizu 890ddd
		pos = -pos;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
		pos が line_len より大きい場合がある。
Toshihiro Shimizu 890ddd
		そのため、pos / line_lenが、1より大きくなり、
Toshihiro Shimizu 890ddd
		それゆえ、1.0 - pos / line_lenが、マイナスとなる。
Toshihiro Shimizu 890ddd
		マイナスを返してはいけないのでそのための処理
Toshihiro Shimizu 890ddd
	*/
Toshihiro Shimizu 890ddd
	const double line_len = sqrt(xv * xv + yv * yv) + valid_len;
Toshihiro Shimizu 890ddd
	if (line_len < pos) {
Toshihiro Shimizu 890ddd
		pos = line_len;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* ????????????????? */
Toshihiro Shimizu 890ddd
	return (double)count_in / (count_in + count_out) *
Toshihiro Shimizu 890ddd
		   (1.0 - pos / line_len);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
void set_smooth_(
Toshihiro Shimizu 890ddd
	const double x_vector,
Toshihiro Shimizu 890ddd
	const double y_vector,
Toshihiro Shimizu 890ddd
	const double vector_scale,
Toshihiro Shimizu 890ddd
	const double curve,
Toshihiro Shimizu 890ddd
	const int zanzo_length,
Toshihiro Shimizu 890ddd
	const double zanzo_power,
Toshihiro Shimizu 890ddd
	std::vector<double> &ratio_array,</double>
Toshihiro Shimizu 890ddd
	std::vector<int> &x_array,</int>
Toshihiro Shimizu 890ddd
	std::vector<int> &y_array)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/* blur効果なしならなにもしない */
Toshihiro Shimizu 890ddd
	if (curve <= 0.0) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* ベクトルの実の長さ */
Toshihiro Shimizu 890ddd
	double xv = x_vector * vector_scale;
Toshihiro Shimizu 890ddd
	double yv = y_vector * vector_scale;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* vectorの長さがゼロならなにもしない */
Toshihiro Shimizu 890ddd
	if ((0.0 == xv) && (0.0 == yv)) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* vectorの始点と終点のpixel位置 */
Toshihiro Shimizu 890ddd
	int x1, y1, x2, y2;
Toshihiro Shimizu 890ddd
	if (0.0 <= xv) {
Toshihiro Shimizu 890ddd
		x1 = 0;
Toshihiro Shimizu 890ddd
		x2 = (int)xv + 2;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		x1 = (int)xv - 2;
Toshihiro Shimizu 890ddd
		x2 = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (0.0 <= yv) {
Toshihiro Shimizu 890ddd
		y1 = 0;
Toshihiro Shimizu 890ddd
		y2 = (int)yv + 2;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		y1 = (int)yv - 2;
Toshihiro Shimizu 890ddd
		y2 = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* smooth線にかかるsubpixel数をカウント */
Toshihiro Shimizu 890ddd
	int size = 0;
Toshihiro Shimizu 890ddd
	for (int yy = y1; yy <= y2; ++yy) {
Toshihiro Shimizu 890ddd
		for (int xx = x1; xx <= x2; ++xx) {
Toshihiro Shimizu 890ddd
			if (0 < count_nearly_vector_(
Toshihiro Shimizu 890ddd
						xv, yv, (double)xx, (double)yy, 16, 16, 0.5)) {
Toshihiro Shimizu 890ddd
				++size;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* カウント0以下では、blur効果がない */
Toshihiro Shimizu 890ddd
	if (size <= 0) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* バッファメモリ確保 */
Toshihiro Shimizu 890ddd
	ratio_array.resize(size);
Toshihiro Shimizu 890ddd
	x_array.resize(size);
Toshihiro Shimizu 890ddd
	y_array.resize(size);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* 位置とピクセル値(0
Toshihiro Shimizu 890ddd
	int ii = 0;
Toshihiro Shimizu 890ddd
	for (int yy = y1; yy <= y2; ++yy) {
Toshihiro Shimizu 890ddd
		for (int xx = x1; xx <= x2; ++xx) {
Toshihiro Shimizu 890ddd
			const int count = count_nearly_vector_(
Toshihiro Shimizu 890ddd
				xv, yv, (double)xx, (double)yy, 16, 16, 0.5);
Toshihiro Shimizu 890ddd
			if (0 < count) {
Toshihiro Shimizu 890ddd
				ratio_array.at(ii) = (double)count / (16 * 16);
Toshihiro Shimizu 890ddd
				x_array.at(ii) = xx;
Toshihiro Shimizu 890ddd
				y_array.at(ii) = yy;
Toshihiro Shimizu 890ddd
				++ii;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* リニア減衰効果 */
Toshihiro Shimizu 890ddd
	for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
		ratio_array.at(ii) *= liner_decrement_(
Toshihiro Shimizu 890ddd
			xv, yv,
Toshihiro Shimizu 890ddd
			(double)(x_array.at(ii)),
Toshihiro Shimizu 890ddd
			(double)(y_array.at(ii)), 16, 16, 0.5);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* 段々の分割指定があれば設定する */
Toshihiro Shimizu 890ddd
	if (0 < zanzo_length) {
Toshihiro Shimizu 890ddd
		/* ぶれ残像減衰効果 */
Toshihiro Shimizu 890ddd
		for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
			ratio_array.at(ii) =
Toshihiro Shimizu 890ddd
				(1.0 - zanzo_power) * ratio_array.at(ii) +
Toshihiro Shimizu 890ddd
				zanzo_power * bure_decrement_(
Toshihiro Shimizu 890ddd
								  xv, yv,
Toshihiro Shimizu 890ddd
								  (double)(x_array.at(ii)),
Toshihiro Shimizu 890ddd
								  (double)(y_array.at(ii)),
Toshihiro Shimizu 890ddd
								  16, 16, 0.5, zanzo_length);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* vector始点は1とする */
Toshihiro Shimizu 890ddd
	for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
		if ((0 == x_array.at(ii)) && (0 == y_array.at(ii))) {
Toshihiro Shimizu 890ddd
			ratio_array.at(ii) = 1.0;
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* ガンマ強弱計算 */
Toshihiro Shimizu 890ddd
	if (1.0 != curve) { /* 0.0以下の値のとき既にreturnしてる */
Toshihiro Shimizu 890ddd
		for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
			ratio_array.at(ii) = pow(ratio_array.at(ii), 1.0 / curve);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	/* 正規化 */
Toshihiro Shimizu 890ddd
	double d_accum = 0.0;
Toshihiro Shimizu 890ddd
	for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
		d_accum += ratio_array.at(ii);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
		ratio_array.at(ii) /= d_accum;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
T pixel_value(
Toshihiro Shimizu 890ddd
	const T *image_array,
Toshihiro Shimizu 890ddd
	const int height,
Toshihiro Shimizu 890ddd
	const int width,
Toshihiro Shimizu 890ddd
	const int channels,
Toshihiro Shimizu 890ddd
	const int xx,
Toshihiro Shimizu 890ddd
	const int yy,
Toshihiro Shimizu 890ddd
	const int zz,
Toshihiro Shimizu 890ddd
	const std::vector<double> &ratio_array,</double>
Toshihiro Shimizu 890ddd
	const std::vector<int> &x_array,</int>
Toshihiro Shimizu 890ddd
	const std::vector<int> &y_array)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double ratio_accum = 0.0;
Toshihiro Shimizu 890ddd
	double accum = 0.0;
Toshihiro Shimizu 890ddd
	for (unsigned int ii = 0; ii < ratio_array.size(); ++ii) {
Toshihiro Shimizu 890ddd
		const int xp = xx + x_array.at(ii);
Toshihiro Shimizu 890ddd
		const int yp = yy + y_array.at(ii);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (xp < 0) {
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (yp < 0) {
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (width <= xp) {
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (height <= yp) {
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ratio_accum += ratio_array.at(ii);
Toshihiro Shimizu 890ddd
		accum += ratio_array.at(ii) * static_cast<double>(*(</double>
Toshihiro Shimizu 890ddd
										  image_array +
Toshihiro Shimizu 890ddd
										  channels * width * yp +
Toshihiro Shimizu 890ddd
										  channels * xp +
Toshihiro Shimizu 890ddd
										  zz));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* can not calculate */
Toshihiro Shimizu 890ddd
	if (0.0 == ratio_accum) {
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/* overflowはありえない(ratio_arrayを正規化してあるため) */
Toshihiro Shimizu 890ddd
	/*if ((accum/ratio_accum) <= 0.0) { return 0; }
Toshihiro Shimizu 890ddd
	if ((USHORT)0xffff <= (USHORT)(accum/ratio_accum)) {
Toshihiro Shimizu 890ddd
		return (unsigned short)0xffff;
Toshihiro Shimizu 890ddd
	}*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return static_cast<t>(accum / ratio_accum + 0.5);</t>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void convert_template_(
Toshihiro Shimizu 890ddd
	const T *in,
Toshihiro Shimizu 890ddd
	T *image_out,
Toshihiro Shimizu 890ddd
	const int hh,
Toshihiro Shimizu 890ddd
	const int ww,
Toshihiro Shimizu 890ddd
	const int cc,
Toshihiro Shimizu 890ddd
	const std::vector<double> &ra,</double>
Toshihiro Shimizu 890ddd
	const std::vector<int> &xa,</int>
Toshihiro Shimizu 890ddd
	const std::vector<int> &ya,</int>
Toshihiro Shimizu 890ddd
	const bool alpha_rend_sw)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/* 効果なしならimageをcopyして終る */
Toshihiro Shimizu 890ddd
	if (ra.size() <= 0) {
Toshihiro Shimizu 890ddd
		memmove(image_out, in, hh * ww * cc * sizeof(T));
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (igs::image::rgba::siz == cc) { /* Alphaがある */
Toshihiro Shimizu 890ddd
		using namespace igs::image::rgba;
Toshihiro Shimizu 890ddd
		if (alpha_rend_sw) { /* Alphaも処理する */
Toshihiro Shimizu 890ddd
			const T *p_in = in;
Toshihiro Shimizu 890ddd
			T *pout = image_out;
Toshihiro Shimizu 890ddd
			for (int yy = 0; yy < hh; ++yy) {
Toshihiro Shimizu 890ddd
				for (int xx = 0; xx < ww; ++xx, p_in += cc, pout += cc) {
Toshihiro Shimizu 890ddd
					/*Alpha処理-->*/ pout[alp] = pixel_value(in, hh, ww, cc, xx, yy, alp, ra, xa, ya);
Toshihiro Shimizu 890ddd
					if (0 == pout[alp]) { /* AlphaがゼロならRGB処理しない */
Toshihiro Shimizu 890ddd
						pout[red] = p_in[red];
Toshihiro Shimizu 890ddd
						pout[gre] = p_in[gre];
Toshihiro Shimizu 890ddd
						pout[blu] = p_in[blu];
Toshihiro Shimizu 890ddd
					} else { /* AlphaがゼロでないときRGB処理する */
Toshihiro Shimizu 890ddd
						pout[red] = pixel_value(in, hh, ww, cc, xx, yy, red, ra, xa, ya);
Toshihiro Shimizu 890ddd
						pout[gre] = pixel_value(in, hh, ww, cc, xx, yy, gre, ra, xa, ya);
Toshihiro Shimizu 890ddd
						pout[blu] = pixel_value(in, hh, ww, cc, xx, yy, blu, ra, xa, ya);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else { /* Alpha処理せず保存のみ */
Toshihiro Shimizu 890ddd
			const T *p_in = in;
Toshihiro Shimizu 890ddd
			T *pout = image_out;
Toshihiro Shimizu 890ddd
			const unsigned int val_max = std::numeric_limits<t>::max();</t>
Toshihiro Shimizu 890ddd
			for (int yy = 0; yy < hh; ++yy) {
Toshihiro Shimizu 890ddd
				for (int xx = 0; xx < ww; ++xx, p_in += cc, pout += cc) {
Toshihiro Shimizu 890ddd
					/*Alpha保存-->*/ pout[alp] = p_in[alp];
Toshihiro Shimizu 890ddd
					if (0 == pout[alp]) { /* AlphaがゼロならRGB処理しない */
Toshihiro Shimizu 890ddd
						pout[red] = p_in[red];
Toshihiro Shimizu 890ddd
						pout[gre] = p_in[gre];
Toshihiro Shimizu 890ddd
						pout[blu] = p_in[blu];
Toshihiro Shimizu 890ddd
					} else { /* AlphaがゼロでないときRGB処理する */
Toshihiro Shimizu 890ddd
						pout[red] = pixel_value(in, hh, ww, cc, xx, yy, red, ra, xa, ya);
Toshihiro Shimizu 890ddd
						pout[gre] = pixel_value(in, hh, ww, cc, xx, yy, gre, ra, xa, ya);
Toshihiro Shimizu 890ddd
						pout[blu] = pixel_value(in, hh, ww, cc, xx, yy, blu, ra, xa, ya);
Toshihiro Shimizu 890ddd
						/* Alphaが0より大きくMaxより小さいとき増分をMaskする */
Toshihiro Shimizu 890ddd
						if (p_in[alp] < val_max) {
Toshihiro Shimizu 890ddd
							const unsigned int aa = static_cast<unsigned int="">(p_in[alp]);</unsigned>
Toshihiro Shimizu 890ddd
							if (p_in[red] < pout[red]) { /* 増分のみMask! */
Toshihiro Shimizu 890ddd
								const unsigned int dif = static_cast<unsigned int="">(pout[red] - p_in[red]);</unsigned>
Toshihiro Shimizu 890ddd
								pout[red] = static_cast<t>(p_in[red] + dif * aa / val_max);</t>
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
							if (p_in[gre] < pout[gre]) { /* 増分のみMask! */
Toshihiro Shimizu 890ddd
								const unsigned int dif = static_cast<unsigned int="">(pout[gre] - p_in[gre]);</unsigned>
Toshihiro Shimizu 890ddd
								pout[gre] = static_cast<t>(p_in[gre] + dif * aa / val_max);</t>
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
							if (p_in[blu] < pout[blu]) { /* 増分のみMask! */
Toshihiro Shimizu 890ddd
								const unsigned int dif = static_cast<unsigned int="">(pout[blu] - p_in[blu]);</unsigned>
Toshihiro Shimizu 890ddd
								pout[blu] = static_cast<t>(p_in[blu] + dif * aa / val_max);</t>
Toshihiro Shimizu 890ddd
							}
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else { /* Alphaがない, RGB/Grayscale... */
Toshihiro Shimizu 890ddd
		T *pout = image_out;
Toshihiro Shimizu 890ddd
		for (int yy = 0; yy < hh; ++yy) {
Toshihiro Shimizu 890ddd
			for (int xx = 0; xx < ww; ++xx, pout += cc) {
Toshihiro Shimizu 890ddd
				for (int zz = 0; zz < cc; ++zz) {
Toshihiro Shimizu 890ddd
					pout[zz] = pixel_value(in, hh, ww, cc, xx, yy, zz, ra, xa, ya);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
void igs::motion_blur::convert(
Toshihiro Shimizu 890ddd
	const unsigned char *image_in,
Toshihiro Shimizu 890ddd
	unsigned char *image_out,
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const int height,
Toshihiro Shimizu 890ddd
	const int width,
Toshihiro Shimizu 890ddd
	const int channels,
Toshihiro Shimizu 890ddd
	const int bits,
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const double x_vector,
Toshihiro Shimizu 890ddd
	const double y_vector,
Toshihiro Shimizu 890ddd
	const double vector_scale,
Toshihiro Shimizu 890ddd
	const double curve,
Toshihiro Shimizu 890ddd
	const int zanzo_length,
Toshihiro Shimizu 890ddd
	const double zanzo_power,
Toshihiro Shimizu 890ddd
	const bool alpha_rend_sw)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::vector<double> ratio_array;</double>
Toshihiro Shimizu 890ddd
	std::vector<int> x_array;</int>
Toshihiro Shimizu 890ddd
	std::vector<int> y_array;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	set_smooth_(
Toshihiro Shimizu 890ddd
		x_vector, y_vector, vector_scale, curve,
Toshihiro Shimizu 890ddd
		zanzo_length, zanzo_power,
Toshihiro Shimizu 890ddd
		ratio_array, x_array, y_array);
Toshihiro Shimizu 890ddd
	/***set_jaggy_(
Toshihiro Shimizu 890ddd
		x_vector, y_vector, vector_scale, curve,
Toshihiro Shimizu 890ddd
		ratio_array, x_array, y_array
Toshihiro Shimizu 890ddd
	);***/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (std::numeric_limits<unsigned char="">::digits == bits) {</unsigned>
Toshihiro Shimizu 890ddd
		convert_template_(
Toshihiro Shimizu 890ddd
			image_in,
Toshihiro Shimizu 890ddd
			image_out,
Toshihiro Shimizu 890ddd
			height, width, channels,
Toshihiro Shimizu 890ddd
			ratio_array, x_array, y_array,
Toshihiro Shimizu 890ddd
			alpha_rend_sw);
Toshihiro Shimizu 890ddd
		y_array.clear();
Toshihiro Shimizu 890ddd
		x_array.clear();
Toshihiro Shimizu 890ddd
		ratio_array.clear();
Toshihiro Shimizu 890ddd
	} else if (std::numeric_limits<unsigned short="">::digits == bits) {</unsigned>
Toshihiro Shimizu 890ddd
		convert_template_(
Toshihiro Shimizu 890ddd
			reinterpret_cast<const *="" short="" unsigned="">(image_in),</const>
Toshihiro Shimizu 890ddd
			reinterpret_cast<unsigned *="" short="">(image_out),</unsigned>
Toshihiro Shimizu 890ddd
			height, width, channels,
Toshihiro Shimizu 890ddd
			ratio_array, x_array, y_array,
Toshihiro Shimizu 890ddd
			alpha_rend_sw);
Toshihiro Shimizu 890ddd
		y_array.clear();
Toshihiro Shimizu 890ddd
		x_array.clear();
Toshihiro Shimizu 890ddd
		ratio_array.clear();
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		throw std::domain_error("Bad bits,Not uchar/ushort");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}