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