Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tmachine.h"
Toshihiro Shimizu 890ddd
#include "tpixelgr.h"
Toshihiro Shimizu 890ddd
#include "quickputP.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#include "tspecialstyleid.h"
Toshihiro Shimizu 890ddd
#include "tsystem.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tpixelutils.h"
Toshihiro Shimizu 890ddd
//#include "tstopwatch.h"
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
#include "trastercm.h"
Toshihiro Shimizu 890ddd
#include "tropcm.h"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace TConsts;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
#include <emmintrin.h> // per SSE2</emmintrin.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6526c7
#include <memory></memory>
Shinya Kitaoka 6526c7
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
Versione con estensione dell'ultimo pixel e con default_value
Toshihiro Shimizu 890ddd
per pixel "fuori" dall'immagine di ingresso.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Sistemi di coordinate a meno di una traslazione:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UV: coordinate dell'immagine di partenza
Toshihiro Shimizu 890ddd
ST: coordinate di filtro (il raggio del filtro e' intero in ST)
Toshihiro Shimizu 890ddd
FG: coordinate del filtro discretizzato
Toshihiro Shimizu 890ddd
XY: coordinate dell'immagine di arrivo
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Tra UV e ST c'e' una traslazione intera finche' non c'e' ingrandimento
Toshihiro Shimizu 890ddd
e non c'e' blur. Il blur aggiunge uno scale, e altrettanto fa l'ingrandimento.
Toshihiro Shimizu 890ddd
Tra ST e FG c'e' uno scale per la risoluzione del filtro.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Oggetti:
Toshihiro Shimizu 890ddd
out : pixel di output (centro di ST e FG)
Toshihiro Shimizu 890ddd
ref : pixel di riferimento dell'immagine di input
Toshihiro Shimizu 890ddd
pix : pixel contribuente
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Notazione per le coordinate:
Toshihiro Shimizu 890ddd
obj_x  : coordinate intere di obj
Toshihiro Shimizu 890ddd
obj_x_ : coordinate float  di obj
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Notazione per le coppie di coordinate:
Toshihiro Shimizu 890ddd
obj1_obj2_x  : coordinate intere di obj1 rispetto a obj2
Toshihiro Shimizu 890ddd
obj1_obj2_x_ : coordinate float  di obj1 rispetto a obj2
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Matrici affini:
Toshihiro Shimizu 890ddd
aff_xy2uv  : matrice di trasformazione delle coordinate da XY a UV
Toshihiro Shimizu 890ddd
aff0_xy2uv : stessa matrice con la parte di shift messa a 0
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Una tantum:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
aff_uv2xy  = aff
Toshihiro Shimizu 890ddd
aff_xy2uv  = aff_inv (aff_uv2xy)
Toshihiro Shimizu 890ddd
aff0_uv2xy = aff_place (00, 00, aff_uv2xy)
Toshihiro Shimizu 890ddd
  vedi il codice, comunque ottimizzo una rotazione seguita da una scalatura
Toshihiro Shimizu 890ddd
  anisotropa. Cerco i fattori di scala facendo radici di somme di quadrati.
Toshihiro Shimizu 890ddd
  Mi regolo sui fattori di scala come se dovessi considerare la scalatura
Toshihiro Shimizu 890ddd
  da sola. In questo modo tutto si riporta alla vecchia maniera se i fattori
Toshihiro Shimizu 890ddd
  di scala sono uguali. Se sono diversi il risultato e' comunque esatto per
Toshihiro Shimizu 890ddd
  rotazioni di multipli di 90 gradi, e non ha discontinuita'.
Toshihiro Shimizu 890ddd
aff0_uv2st = aff_mult (aff0_xy2st, aff0_uv2xy)
Toshihiro Shimizu 890ddd
aff0_st2fg = aff_scale (filter_resolution, Aff_I)
Toshihiro Shimizu 890ddd
aff0_uv2fg = aff_mult (aff0_st2fg, aff0_uv2st)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
pix_ref_uv[] = tutti quelli che servono (vedi sotto)
Toshihiro Shimizu 890ddd
pix_ref_fg_  = AFF_M_V (aff0_uv2fg, pix_ref_uv)
Toshihiro Shimizu 890ddd
pix_ref_fg[] = ROUND (pix_ref_fg_)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Ciclo su out_xy:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
out_uv_ = AFF_M_V (aff_xy2uv, out_xy)
Toshihiro Shimizu 890ddd
ref_uv = INT_LE (out_uv_)
Toshihiro Shimizu 890ddd
ref_out_uv_ = ref_uv - out_uv_
Toshihiro Shimizu 890ddd
ref_out_fg_ = AFF_M_V (aff0_uv2fg, ref_out_uv_)
Toshihiro Shimizu 890ddd
ref_out_fg  = ROUND (ref_out_fg_)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Ciclo sui pix:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
pix_out_fg = pix_ref_fg + ref_out_fg
Toshihiro Shimizu 890ddd
weight = filter[pix_out_f] * filter[pix_out_g]
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Per sapere quali sono i pix che servono:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
-filter_fg_radius < pix_out_fg < filter_fg_radius
Toshihiro Shimizu 890ddd
min_pix_out_uv_ < pix_out_uv_ < max_pix_out_uv_
Toshihiro Shimizu 890ddd
min_pix_out_uv_ < pix_ref_uv_ + ref_out_uv_ < max_pix_out_uv_
Toshihiro Shimizu 890ddd
min_pix_out_uv_ + out_ref_uv_ < pix_ref_uv_ < max_pix_out_uv_ + out_ref_uv_
Toshihiro Shimizu 890ddd
min_pix_out_uv_ < pix_ref_uv_ < max_pix_out_uv_ + 1
Toshihiro Shimizu 890ddd
Ciclo su tutti quelli che soddisfano questa condizione
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
0 <= out_ref_uv_ < 1
Toshihiro Shimizu 890ddd
-1 < ref_out_uv_ <= 0
Toshihiro Shimizu 890ddd
min_ref_out_fg_ <= ref_out_fg_ <= max_ref_out_fg_
Toshihiro Shimizu 890ddd
min_ref_out_fg  <= ref_out_fg  <= max_ref_out_fg
Toshihiro Shimizu 890ddd
-filter_fg_radius < pix_out_fg < filter_fg_radius
Toshihiro Shimizu 890ddd
-filter_fg_radius < pix_ref_fg + ref_out_fg < filter_fg_radius
Toshihiro Shimizu 890ddd
-filter_fg_radius - ref_out_fg < pix_ref_fg < filter_fg_radius - ref_out_fg
Toshihiro Shimizu 890ddd
-filter_fg_radius - max_ref_out_fg < pix_ref_fg < filter_fg_radius - min_ref_out_fg
Toshihiro Shimizu 890ddd
Scarto quelli che non soddisfano questa condizione
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Come e' fatto il filtro:
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TOP                          filter_array[filter_array_size-1]
Toshihiro Shimizu 890ddd
   |  filter[max_filter_fg]
Toshihiro Shimizu 890ddd
   |  filter[max_pix_out_fg]
Toshihiro Shimizu 890ddd
   |  filter[0]
Toshihiro Shimizu 890ddd
   |  filter[min_pix_out_fg]
Toshihiro Shimizu 890ddd
  BOT filter[min_filter_fg] == filter_array[0]
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if !defined(TNZ_LITTLE_ENDIAN)
Toshihiro Shimizu 890ddd
TNZ_LITTLE_ENDIAN undefined !!
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//2^36 * 1.5,  (52-_shiftamt=36) uses limited precision to floor
Toshihiro Shimizu 890ddd
	const double _double2fixmagic = 68719476736.0 * 1.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//16.16 fixed point representation
Toshihiro Shimizu 890ddd
const TINT32 _shiftamt = 16;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if TNZ_LITTLE_ENDIAN
Toshihiro Shimizu 890ddd
#define iexp_ 1
Toshihiro Shimizu 890ddd
#define iman_ 0
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define iexp_ 0
Toshihiro Shimizu 890ddd
#define iman_ 1
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline TINT32 Double2Int(double val)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	val = val + _double2fixmagic;
Toshihiro Shimizu 890ddd
	return ((TINT32 *)&val)[iman_] >> _shiftamt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define DOUBLE_TO_INT32(D) (d2iaux = D, d2iaux += _double2fixmagic, (((TINT32 *)&(d2iaux))[iman_] >> _shiftamt))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double sinc0(double x, int a)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka ee259f
	return sin((M_PI / (a)) * (x)) / ((M_PI / (a)) * (x));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double sinc(double x, int a)
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka ee259f
	return (x) == 0.0 ? 1.0 : sin((M_PI / (a)) * (x)) / ((M_PI / (a)) * (x));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline UCHAR TO8BIT(float X)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (((X) < 0.0F) ? 0 : (((X) > 255.0F) ? 255 : tround(X)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const UCHAR BORDER_GR8 = 255;
Toshihiro Shimizu 890ddd
const UCHAR GREY_GR8 = 127;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double aff0MV1(const TAffine &aff, double v1, double v2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return aff.a11 * v1 + aff.a12 * v2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double affMV1(const TAffine &aff, double v1, double v2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return aff.a11 * v1 + aff.a12 * v2 + aff.a13;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double aff0MV2(const TAffine &aff, double v1, double v2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return aff.a21 * v1 + aff.a22 * v2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double affMV2(const TAffine &aff, double v1, double v2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return aff.a21 * v1 + aff.a22 * v2 + aff.a23;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#else // !USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
#define ROUND(x) ((int)(((int)(-0.9F) == 0 && (x) < 0.0F) ? ((x)-0.5F) : ((x) + 0.5F)))
Toshihiro Shimizu 890ddd
#define ROUNDP(x) ((int)((x) + 0.5F))
Toshihiro Shimizu 890ddd
#define FLOOR(x) ((int)(x) > (x) ? (int)(x)-1 : (int)(x))
Toshihiro Shimizu 890ddd
#define CEIL(x) ((int)(x) < (x) ? (int)(x) + 1 : (int)(x))
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define ROUND(x) (DOUBLE_TO_INT32(((int)(-0.9F) == 0 && (x) < 0.0F) ? ((x)-0.5F) : ((x) + 0.5F)))
Toshihiro Shimizu 890ddd
#define ROUNDP(x) (DOUBLE_TO_INT32((x) + 0.5F))
Toshihiro Shimizu 890ddd
#define FLOOR(x) (DOUBLE_TO_INT32(x) > (x) ? DOUBLE_TO_INT32(x) - 1 : DOUBLE_TO_INT32(x))
Toshihiro Shimizu 890ddd
#define CEIL(x) (DOUBLE_TO_INT32(x) < (x) ? DOUBLE_TO_INT32(x) + 1 : DOUBLE_TO_INT32(x))
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define INTLE(x) (FLOOR(x))
Toshihiro Shimizu 890ddd
#define INTGT(x) (FLOOR(x) + 1)
Toshihiro Shimizu 890ddd
#define INTLT(x) (CEIL(x) - 1)
Toshihiro Shimizu 890ddd
#define INTGE(x) (CEIL(x))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define NOT_LESS_THAN(MIN, X) \
Toshihiro Shimizu 890ddd
	{                         \
Toshihiro Shimizu 890ddd
		if ((X) < (MIN))      \
Toshihiro Shimizu 890ddd
			(X) = (MIN);      \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#define NOT_MORE_THAN(MAX, X) \
Toshihiro Shimizu 890ddd
	{                         \
Toshihiro Shimizu 890ddd
		if ((X) > (MAX))      \
Toshihiro Shimizu 890ddd
			(X) = (MAX);      \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define tround ROUND
Toshihiro Shimizu 890ddd
#define troundp ROUNDP
Toshihiro Shimizu 890ddd
#define tfloor FLOOR
Toshihiro Shimizu 890ddd
#define tceil CEIL
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define intLE INTLE
Toshihiro Shimizu 890ddd
#define intGT INTGT
Toshihiro Shimizu 890ddd
#define intLT INTLT
Toshihiro Shimizu 890ddd
#define intGE INTGE
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define notLessThan NOT_LESS_THAN
Toshihiro Shimizu 890ddd
#define notMoreThan NOT_MORE_THAN
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define AFF0_M_V_1(AFF, V1, V2) ((AFF).a11 * (V1) + (AFF).a12 * (V2))
Toshihiro Shimizu 890ddd
#define AFF0_M_V_2(AFF, V1, V2) ((AFF).a21 * (V1) + (AFF).a22 * (V2))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define AFF_M_V_1(AFF, V1, V2) ((AFF).a11 * (V1) + (AFF).a12 * (V2) + (AFF).a13)
Toshihiro Shimizu 890ddd
#define AFF_M_V_2(AFF, V1, V2) ((AFF).a21 * (V1) + (AFF).a22 * (V2) + (AFF).a23)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define aff0MV1 AFF0_M_V_1
Toshihiro Shimizu 890ddd
#define aff0MV2 AFF0_M_V_2
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define affMV1 AFF_M_V_1
Toshihiro Shimizu 890ddd
#define affMV2 AFF_M_V_2
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct FILTER {
Toshihiro Shimizu 890ddd
	int first, last;
Toshihiro Shimizu 890ddd
	float *w;
Toshihiro Shimizu 890ddd
	float *w_base;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct NOCALC {
Toshihiro Shimizu 890ddd
	int first, last;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
inline int get_filter_radius(TRop::ResampleFilterType flt_type)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	switch (flt_type) {
Toshihiro Shimizu 890ddd
	case TRop::Triangle:
Toshihiro Shimizu 890ddd
		return 1;
Toshihiro Shimizu 890ddd
	case TRop::Mitchell:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Cubic5:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Cubic75:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Cubic1:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Hann2:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Hann3:
Toshihiro Shimizu 890ddd
		return 3;
Toshihiro Shimizu 890ddd
	case TRop::Hamming2:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Hamming3:
Toshihiro Shimizu 890ddd
		return 3;
Toshihiro Shimizu 890ddd
	case TRop::Lanczos2:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	case TRop::Lanczos3:
Toshihiro Shimizu 890ddd
		return 3;
Toshihiro Shimizu 890ddd
	case TRop::Gauss:
Toshihiro Shimizu 890ddd
		return 2;
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		assert(!"bad filter type");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!Equivalent to aff * TRectD(u0, v0, u1, v0).
Toshihiro Shimizu 890ddd
inline void minmax(double u0, double v0,
Toshihiro Shimizu 890ddd
				   double u1, double v1, const TAffine &aff,
Toshihiro Shimizu 890ddd
				   double &x0, double &y0,
Toshihiro Shimizu 890ddd
				   double &x1, double &y1)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double xmin, ymin;
Toshihiro Shimizu 890ddd
	double xmax, ymax;
Toshihiro Shimizu 890ddd
	double x_a, y_a;
Toshihiro Shimizu 890ddd
	double x_b, y_b;
Toshihiro Shimizu 890ddd
	double x_c, y_c;
Toshihiro Shimizu 890ddd
	double x_d, y_d;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	x_a = affMV1(aff, u0, v0);
Toshihiro Shimizu 890ddd
	y_a = affMV2(aff, u0, v0);
Toshihiro Shimizu 890ddd
	x_b = affMV1(aff, u1, v0);
Toshihiro Shimizu 890ddd
	y_b = affMV2(aff, u1, v0);
Toshihiro Shimizu 890ddd
	x_c = affMV1(aff, u1, v1);
Toshihiro Shimizu 890ddd
	y_c = affMV2(aff, u1, v1);
Toshihiro Shimizu 890ddd
	x_d = affMV1(aff, u0, v1);
Toshihiro Shimizu 890ddd
	y_d = affMV2(aff, u0, v1);
Shinya Kitaoka 12c444
	xmin = std::min(x_a, x_b);
Shinya Kitaoka 12c444
	xmax = std::max(x_a, x_b);
Shinya Kitaoka 12c444
	xmin = std::min(xmin, x_c);
Shinya Kitaoka 12c444
	xmax = std::max(xmax, x_c);
Shinya Kitaoka 12c444
	xmin = std::min(xmin, x_d);
Shinya Kitaoka 12c444
	xmax = std::max(xmax, x_d);
Shinya Kitaoka 12c444
	ymin = std::min(y_a, y_b);
Shinya Kitaoka 12c444
	ymax = std::max(y_a, y_b);
Shinya Kitaoka 12c444
	ymin = std::min(ymin, y_c);
Shinya Kitaoka 12c444
	ymax = std::max(ymax, y_c);
Shinya Kitaoka 12c444
	ymin = std::min(ymin, y_d);
Shinya Kitaoka 12c444
	ymax = std::max(ymax, y_d);
Toshihiro Shimizu 890ddd
	x0 = xmin;
Toshihiro Shimizu 890ddd
	y0 = ymin;
Toshihiro Shimizu 890ddd
	x1 = xmax;
Toshihiro Shimizu 890ddd
	y1 = ymax;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
inline bool trivial_rot (TAffine inv, int *dudx, int *dudy,
Toshihiro Shimizu 890ddd
                                    int *dvdx, int *dvdy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
*dudx = 0;
Toshihiro Shimizu 890ddd
*dudy = 0;
Toshihiro Shimizu 890ddd
*dvdx = 0;
Toshihiro Shimizu 890ddd
*dvdy = 0;
Toshihiro Shimizu 890ddd
if (! (inv.a12 == 0 && inv.a21 == 0 || inv.a11 == 0 && inv.a22 == 0))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
if (! (inv.a11 == 1 || inv.a11 == 0 || inv.a11 == -1))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
if (! (inv.a12 == 1 || inv.a12 == 0 || inv.a12 == -1))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
if (! (inv.a21 == 1 || inv.a21 == 0 || inv.a21 == -1))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
if (! (inv.a22 == 1 || inv.a22 == 0 || inv.a22 == -1))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
*dudx = (int)inv.a11;
Toshihiro Shimizu 890ddd
*dudy = (int)inv.a12;
Toshihiro Shimizu 890ddd
*dvdx = (int)inv.a21;
Toshihiro Shimizu 890ddd
*dvdy = (int)inv.a22;
Toshihiro Shimizu 890ddd
return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// see Mitchell&Netravali, "Reconstruction Filters in Computer Graphics",
Toshihiro Shimizu 890ddd
// SIGGRAPH 88.  Mitchell code provided by Paul Heckbert.
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static double p0, p2, p3, q0, q1, q2, q3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void mitchellinit(double b, double c)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	p0 = (6.0 - 2.0 * b) / 6.0;
Toshihiro Shimizu 890ddd
	p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
	p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
	q0 = (8.0 * b + 24.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
	q1 = (-12.0 * b - 48.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
	q2 = (6.0 * b + 30.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
	q3 = (-b - 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradMitchell = 2;
Toshihiro Shimizu 890ddd
static inline double flt_mitchell(double x) /*Mitchell & Netravali's two-param cubic*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static int mitfirsted;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!mitfirsted) {
Toshihiro Shimizu 890ddd
		mitchellinit(1.0 / 3.0, 1.0 / 3.0);
Toshihiro Shimizu 890ddd
		mitfirsted = 1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (x < -2.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < -1.0)
Toshihiro Shimizu 890ddd
		return (q0 - x * (q1 - x * (q2 - x * q3)));
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		return (p0 + x * x * (p2 - x * p3));
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return (p0 + x * x * (p2 + x * p3));
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return (q0 + x * (q1 + x * (q2 + x * q3)));
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradTriangle = 1;
Toshihiro Shimizu 890ddd
static inline double flt_triangle(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x < -1.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		return 1.0 + x;
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return 1.0 - x;
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic5 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_cubic_5(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		x = -x;
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return 2.5 * x * x * x - 3.5 * x * x + 1;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return 0.5 * x * x * x - 2.5 * x * x + 4 * x - 2;
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic75 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_cubic_75(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		x = -x;
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return 2.75 * x * x * x - 3.75 * x * x + 1;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return 0.75 * x * x * x - 3.75 * x * x + 6 * x - 3;
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic1 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_cubic_1(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		x = -x;
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return 3 * x * x * x - 4 * x * x + 1;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return x * x * x - 5 * x * x + 8 * x - 4;
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHann2 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_hann2(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -2.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Shinya Kitaoka ee259f
		return sinc(x, 1) * (0.5 + 0.5 * cos(M_PI_2 * x));
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHann3 = 3;
Toshihiro Shimizu 890ddd
static inline double flt_hann3(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -3.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 3.0)
Shinya Kitaoka ee259f
		return sinc(x, 1) * (0.5 + 0.5 * cos(M_PI_3 * x));
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHamming2 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_hamming2(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -2.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Shinya Kitaoka ee259f
		return sinc(x, 1) * (0.54 + 0.46 * cos(M_PI_2 * x));
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHamming3 = 3;
Toshihiro Shimizu 890ddd
static inline double flt_hamming3(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -3.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 3.0)
Shinya Kitaoka ee259f
		return sinc(x, 1) * (0.54 + 0.46 * cos(M_PI_3 * x));
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradLanczos2 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_lanczos2(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -2.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return sinc(x, 1) * sinc(x, 2);
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradLanczos3 = 3;
Toshihiro Shimizu 890ddd
static inline double flt_lanczos3(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -3.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 3.0)
Toshihiro Shimizu 890ddd
		return sinc(x, 1) * sinc(x, 3);
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradGauss = 2;
Toshihiro Shimizu 890ddd
static inline double flt_gauss(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x <= -2.0)
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Shinya Kitaoka ee259f
		return exp(-M_PI * x * x);
Toshihiro Shimizu 890ddd
	return 0.0; /* exp(-M_PI*2*2)~=3.5*10^-6 */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradW1 = 2;
Toshihiro Shimizu 890ddd
static inline double flt_w_1(double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (x < 0.0)
Toshihiro Shimizu 890ddd
		x = -x;
Toshihiro Shimizu 890ddd
	if (x < 0.5)
Toshihiro Shimizu 890ddd
		return 1 - 0.5 * x;
Toshihiro Shimizu 890ddd
	if (x < 1.0)
Toshihiro Shimizu 890ddd
		return 1.5 - 1.5 * x;
Toshihiro Shimizu 890ddd
	if (x < 1.5)
Toshihiro Shimizu 890ddd
		return 0.5 - 0.5 * x;
Toshihiro Shimizu 890ddd
	if (x < 2.0)
Toshihiro Shimizu 890ddd
		return 0.5 * x - 1.0;
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static inline void get_flt_fun_rad(TRop::ResampleFilterType flt_type,
Toshihiro Shimizu 890ddd
								   double (**flt_fun)(double), double &flt_rad)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double (*fun)(double);
Toshihiro Shimizu 890ddd
	double rad;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (flt_type) {
Shinya Kitaoka d4642c
	case TRop::Triangle: fun = flt_triangle; rad = fltradTriangle; break;
Shinya Kitaoka d4642c
	case TRop::Mitchell: fun = flt_mitchell; rad = fltradMitchell; break;
Shinya Kitaoka d4642c
	case TRop::Cubic5  : fun = flt_cubic_5 ; rad = fltradCubic5  ; break;
Shinya Kitaoka d4642c
	case TRop::Cubic75 : fun = flt_cubic_75; rad = fltradCubic75 ; break;
Shinya Kitaoka d4642c
	case TRop::Cubic1  : fun = flt_cubic_1 ; rad = fltradCubic1  ; break;
Shinya Kitaoka d4642c
	case TRop::Hann2   : fun = flt_hann2   ; rad = fltradHann2   ; break;
Shinya Kitaoka d4642c
	case TRop::Hann3   : fun = flt_hann3   ; rad = fltradHann3   ; break;
Shinya Kitaoka d4642c
	case TRop::Hamming2: fun = flt_hamming2; rad = fltradHamming2; break;
Shinya Kitaoka d4642c
	case TRop::Hamming3: fun = flt_hamming3; rad = fltradHamming3; break;
Shinya Kitaoka d4642c
	case TRop::Lanczos2: fun = flt_lanczos2; rad = fltradLanczos2; break;
Shinya Kitaoka d4642c
	case TRop::Lanczos3: fun = flt_lanczos3; rad = fltradLanczos3; break;
Shinya Kitaoka d4642c
	case TRop::Gauss   : fun = flt_gauss   ; rad = fltradGauss   ; break;
Shinya Kitaoka d4642c
	case 101           : fun = flt_w_1     ; rad = fltradW1      ; break;
Shinya Kitaoka d4642c
	default            : fun = flt_triangle; rad = fltradTriangle; break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (flt_fun)
Toshihiro Shimizu 890ddd
		*flt_fun = fun;
Toshihiro Shimizu 890ddd
	flt_rad = rad;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static FILTER *create_filter(TRop::ResampleFilterType flt_type, double blur,
Toshihiro Shimizu 890ddd
							 double dx_du, double delta_x, int lx,
Toshihiro Shimizu 890ddd
							 double &xrad, int &umin, int &umax, int &uwidth)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double (*flt_fun)(double);
Toshihiro Shimizu 890ddd
	FILTER *filter, *f;
Toshihiro Shimizu 890ddd
	double du_dx;
Toshihiro Shimizu 890ddd
	int x;
Toshihiro Shimizu 890ddd
	double u_;
Toshihiro Shimizu 890ddd
	int u, ulo, uhi, ulomin, uhimax, m, n, nmax;
Toshihiro Shimizu 890ddd
	double flt_rad, rad_u, rad_x, nodedist_u, nodefreq_u, sum, norm, w;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	get_flt_fun_rad(flt_type, &flt_fun, flt_rad);
Toshihiro Shimizu 890ddd
	du_dx = 1 / dx_du;
Toshihiro Shimizu 890ddd
	if (dx_du > 1)
Toshihiro Shimizu 890ddd
		nodedist_u = blur; /* magnification */
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		nodedist_u = du_dx * blur; /* minification */
Toshihiro Shimizu 890ddd
	rad_u = flt_rad * nodedist_u;
Toshihiro Shimizu 890ddd
	rad_x = rad_u * dx_du;
Toshihiro Shimizu 890ddd
	nodefreq_u = 1 / nodedist_u;
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
mu = lu - 1;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
	filter = new FILTER[lx];
Toshihiro Shimizu 890ddd
	nmax = 0;
Toshihiro Shimizu 890ddd
	ulomin = c_maxint - 1;
Toshihiro Shimizu 890ddd
	uhimax = c_minint + 1;
Toshihiro Shimizu 890ddd
	for (x = 0; x < lx; x++) {
Toshihiro Shimizu 890ddd
		f = filter + x;
Toshihiro Shimizu 890ddd
		u_ = (x - delta_x) * du_dx;
Toshihiro Shimizu 890ddd
		ulo = intGT(u_ - rad_u);
Toshihiro Shimizu 890ddd
		uhi = intLT(u_ + rad_u);
Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
  NOT_LESS_THAN( 0, ulo)
Toshihiro Shimizu 890ddd
  NOT_MORE_THAN(mu, uhi)
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
		m = uhi - ulo + 1;
Toshihiro Shimizu 890ddd
		if (m > 0) {
Toshihiro Shimizu 890ddd
			f->w_base = new float[m];
Toshihiro Shimizu 890ddd
			f->w = f->w_base - ulo;
Toshihiro Shimizu 890ddd
			for (sum = 0.0, u = ulo; u <= uhi; u++) {
Toshihiro Shimizu 890ddd
				w = (*flt_fun)((u - u_) * nodefreq_u);
Toshihiro Shimizu 890ddd
				sum += w;
Toshihiro Shimizu 890ddd
				f->w[u] = (float)w;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			for (; ulo <= uhi; ulo++)
Toshihiro Shimizu 890ddd
				if (f->w[ulo])
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
			for (; uhi >= ulo; uhi--)
Toshihiro Shimizu 890ddd
				if (f->w[uhi])
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
			if (ulo < ulomin)
Toshihiro Shimizu 890ddd
				ulomin = ulo;
Toshihiro Shimizu 890ddd
			if (uhi > uhimax)
Toshihiro Shimizu 890ddd
				uhimax = uhi;
Toshihiro Shimizu 890ddd
			n = uhi - ulo + 1;
Toshihiro Shimizu 890ddd
			if (n > nmax)
Toshihiro Shimizu 890ddd
				nmax = n;
Toshihiro Shimizu 890ddd
			f->first = ulo;
Toshihiro Shimizu 890ddd
			f->last = uhi;
Toshihiro Shimizu 890ddd
			norm = 1 / sum;
Toshihiro Shimizu 890ddd
			for (u = ulo; u <= uhi; u++)
Toshihiro Shimizu 890ddd
				f->w[u] *= (float)norm;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			f->w_base = 0;
Toshihiro Shimizu 890ddd
			f->first = ulo;
Toshihiro Shimizu 890ddd
			f->last = uhi;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	xrad = rad_x;
Toshihiro Shimizu 890ddd
	umin = ulomin;
Toshihiro Shimizu 890ddd
	umax = uhimax;
Toshihiro Shimizu 890ddd
	uwidth = nmax;
Toshihiro Shimizu 890ddd
	return filter;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static NOCALC *create_nocalc(TRop::ResampleFilterType flt_type, double blur,
Toshihiro Shimizu 890ddd
							 double dx_du, double delta_x, int lx,
Toshihiro Shimizu 890ddd
							 int umin, int umax, int &xwidth)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Il nocalc serve a stabilire che un insieme di pixel u (di ingresso)
Toshihiro Shimizu 890ddd
non ha bisogno di essere calcolato, perche tutti i pixel x (di uscita)
Toshihiro Shimizu 890ddd
su cui questo insieme si distribuisce non hanno bisogno di essere calcolati.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Il significato del nocalc a coordinata x e':
Toshihiro Shimizu 890ddd
se arrivati a x si e' trovata una sequenza di width pixel x che
Toshihiro Shimizu 890ddd
non e' necessario calcolare, allora non e' necessario calcolare tutti i
Toshihiro Shimizu 890ddd
pixel u da nocalc->first a nocalc->last.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Per primo va calcolata la width. Deve essere garantito che tutti i pixel u
Toshihiro Shimizu 890ddd
siano coperti dal vettore di nocalc.
Toshihiro Shimizu 890ddd
Un pixel u viene usato da un intervallo di x largo quanto il filtro (in x),
Toshihiro Shimizu 890ddd
cioe' un intervallo aperto (-radx_,radx_) intorno a x(u).
Toshihiro Shimizu 890ddd
Aggiungendo una unita' x a questa larghezza si ha una larghezza tale che
Toshihiro Shimizu 890ddd
se tutti i pixel x sono nocalc, un intervallo largo 1 in unita' x
Toshihiro Shimizu 890ddd
di pixel u non necessita di essere calcolato.
Toshihiro Shimizu 890ddd
Vogliamo che ulo_ <= first <= last < uhi_ con uhi_ = ulo_ + u(1).
Toshihiro Shimizu 890ddd
Devono essere nocalc almeno gli x in (x(ulo_)-radx_, x(uhi_)+radx_).
Toshihiro Shimizu 890ddd
Poniamo x = x(uhi_)+radx_-1.
Toshihiro Shimizu 890ddd
uhi_ = u(x-radx_+1)
Toshihiro Shimizu 890ddd
ulo_ = u(x-radx_)
Toshihiro Shimizu 890ddd
x(ulo_)-radx_ = x-2*radx_   ma questo punto e' escluso, quindi l'intero GT e'
Toshihiro Shimizu 890ddd
x - width + 1 = INT_LE (x-2*radx_+1)
Toshihiro Shimizu 890ddd
1 - INT_LE (-2*radx_+1) = width
Toshihiro Shimizu 890ddd
1 + INT_GE (2*radx_-1) = width
Toshihiro Shimizu 890ddd
INT_GE (2*radx_) = width
Toshihiro Shimizu 890ddd
Pero' per sicurezza facciamo
Toshihiro Shimizu 890ddd
INT_GT (2*radx_) = width
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	NOCALC *nocalc;
Toshihiro Shimizu 890ddd
	int width;
Toshihiro Shimizu 890ddd
	double flt_rad;
Toshihiro Shimizu 890ddd
	double rad_x;
Toshihiro Shimizu 890ddd
	double du_dx;
Toshihiro Shimizu 890ddd
	double ulo_, uhi_;
Toshihiro Shimizu 890ddd
	int ulo, uhi;
Toshihiro Shimizu 890ddd
	int x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	du_dx = 1 / dx_du;
Toshihiro Shimizu 890ddd
	get_flt_fun_rad(flt_type, 0, flt_rad);
Toshihiro Shimizu 890ddd
	if (dx_du > 1) /* sto ingrandendo */
Toshihiro Shimizu 890ddd
		rad_x = flt_rad * blur * dx_du;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		rad_x = flt_rad * blur;
Toshihiro Shimizu 890ddd
	rad_x += 0.5; /* ?!?!?!?!? */
Toshihiro Shimizu 890ddd
	width = intGT(2 * rad_x + 1);
Toshihiro Shimizu 890ddd
	nocalc = new NOCALC[lx + width - 1];
Toshihiro Shimizu 890ddd
	for (x = 0; x < lx + width - 1; x++) {
Toshihiro Shimizu 890ddd
		ulo_ = (x - rad_x - delta_x) * du_dx;
Toshihiro Shimizu 890ddd
		uhi_ = ulo_ + du_dx;
Toshihiro Shimizu 890ddd
		ulo = intGE(ulo_);
Toshihiro Shimizu 890ddd
		uhi = intLT(uhi_);
Shinya Kitaoka 12c444
		nocalc[x].first = std::max(umin, ulo);
Shinya Kitaoka 12c444
		nocalc[x].last = std::min(umax, uhi);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	xwidth = width;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return nocalc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
inline UINT calcValueInit(UINT init_value){
Toshihiro Shimizu 890ddd
  return init_value;//0xffffU;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
inline void calcValueInit(UINT &calc_value){
Toshihiro Shimizu 890ddd
  calc_value = 0xffffU;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline bool calcValueEmpty(UINT calc_value){
Toshihiro Shimizu 890ddd
  return calc_value == 0xffffU;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
inline bool calcValueReady(UINT calc_value){
Toshihiro Shimizu 890ddd
  return calc_value <=  0x1ffU;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void calcValueAdvance(UINT &calc_value){
Toshihiro Shimizu 890ddd
  calc_value >>= 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline void calcValueNoCalc(UINT &calc_value){
Toshihiro Shimizu 890ddd
  calc_value &= ~0x80U;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
#define CALC_VALUE_INIT       \
Toshihiro Shimizu 890ddd
	{                         \
Toshihiro Shimizu 890ddd
		calc_value = 0xffffU; \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#define CALC_VALUE_EMPTY (calc_value == 0xffffU)
Toshihiro Shimizu 890ddd
#define CALC_VALUE_READY (calc_value <= 0x1ffU)
Toshihiro Shimizu 890ddd
#define CALC_VALUE_ADVANCE \
Toshihiro Shimizu 890ddd
	{                      \
Toshihiro Shimizu 890ddd
		calc_value >>= 1;  \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#define CALC_VALUE_NOCALC     \
Toshihiro Shimizu 890ddd
	{                         \
Toshihiro Shimizu 890ddd
		calc_value &= ~0x80U; \
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixtype=""></typename>
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
__forceinline
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	void
Toshihiro Shimizu 890ddd
	ResampleCalcAlgo(PixType *buffer_in, int lu, int lv, int wrap_in, int max_pix_ref_u, int min_pix_ref_u, int max_pix_ref_v, int min_pix_ref_v, UCHAR *calc, int calc_bytesize, int calc_bytewrap)
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
lu = width
Toshihiro Shimizu 890ddd
lv = height
Toshihiro Shimizu 890ddd
wrap_in = wrap
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	PixType *prev_line_in;
Toshihiro Shimizu 890ddd
	PixType *last_line_in;
Toshihiro Shimizu 890ddd
	PixType prev_value;
Toshihiro Shimizu 890ddd
	PixType left_value;
Toshihiro Shimizu 890ddd
	PixType last_value;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT calc_value;
Toshihiro Shimizu 890ddd
	UCHAR *calc_byte = 0;
Toshihiro Shimizu 890ddd
	int goodcols;
Shinya Kitaoka 6a4e01
	std::unique_ptr<int[]> col_height(new int[lu]);</int[]>
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int filter_diam_u = max_pix_ref_u - min_pix_ref_u + 1;
Toshihiro Shimizu 890ddd
	int filter_diam_v = max_pix_ref_v - min_pix_ref_v + 1;
Toshihiro Shimizu 890ddd
	int last_u, last_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int *ch;
Toshihiro Shimizu 890ddd
	int *ch_end;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(col_height);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CALC_VALUE_INIT
Shinya Kitaoka 6a4e01
	ch = col_height.get();
Toshihiro Shimizu 890ddd
	ch_end = ch + lu;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	while (ch < ch_end) {
Toshihiro Shimizu 890ddd
		*ch = filter_diam_v;
Toshihiro Shimizu 890ddd
		++ch;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	last_line_in = buffer_in;
Toshihiro Shimizu 890ddd
	for (last_v = 1, ref_v = last_v - max_pix_ref_v; ref_v < 0; last_v++, ref_v++) {
Toshihiro Shimizu 890ddd
		prev_line_in = last_line_in;
Toshihiro Shimizu 890ddd
		last_line_in = buffer_in + last_v * wrap_in;
Toshihiro Shimizu 890ddd
		for (last_u = 0; last_u < lu; last_u++) {
Toshihiro Shimizu 890ddd
			last_value = last_line_in[last_u];
Toshihiro Shimizu 890ddd
			prev_value = prev_line_in[last_u];
Toshihiro Shimizu 890ddd
			if (last_value == prev_value)
Toshihiro Shimizu 890ddd
				col_height[last_u]++;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				col_height[last_u] = 1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; last_v < lv; last_v++, ref_v++) {
Toshihiro Shimizu 890ddd
		prev_line_in = last_line_in;
Toshihiro Shimizu 890ddd
		last_line_in = buffer_in + last_v * wrap_in;
Toshihiro Shimizu 890ddd
		last_value = last_line_in[0];
Toshihiro Shimizu 890ddd
		goodcols = 0;
Toshihiro Shimizu 890ddd
		for (last_u = 0, ref_u = last_u - max_pix_ref_u; ref_u < 0; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
			left_value = last_value;
Toshihiro Shimizu 890ddd
			last_value = last_line_in[last_u];
Toshihiro Shimizu 890ddd
			prev_value = prev_line_in[last_u];
Toshihiro Shimizu 890ddd
			if (last_value == prev_value) {
Toshihiro Shimizu 890ddd
				col_height[last_u]++;
Toshihiro Shimizu 890ddd
				if (col_height[last_u] >= filter_diam_v)
Toshihiro Shimizu 890ddd
					if (last_value == left_value)
Toshihiro Shimizu 890ddd
						goodcols++;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						goodcols = 1;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					goodcols = 0;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				col_height[last_u] = 1;
Toshihiro Shimizu 890ddd
				goodcols = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		calc_byte = calc + calc_bytewrap * ref_v;
Toshihiro Shimizu 890ddd
		CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
		for (; last_u < lu; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
			left_value = last_value;
Toshihiro Shimizu 890ddd
			last_value = last_line_in[last_u];
Toshihiro Shimizu 890ddd
			prev_value = prev_line_in[last_u];
Toshihiro Shimizu 890ddd
			if (last_value == prev_value) {
Toshihiro Shimizu 890ddd
				col_height[last_u]++;
Toshihiro Shimizu 890ddd
				if (col_height[last_u] >= filter_diam_v)
Toshihiro Shimizu 890ddd
					if (last_value == left_value) {
Toshihiro Shimizu 890ddd
						goodcols++;
Toshihiro Shimizu 890ddd
						if (goodcols >= filter_diam_u)
Toshihiro Shimizu 890ddd
							CALC_VALUE_NOCALC
Toshihiro Shimizu 890ddd
					} else
Toshihiro Shimizu 890ddd
						goodcols = 1;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					goodcols = 0;
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				col_height[last_u] = 1;
Toshihiro Shimizu 890ddd
				goodcols = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (CALC_VALUE_READY) {
Toshihiro Shimizu 890ddd
				*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
				CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (; ref_u < lu; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
			if (CALC_VALUE_READY) {
Toshihiro Shimizu 890ddd
				*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
				CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (!CALC_VALUE_EMPTY) {
Toshihiro Shimizu 890ddd
			while (!CALC_VALUE_READY)
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
			*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (; ref_v < lv; last_v++, ref_v++) {
Toshihiro Shimizu 890ddd
		for (last_u = 0, ref_u = last_u - max_pix_ref_u; ref_u < 0; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		calc_byte = calc + calc_bytewrap * ref_v;
Toshihiro Shimizu 890ddd
		CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
		for (; last_u < lu; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
			if (CALC_VALUE_READY) {
Toshihiro Shimizu 890ddd
				*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
				CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (; ref_u < lu; last_u++, ref_u++) {
Toshihiro Shimizu 890ddd
			if (CALC_VALUE_READY) {
Toshihiro Shimizu 890ddd
				*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
				CALC_VALUE_INIT
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (!CALC_VALUE_EMPTY) {
Toshihiro Shimizu 890ddd
			while (!CALC_VALUE_READY)
Toshihiro Shimizu 890ddd
				CALC_VALUE_ADVANCE
Toshihiro Shimizu 890ddd
			*calc_byte++ = (UCHAR)calc_value;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	assert(!calc_byte || calc_byte == calc + calc_bytesize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void create_calc(const TRasterPT<t> &rin,</t>
Toshihiro Shimizu 890ddd
				 int min_pix_ref_u, int max_pix_ref_u,
Toshihiro Shimizu 890ddd
				 int min_pix_ref_v, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
				 UCHAR *&p_calc, int &p_calc_allocsize, int &p_calc_bytewrap)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int lu, lv;
Toshihiro Shimizu 890ddd
	int wrap_in;
Toshihiro Shimizu 890ddd
	int calc_bytesize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	p_calc_bytewrap = (lu + 7) >> 3; // ceil(lu/8)
Toshihiro Shimizu 890ddd
	calc_bytewrap = p_calc_bytewrap;
Toshihiro Shimizu 890ddd
	calc_bytesize = calc_bytewrap * lv; // lv * ceil(lu/8)
Toshihiro Shimizu 890ddd
	if (calc_bytesize > p_calc_allocsize) {
Toshihiro Shimizu 890ddd
		if (p_calc_allocsize)
Toshihiro Shimizu 890ddd
			delete[](p_calc);
Toshihiro Shimizu 890ddd
		//TMALLOC (*p_calc, calc_bytesize)
Toshihiro Shimizu 890ddd
		p_calc = new UCHAR[calc_bytesize];
Toshihiro Shimizu 890ddd
		assert(p_calc);
Toshihiro Shimizu 890ddd
		memset(p_calc, 0xff, calc_bytesize);
Toshihiro Shimizu 890ddd
		p_calc_allocsize = calc_bytesize;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	calc = p_calc;
Toshihiro Shimizu 890ddd
	if (lu < max_pix_ref_u + 1 || lv < max_pix_ref_v + 1) {
Toshihiro Shimizu 890ddd
		memset(calc, 0xff, calc_bytesize);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//RESAMPLE_CALC_ALGO
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	ResampleCalcAlgo<t>(rin->pixels(), lu, lv, wrap_in, max_pix_ref_u, min_pix_ref_u,</t>
Toshihiro Shimizu 890ddd
						max_pix_ref_v, min_pix_ref_v, calc, calc_bytesize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
class Converter
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static inline T convert(const TPixel32 &pixin)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return pixin;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BYTE_FROM_USHORT(u) (((256U * 255U + 1U) * u + (1 << 23)) >> 24)
Toshihiro Shimizu 890ddd
#define USHORT_FROM_BYTE(u) (u | u << 8)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <>
Toshihiro Shimizu 890ddd
class Converter<tpixel64></tpixel64>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	static inline TPixel64 convert(const TPixel32 &pix)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return TPixel64(
Toshihiro Shimizu 890ddd
			USHORT_FROM_BYTE(pix.r),
Toshihiro Shimizu 890ddd
			USHORT_FROM_BYTE(pix.g),
Toshihiro Shimizu 890ddd
			USHORT_FROM_BYTE(pix.b),
Toshihiro Shimizu 890ddd
			USHORT_FROM_BYTE(pix.m));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
inline double get_filter_value(TRop::ResampleFilterType flt_type, double x)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//it is assumed that x != 0 (not checked only for speed reasons)
Toshihiro Shimizu 890ddd
	switch (flt_type) {
Toshihiro Shimizu 890ddd
	case TRop::Triangle:
Toshihiro Shimizu 890ddd
		if (x < -1.0)
Toshihiro Shimizu 890ddd
			return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 0.0)
Toshihiro Shimizu 890ddd
			return 1.0 + x;
Toshihiro Shimizu 890ddd
		if (x < 1.0)
Toshihiro Shimizu 890ddd
			return 1.0 - x;
Toshihiro Shimizu 890ddd
		return 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRop::Mitchell: {
Toshihiro Shimizu 890ddd
		static double p0, p2, p3, q0, q1, q2, q3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (!p0) {
Toshihiro Shimizu 890ddd
			const double b = 1.0 / 3.0;
Toshihiro Shimizu 890ddd
			const double c = 1.0 / 3.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			p0 = (6.0 - 2.0 * b) / 6.0;
Toshihiro Shimizu 890ddd
			p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
			p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
			q0 = (8.0 * b + 24.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
			q1 = (-12.0 * b - 48.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
			q2 = (6.0 * b + 30.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
			q3 = (-b - 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (x < -2.0)
Toshihiro Shimizu 890ddd
			return 0.0;
Toshihiro Shimizu 890ddd
		if (x < -1.0)
Toshihiro Shimizu 890ddd
			return (q0 - x * (q1 - x * (q2 - x * q3)));
Toshihiro Shimizu 890ddd
		if (x < 0.0)
Toshihiro Shimizu 890ddd
			return (p0 + x * x * (p2 - x * p3));
Toshihiro Shimizu 890ddd
		if (x < 1.0)
Toshihiro Shimizu 890ddd
			return (p0 + x * x * (p2 + x * p3));
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Toshihiro Shimizu 890ddd
			return (q0 + x * (q1 + x * (q2 + x * q3)));
Shinya Kitaoka d4642c
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Cubic5:
Shinya Kitaoka d4642c
		if (x < 0.0) x = -x;
Toshihiro Shimizu 890ddd
		if (x < 1.0)
Toshihiro Shimizu 890ddd
			return 2.5 * x * x * x - 3.5 * x * x + 1;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Toshihiro Shimizu 890ddd
			return 0.5 * x * x * x - 2.5 * x * x + 4 * x - 2;
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Cubic75:
Shinya Kitaoka d4642c
		if (x < 0.0) x = -x;
Toshihiro Shimizu 890ddd
		if (x < 1.0)
Toshihiro Shimizu 890ddd
			return 2.75 * x * x * x - 3.75 * x * x + 1;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Toshihiro Shimizu 890ddd
			return 0.75 * x * x * x - 3.75 * x * x + 6 * x - 3;
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Cubic1:
Shinya Kitaoka d4642c
		if (x < 0.0) x = -x;
Toshihiro Shimizu 890ddd
		if (x < 1.0)
Toshihiro Shimizu 890ddd
			return 3 * x * x * x - 4 * x * x + 1;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Toshihiro Shimizu 890ddd
			return x * x * x - 5 * x * x + 8 * x - 4;
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Hann2:
Shinya Kitaoka d4642c
		if (x <= -2.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Shinya Kitaoka ee259f
			return sinc0(x, 1) * (0.5 + 0.5 * cos(M_PI_2 * x));
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Hann3:
Shinya Kitaoka d4642c
		if (x <= -3.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 3.0)
Shinya Kitaoka ee259f
			return sinc0(x, 1) * (0.5 + 0.5 * cos(M_PI_3 * x));
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Hamming2:
Shinya Kitaoka d4642c
		if (x <= -2.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Shinya Kitaoka ee259f
			return sinc0(x, 1) * (0.54 + 0.46 * cos(M_PI_2 * x));
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Hamming3:
Shinya Kitaoka d4642c
		if (x <= -3.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 3.0)
Shinya Kitaoka ee259f
			return sinc0(x, 1) * (0.54 + 0.46 * cos(M_PI_3 * x));
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Lanczos2:
Shinya Kitaoka d4642c
		if (x <= -2.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Toshihiro Shimizu 890ddd
			return sinc0(x, 1) * sinc0(x, 2);
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Lanczos3:
Shinya Kitaoka d4642c
		if (x <= -3.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 3.0)
Toshihiro Shimizu 890ddd
			return sinc0(x, 1) * sinc0(x, 3);
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
Shinya Kitaoka d4642c
	case TRop::Gauss:
Shinya Kitaoka d4642c
		if (x <= -2.0) return 0.0;
Toshihiro Shimizu 890ddd
		if (x < 2.0)
Shinya Kitaoka ee259f
			return exp(-M_PI * x * x); /* exp(-M_PI*2*2)~=3.5*10^-6 */
Shinya Kitaoka d4642c
		break;
Shinya Kitaoka d4642c
	default:
Toshihiro Shimizu 890ddd
		assert(!"bad filter type");
Shinya Kitaoka d4642c
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void resample_clear_rgbm(TRasterPT<t> rout, T default_value)</t>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	for (int out_y = 0; out_y < rout->getLy(); out_y++)
Toshihiro Shimizu 890ddd
		for (int out_x = 0; out_x < rout->getLx(); out_x++)
Toshihiro Shimizu 890ddd
			buffer_out[out_x + out_y * rout->getWrap()] = default_value;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class sums_type="" t,="" typename=""></class>
Toshihiro Shimizu 890ddd
void resample_main_rgbm(TRasterPT<t> rout, const TRasterPT<t> &rin,</t></t>
Toshihiro Shimizu 890ddd
						const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
						const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
						int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
						int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
						int n_pix,
Toshihiro Shimizu 890ddd
						int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
						int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
						short *filter)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const T *buffer_in;
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	T *pix_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int filter_mu, filter_mv;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	int outside_min_u, outside_min_v;
Toshihiro Shimizu 890ddd
	int outside_max_u, outside_max_v;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	T pix_value, default_value(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	SUMS_TYPE weight, sum_weights;
Toshihiro Shimizu 890ddd
	double inv_sum_weights;
Toshihiro Shimizu 890ddd
	SUMS_TYPE sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Toshihiro Shimizu 890ddd
	double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Toshihiro Shimizu 890ddd
	int out_value_r, out_value_g, out_value_b, out_value_m;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		rout->clear();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Create a bit array, each indicating whether a pixel has to be calculated or not
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	filter_mu = max_pix_ref_u - min_pix_ref_u;
Toshihiro Shimizu 890ddd
	filter_mv = max_pix_ref_v - min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - filter_mu;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - filter_mv;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u = -max_pix_ref_u;
Toshihiro Shimizu 890ddd
	outside_min_v = -max_pix_ref_v;
Toshihiro Shimizu 890ddd
	outside_max_u = mu - min_pix_ref_u;
Toshihiro Shimizu 890ddd
	outside_max_v = mv - min_pix_ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//For every pixel of the output image
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.5; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.5; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			pix_out = buffer_out + out_y * wrap_out + out_x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Take the pre-image of the pixel through the passed affine
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//Convert to integer coordinates
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//NOTE: The following condition is equivalent to:
Toshihiro Shimizu 890ddd
			// (ref_u + min_pix_ref_u >= 0 && ref_v + min_pix_ref_v >= 0 &&
Toshihiro Shimizu 890ddd
			//  ref_u + max_pix_ref_u < lu && ref_v + max_pix_ref_v < lv)
Toshihiro Shimizu 890ddd
			// - since the presence of (UINT) makes integeres < 0 become >> 0
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u + min_pix_ref_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v + min_pix_ref_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				//The filter mask starting around (ref_u, ref_v) is completely contained
Toshihiro Shimizu 890ddd
				//in the source raster
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//Get the calculation array mask byte
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) //If the mask bit for this pixel is on
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_; //Fractionary part of the pre-image
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_); //Make the image of it into fg
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_); //Convert to integer coordinates
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					//Make the weighted sum of source pixels
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; --i) {
Toshihiro Shimizu 890ddd
						//Build the weight for this pixel
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f; //image of the integer part + that of the fractionary part
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						//Add the weighted pixel contribute
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
						sum_contribs_r += (SUMS_TYPE)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (SUMS_TYPE)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (SUMS_TYPE)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (SUMS_TYPE)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					pix_out->r = out_value_r;
Toshihiro Shimizu 890ddd
					pix_out->g = out_value_g;
Toshihiro Shimizu 890ddd
					pix_out->b = out_value_b;
Toshihiro Shimizu 890ddd
					pix_out->m = out_value_m;
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					//The pixel is copied from the corresponding source...
Toshihiro Shimizu 890ddd
					*pix_out = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
			} else if (outside_min_u <= ref_u && ref_u <= outside_max_u &&
Toshihiro Shimizu 890ddd
					   outside_min_v <= ref_v && ref_v <= outside_max_v) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; --i) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (pix_u < 0 || pix_u > mu ||
Toshihiro Shimizu 890ddd
							pix_v < 0 || pix_v > mv) {
Toshihiro Shimizu 890ddd
							sum_weights += weight; //0-padding
Toshihiro Shimizu 890ddd
							continue;
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u); //Copy-padding
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
						sum_contribs_r += (SUMS_TYPE)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (SUMS_TYPE)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (SUMS_TYPE)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (SUMS_TYPE)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					pix_out->r = out_value_r;
Toshihiro Shimizu 890ddd
					pix_out->g = out_value_g;
Toshihiro Shimizu 890ddd
					pix_out->b = out_value_b;
Toshihiro Shimizu 890ddd
					pix_out->m = out_value_m;
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					*pix_out = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				*pix_out = default_value;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
__declspec(align(16)) class TPixelFloat
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TPixelFloat() : b(0), g(0), r(0), m(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPixelFloat(float rr, float gg, float bb, float mm)
Toshihiro Shimizu 890ddd
		: b(bb), g(gg), r(rr), m(mm) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPixelFloat(const TPixel32 &pix)
Toshihiro Shimizu 890ddd
		: b(pix.b), g(pix.g), r(pix.r), m(pix.m) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float b, g, r, m;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // anonymous namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void resample_main_rgbm_SSE2(TRasterPT<t> rout, const TRasterPT<t> &rin,</t></t>
Toshihiro Shimizu 890ddd
							 const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
							 const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
							 int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
							 int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
							 int n_pix,
Toshihiro Shimizu 890ddd
							 int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
							 int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
							 short *filter)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	__m128i zeros = _mm_setzero_si128();
Toshihiro Shimizu 890ddd
	const T *buffer_in;
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int filter_mu, filter_mv;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	//double outside_min_u_,  outside_min_v_;
Toshihiro Shimizu 890ddd
	//double outside_max_u_,  outside_max_v_;
Toshihiro Shimizu 890ddd
	int outside_min_u, outside_min_v;
Toshihiro Shimizu 890ddd
	int outside_max_u, outside_max_v;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	T pix_value;
Toshihiro Shimizu 890ddd
	T default_value(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	float weight;
Toshihiro Shimizu 890ddd
	float sum_weights;
Toshihiro Shimizu 890ddd
	float inv_sum_weights;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T *pix_out;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 sum_contribs_packed;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128i pix_value_packed_i;
Toshihiro Shimizu 890ddd
	__m128 pix_value_packed;
Toshihiro Shimizu 890ddd
	__m128 weight_packed;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 zeros2 = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float maxChannelValue = (float)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	__m128 maxChanneValue_packed = _mm_load1_ps(&maxChannelValue);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		resample_clear_rgbm(rout, default_value);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	filter_mu = max_pix_ref_u - min_pix_ref_u;
Toshihiro Shimizu 890ddd
	filter_mv = max_pix_ref_v - min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - filter_mu;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - filter_mv;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u = -max_pix_ref_u;
Toshihiro Shimizu 890ddd
	outside_min_v = -max_pix_ref_v;
Toshihiro Shimizu 890ddd
	outside_max_u = mu - min_pix_ref_u;
Toshihiro Shimizu 890ddd
	outside_max_v = mv - min_pix_ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.5; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.5; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			pix_out = buffer_out + out_y * wrap_out + out_x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u + min_pix_ref_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v + min_pix_ref_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					sum_contribs_packed = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
						pix_value_packed_i = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(DWORD *)&pix_value), zeros);
Toshihiro Shimizu 890ddd
						pix_value_packed = _mm_cvtepi32_ps(_mm_unpacklo_epi16(pix_value_packed_i, zeros));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						weight_packed = _mm_load1_ps(&weight);
Toshihiro Shimizu 890ddd
						sum_contribs_packed = _mm_add_ps(sum_contribs_packed, _mm_mul_ps(pix_value_packed, weight_packed));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0f / sum_weights;
Toshihiro Shimizu 890ddd
					__m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128 out_fval_packed = _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packs_epi32(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packus_epi16(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					*(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					*pix_out = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				//if( outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Toshihiro Shimizu 890ddd
				//    outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_ )
Toshihiro Shimizu 890ddd
				if (outside_min_u <= ref_u && ref_u <= outside_max_u &&
Toshihiro Shimizu 890ddd
					outside_min_v <= ref_v && ref_v <= outside_max_v) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_packed = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (pix_u < 0 || pix_u > mu ||
Toshihiro Shimizu 890ddd
							pix_v < 0 || pix_v > mv) {
Toshihiro Shimizu 890ddd
							sum_weights += weight;
Toshihiro Shimizu 890ddd
							continue;
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u);
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
						pix_value_packed_i = _mm_unpacklo_epi8(_mm_cvtsi32_si128(*(DWORD *)&pix_value), zeros);
Toshihiro Shimizu 890ddd
						pix_value_packed = _mm_cvtepi32_ps(_mm_unpacklo_epi16(pix_value_packed_i, zeros));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						weight_packed = _mm_load1_ps(&weight);
Toshihiro Shimizu 890ddd
						sum_contribs_packed = _mm_add_ps(sum_contribs_packed, _mm_mul_ps(pix_value_packed, weight_packed));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0f / sum_weights;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Toshihiro Shimizu 890ddd
					__m128 out_fval_packed = _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packs_epi32(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packus_epi16(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					*(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Toshihiro Shimizu 890ddd
				} else
Toshihiro Shimizu 890ddd
					*pix_out = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				*pix_out = default_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (calc)
Toshihiro Shimizu 890ddd
		delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void inline blendBySSE2(TPixel32 *pix_out,
Toshihiro Shimizu 890ddd
						float *ink, float *paint, float *tone,
Toshihiro Shimizu 890ddd
						const __m128 &maxtone_packed,
Toshihiro Shimizu 890ddd
						const __m128i &zeros)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	__m128 a_packed = _mm_load_ps(ink);
Toshihiro Shimizu 890ddd
	__m128 b_packed = _mm_load_ps(paint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 num_packed = _mm_load1_ps(tone);
Toshihiro Shimizu 890ddd
	__m128 diff_packed = _mm_sub_ps(maxtone_packed, num_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// calcola in modo vettoriale out = ((den-num)*a + num*b)/den
Toshihiro Shimizu 890ddd
	__m128 pix_value_packed = _mm_mul_ps(diff_packed, a_packed);
Toshihiro Shimizu 890ddd
	__m128 tmpPix_packed = _mm_mul_ps(num_packed, b_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pix_value_packed = _mm_add_ps(pix_value_packed, tmpPix_packed);
Toshihiro Shimizu 890ddd
	pix_value_packed = _mm_div_ps(pix_value_packed, maxtone_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// converte i canali da float a char
Toshihiro Shimizu 890ddd
	__m128i pix_value_packed_i = _mm_cvtps_epi32(pix_value_packed);
Toshihiro Shimizu 890ddd
	pix_value_packed_i = _mm_packs_epi32(pix_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
	pix_value_packed_i = _mm_packus_epi16(pix_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	*(DWORD *)(pix_out) = _mm_cvtsi128_si32(pix_value_packed_i);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void inline blendBySSE2(__m128 &pix_out_packed,
Toshihiro Shimizu 890ddd
						float *ink, float *paint, float *tone,
Toshihiro Shimizu 890ddd
						const __m128 &maxtone_packed,
Toshihiro Shimizu 890ddd
						const __m128i &zeros)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	__m128 a_packed = _mm_load_ps(ink);
Toshihiro Shimizu 890ddd
	__m128 b_packed = _mm_load_ps(paint);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 num_packed = _mm_load1_ps(tone);
Toshihiro Shimizu 890ddd
	__m128 diff_packed = _mm_sub_ps(maxtone_packed, num_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// calcola in modo vettoriale out = ((den-num)*a + num*b)/den
Toshihiro Shimizu 890ddd
	pix_out_packed = _mm_mul_ps(diff_packed, a_packed);
Toshihiro Shimizu 890ddd
	__m128 tmpPix_packed = _mm_mul_ps(num_packed, b_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pix_out_packed = _mm_add_ps(pix_out_packed, tmpPix_packed);
Toshihiro Shimizu 890ddd
	pix_out_packed = _mm_div_ps(pix_out_packed, maxtone_packed);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#endif // _WIN32
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void get_prow_gr8(const TRasterGR8P &rin,
Toshihiro Shimizu 890ddd
						 double a11, double a12, double a21, double a22,
Toshihiro Shimizu 890ddd
						 int pmin, int pmax, int q, float *prow)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR *bufin_gr8, *in_gr8;
Toshihiro Shimizu 890ddd
	int u, v;
Toshihiro Shimizu 890ddd
	int p, p1, p2;
Toshihiro Shimizu 890ddd
	UINT lu, lv;
Toshihiro Shimizu 890ddd
	UINT mu, mv;
Toshihiro Shimizu 890ddd
	int du, dv;
Toshihiro Shimizu 890ddd
	double u_0, v_0;
Toshihiro Shimizu 890ddd
	double u_, v_;
Toshihiro Shimizu 890ddd
	double fu, fv;
Toshihiro Shimizu 890ddd
	double gu, gv;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef BORDER
Toshihiro Shimizu 890ddd
#undef BORDER
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#define BORDER BORDER_GR8
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bufin_gr8 = (UCHAR *)rin->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
	du = 1;
Toshihiro Shimizu 890ddd
	dv = rin->getWrap();
Toshihiro Shimizu 890ddd
	u_0 = a12 * q;
Toshihiro Shimizu 890ddd
	v_0 = a22 * q;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (p = pmin; p <= pmax; p++)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if ((UINT)u < mu && (UINT)v < mv)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_gr8 = bufin_gr8 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? in_gr8[du] : BORDER) +
Toshihiro Shimizu 890ddd
									 fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv) ? in_gr8[du + dv] : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * gv * (((UINT)u < lu && (UINT)v < lv) ? in_gr8[0] : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? in_gr8[dv] : BORDER));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	p1 = p;
Toshihiro Shimizu 890ddd
	for (p = pmax; p > p1; p--)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if ((UINT)u < mu && (UINT)v < mv)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_gr8 = bufin_gr8 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? in_gr8[du] : BORDER) +
Toshihiro Shimizu 890ddd
									 fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv) ? in_gr8[du + dv] : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * gv * (((UINT)u < lu && (UINT)v < lv) ? in_gr8[0] : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? in_gr8[dv] : BORDER));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	p2 = p;
Toshihiro Shimizu 890ddd
	for (p = p1; p <= p2; p++)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = (int)(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = (int)(v_);
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_gr8 = bufin_gr8 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * in_gr8[du] + fu * fv * in_gr8[du + dv] +
Toshihiro Shimizu 890ddd
									 gu * gv * in_gr8[0] + gu * fv * in_gr8[dv]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define grey(PIXEL) (TPixelGR8::from(PIXEL).value)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void get_prow_gr8(const TRaster32P &rin,
Toshihiro Shimizu 890ddd
						 double a11, double a12, double a21, double a22,
Toshihiro Shimizu 890ddd
						 int pmin, int pmax, int q, float *prow)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPixel *bufin_32, *in_32;
Toshihiro Shimizu 890ddd
	int u, v;
Toshihiro Shimizu 890ddd
	int p, p1, p2;
Toshihiro Shimizu 890ddd
	UINT lu, lv;
Toshihiro Shimizu 890ddd
	UINT mu, mv;
Toshihiro Shimizu 890ddd
	int du, dv;
Toshihiro Shimizu 890ddd
	double u_0, v_0;
Toshihiro Shimizu 890ddd
	double u_, v_;
Toshihiro Shimizu 890ddd
	double fu, fv;
Toshihiro Shimizu 890ddd
	double gu, gv;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef BORDER
Toshihiro Shimizu 890ddd
#undef BORDER
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#define BORDER BORDER_GR8
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bufin_32 = (TPixel *)rin->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
	du = 1;
Toshihiro Shimizu 890ddd
	dv = rin->getWrap();
Toshihiro Shimizu 890ddd
	u_0 = a12 * q;
Toshihiro Shimizu 890ddd
	v_0 = a22 * q;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (p = pmin; p <= pmax; p++)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if ((UINT)u < mu && (UINT)v < mv)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_32 = bufin_32 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? grey(in_32[du]) : BORDER) +
Toshihiro Shimizu 890ddd
									 fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv) ? grey(in_32[du + dv]) : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * gv * (((UINT)u < lu && (UINT)v < lv) ? grey(in_32[0]) : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? grey(in_32[dv]) : BORDER));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	p1 = p;
Toshihiro Shimizu 890ddd
	for (p = pmax; p > p1; p--)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if ((UINT)u < mu && (UINT)v < mv)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_32 = bufin_32 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? grey(in_32[du]) : BORDER) +
Toshihiro Shimizu 890ddd
									 fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv) ? grey(in_32[du + dv]) : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * gv * (((UINT)u < lu && (UINT)v < lv) ? grey(in_32[0]) : BORDER) +
Toshihiro Shimizu 890ddd
									 gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? grey(in_32[dv]) : BORDER));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	p2 = p;
Toshihiro Shimizu 890ddd
	for (p = p1; p <= p2; p++)
Toshihiro Shimizu 890ddd
		if (!prow[p]) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + a11 * p;
Toshihiro Shimizu 890ddd
			u = (int)(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + a21 * p;
Toshihiro Shimizu 890ddd
			v = (int)(v_);
Toshihiro Shimizu 890ddd
			fu = u_ - u;
Toshihiro Shimizu 890ddd
			gu = 1. - fu;
Toshihiro Shimizu 890ddd
			fv = v_ - v;
Toshihiro Shimizu 890ddd
			gv = 1. - fv;
Toshihiro Shimizu 890ddd
			in_32 = bufin_32 + (u * du + v * dv);
Toshihiro Shimizu 890ddd
			prow[p] = (float)troundp(fu * gv * grey(in_32[du]) + fu * fv * grey(in_32[du + dv]) +
Toshihiro Shimizu 890ddd
									 gu * gv * grey(in_32[0]) + gu * fv * grey(in_32[dv]));
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
typedef float *MyFloatPtr;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void rop_resample_gr8(const TRasterGR8P &rin, TRasterGR8P rout,
Toshihiro Shimizu 890ddd
							 const TAffine &aff, const TAffine &invrot,
Toshihiro Shimizu 890ddd
							 FILTER *rowflt, int pmin, int pmax,
Toshihiro Shimizu 890ddd
							 FILTER *colflt, int qmin, int qmax, int nrows,
Toshihiro Shimizu 890ddd
							 int flatradu, int flatradv,
Toshihiro Shimizu 890ddd
							 double flatradx_, double flatrady_,
Toshihiro Shimizu 890ddd
							 NOCALC *rownoc, int nocdiamx,
Toshihiro Shimizu 890ddd
							 NOCALC *colnoc, int nocdiamy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FILTER *xflt, *yflt;
Toshihiro Shimizu 890ddd
	UCHAR *bufin_gr8, *bufout_gr8, *in_gr8, *out_gr8;
Toshihiro Shimizu 890ddd
	float *prow_base, *prow, **xrow_base, **xrow, *xxx, tmp;
Toshihiro Shimizu 890ddd
	double x_, y_;
Toshihiro Shimizu 890ddd
	int u, v; //, vw;
Toshihiro Shimizu 890ddd
	int p, q;
Toshihiro Shimizu 890ddd
	int x, y;
Toshihiro Shimizu 890ddd
	int lu, lv, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, mx, my;
Toshihiro Shimizu 890ddd
	//int dudp, dudq, dvdp, dvdq;
Toshihiro Shimizu 890ddd
	int topq, topy;
Toshihiro Shimizu 890ddd
	int wrapin, wrapout;
Toshihiro Shimizu 890ddd
	int flatdiamu, flatdiamv;
Toshihiro Shimizu 890ddd
	int xlo, xhi, ylo, yhi;
Toshihiro Shimizu 890ddd
	int *nocheight;
Toshihiro Shimizu 890ddd
	int nocwidth;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bufin_gr8 = (UCHAR *)rin->pixels();
Toshihiro Shimizu 890ddd
	bufout_gr8 = (UCHAR *)rout->pixels();
Toshihiro Shimizu 890ddd
	wrapin = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrapout = rout->getWrap();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	mx = lx - 1;
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	my = ly - 1;
Toshihiro Shimizu 890ddd
	prow_base = new float[pmax - pmin + 1];
Toshihiro Shimizu 890ddd
	prow = prow_base - pmin;
Toshihiro Shimizu 890ddd
	xrow_base = new MyFloatPtr[qmax - (qmin - nrows) + 1];
Toshihiro Shimizu 890ddd
	xrow = xrow_base - (qmin - nrows);
Toshihiro Shimizu 890ddd
	topq = qmin;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//app = xrow+topq-nrows;
Toshihiro Shimizu 890ddd
	i = 0;
Toshihiro Shimizu 890ddd
	j = 3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < nrows; i++)
Toshihiro Shimizu 890ddd
		*(xrow + topq - nrows + i) = new float[lx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//while(app
Toshihiro Shimizu 890ddd
	//  *app++ = new float[lx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	flatdiamu = flatradu * 2 + 1;
Toshihiro Shimizu 890ddd
	flatdiamv = flatradv * 2 + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; y++)
Toshihiro Shimizu 890ddd
		memset(bufout_gr8 + y * wrapout, 127, sizeof(UCHAR) * lx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int count = 0; /* !!!!!!!!!!!!!!!!*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int *colheight;
Toshihiro Shimizu 890ddd
	UCHAR *colval;
Toshihiro Shimizu 890ddd
	int flatcols;
Toshihiro Shimizu 890ddd
	UCHAR flatval;
Toshihiro Shimizu 890ddd
	double xlo_, xhi_, ylo_, yhi_;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*  TCALLOC (colheight, lu);
Toshihiro Shimizu 890ddd
  TCALLOC (colval,    lu);*/
Toshihiro Shimizu 890ddd
	colheight = new int[lu];
Toshihiro Shimizu 890ddd
	//memset(colheight, 0, lu);
Toshihiro Shimizu 890ddd
	colval = new UCHAR[lu];
Toshihiro Shimizu 890ddd
	//memset(colval, 0, lu);
Toshihiro Shimizu 890ddd
	for (u = 0; u < (int)lu; u++) {
Toshihiro Shimizu 890ddd
		colheight[u] = 0;
Toshihiro Shimizu 890ddd
		colval[u] = BORDER_GR8;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (v = 0; v < (int)lv; v++) {
Toshihiro Shimizu 890ddd
		x_ = affMV1(aff, 0 - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
		y_ = affMV2(aff, 0 - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		xlo_ = tceil(x_ - flatradx_);
Toshihiro Shimizu 890ddd
		xhi_ = tfloor(x_ + flatradx_);
Toshihiro Shimizu 890ddd
		ylo_ = tceil(y_ - flatrady_);
Toshihiro Shimizu 890ddd
		yhi_ = tfloor(y_ + flatrady_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		flatcols = 0;
Toshihiro Shimizu 890ddd
		flatval = BORDER_GR8;
Toshihiro Shimizu 890ddd
		for (u = 0, in_gr8 = bufin_gr8 + v * wrapin; u < (int)lu; u++, in_gr8++) {
Toshihiro Shimizu 890ddd
			if (*in_gr8 == colval[u])
Toshihiro Shimizu 890ddd
				colheight[u]++;
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				colheight[u] = 1;
Toshihiro Shimizu 890ddd
				colval[u] = *in_gr8;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (colheight[u] >= flatdiamv)
Toshihiro Shimizu 890ddd
				if (colval[u] == flatval)
Toshihiro Shimizu 890ddd
					flatcols++;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					flatcols = 1;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				flatcols = 0;
Toshihiro Shimizu 890ddd
			flatval = colval[u];
Toshihiro Shimizu 890ddd
			if (flatcols >= flatdiamu) {
Toshihiro Shimizu 890ddd
#ifdef VECCHIA_MANIERA
Toshihiro Shimizu 890ddd
				x_ = AFF_M_V_1(aff, u - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
				y_ = AFF_M_V_2(aff, u - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
				xlo = CEIL(x_ - flatradx_);
Toshihiro Shimizu 890ddd
				xhi = FLOOR(x_ + flatradx_);
Toshihiro Shimizu 890ddd
				ylo = CEIL(y_ - flatrady_);
Toshihiro Shimizu 890ddd
				yhi = FLOOR(y_ + flatrady_);
Toshihiro Shimizu 890ddd
				NOT_LESS_THAN(0, xlo);
Toshihiro Shimizu 890ddd
				NOT_MORE_THAN(mx, xhi);
Toshihiro Shimizu 890ddd
				NOT_LESS_THAN(0, ylo);
Toshihiro Shimizu 890ddd
				NOT_MORE_THAN(my, yhi);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 12c444
				xlo = std::max(0, (int)xlo_);
Shinya Kitaoka 12c444
				xhi = std::min(mx, (int)xhi_);
Shinya Kitaoka 12c444
				ylo = std::max(0, (int)ylo_);
Shinya Kitaoka 12c444
				yhi = std::min(my, (int)yhi_);
Toshihiro Shimizu 890ddd
				for (y = ylo; y <= yhi; y++)
Toshihiro Shimizu 890ddd
					for (x = xlo; x <= xhi; x++)
Toshihiro Shimizu 890ddd
						bufout_gr8[x + y * wrapout] = flatval, count++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			xlo_ += aff.a11;
Toshihiro Shimizu 890ddd
			xhi_ += aff.a11;
Toshihiro Shimizu 890ddd
			ylo_ += aff.a21;
Toshihiro Shimizu 890ddd
			yhi_ += aff.a21;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	delete colval;
Toshihiro Shimizu 890ddd
	delete colheight;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	topy = 0;
Toshihiro Shimizu 890ddd
	/*TCALLOC (nocheight, lx);*/
Toshihiro Shimizu 890ddd
	nocheight = new int[lx];
Toshihiro Shimizu 890ddd
	memset(nocheight, 0, lx * sizeof(int));
Toshihiro Shimizu 890ddd
	out_gr8 = bufout_gr8;
Toshihiro Shimizu 890ddd
	for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
		if (out_gr8[x] != GREY_GR8)
Toshihiro Shimizu 890ddd
			nocheight[x]++;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			nocheight[x] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = 0, yflt = colflt; y < ly; y++, yflt++) {
Toshihiro Shimizu 890ddd
		for (; topq <= yflt->last; topq++) {
Toshihiro Shimizu 890ddd
			xrow[topq] = xrow[topq - nrows];
Toshihiro Shimizu 890ddd
			xxx = xrow[topq];
Toshihiro Shimizu 890ddd
			memset(xxx, 0, sizeof(*xxx) * lx); /* 0.0 == nocalc */
Toshihiro Shimizu 890ddd
			while (topy < ly - 1 && colnoc[topy].last < topq) {
Toshihiro Shimizu 890ddd
				topy++;
Toshihiro Shimizu 890ddd
				out_gr8 = bufout_gr8 + topy * wrapout;
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					if (out_gr8[x] != GREY_GR8)
Toshihiro Shimizu 890ddd
						nocheight[x]++;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						nocheight[x] = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (topy < ly && colnoc[topy].first <= topq) {
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					if (nocheight[x] < nocdiamy)
Toshihiro Shimizu 890ddd
						xxx[x] = 1.0; /* 1.0 == calc */
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					xxx[x] = 1.0; /* 1.0 == calc */
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			memset(prow + pmin, 0, sizeof(*prow) * (pmax - pmin + 1)); /* 0.0 == calc */
Toshihiro Shimizu 890ddd
			nocwidth = 0;
Toshihiro Shimizu 890ddd
			for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
				if (xxx[x])
Toshihiro Shimizu 890ddd
					nocwidth = 0;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					nocwidth++;
Toshihiro Shimizu 890ddd
					if (nocwidth >= nocdiamx)
Toshihiro Shimizu 890ddd
						for (p = rownoc[x].first; p <= rownoc[x].last; p++)
Toshihiro Shimizu 890ddd
							prow[p] = 1.0; /* 1.0 == nocalc */
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			get_prow_gr8(rin, invrot.a11, invrot.a12, invrot.a21, invrot.a22,
Toshihiro Shimizu 890ddd
						 pmin, pmax, topq, prow);
Toshihiro Shimizu 890ddd
			for (x = 0, xflt = rowflt; x < lx; x++, xflt++)
Toshihiro Shimizu 890ddd
				if (xxx[x]) {
Toshihiro Shimizu 890ddd
					for (tmp = 0.0, p = xflt->first; p <= xflt->last; p++)
Toshihiro Shimizu 890ddd
						tmp += xflt->w[p] * prow[p];
Toshihiro Shimizu 890ddd
					xxx[x] = tmp;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		out_gr8 = bufout_gr8 + wrapout * y;
Toshihiro Shimizu 890ddd
		for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
			if (out_gr8[x] == GREY_GR8) {
Toshihiro Shimizu 890ddd
				for (tmp = 0.0, q = yflt->first; q <= yflt->last; q++)
Toshihiro Shimizu 890ddd
					tmp += yflt->w[q] * xrow[q][x];
Toshihiro Shimizu 890ddd
				out_gr8[x] = TO8BIT(tmp);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//cest_plus_facile (xrow);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (q = 0; q < nrows; q++)
Toshihiro Shimizu 890ddd
		delete xrow_base[q];
Toshihiro Shimizu 890ddd
	delete xrow_base;
Toshihiro Shimizu 890ddd
	delete prow_base;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void rop_resample_rgbm32_gr8(const TRaster32P &rin, TRasterGR8P rout,
Toshihiro Shimizu 890ddd
									const TAffine &aff, const TAffine &invrot,
Toshihiro Shimizu 890ddd
									FILTER *rowflt, int pmin, int pmax,
Toshihiro Shimizu 890ddd
									FILTER *colflt, int qmin, int qmax, int nrows,
Toshihiro Shimizu 890ddd
									int flatradu, int flatradv,
Toshihiro Shimizu 890ddd
									double flatradx_, double flatrady_,
Toshihiro Shimizu 890ddd
									NOCALC *rownoc, int nocdiamx,
Toshihiro Shimizu 890ddd
									NOCALC *colnoc, int nocdiamy)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FILTER *xflt, *yflt;
Toshihiro Shimizu 890ddd
	UCHAR *bufout_gr8, *out_gr8;
Toshihiro Shimizu 890ddd
	TPixel *bufin_32, *in_32;
Toshihiro Shimizu 890ddd
	float *prow_base, *prow, **xrow_base, **xrow, *xxx, tmp;
Toshihiro Shimizu 890ddd
	double x_, y_;
Toshihiro Shimizu 890ddd
	int u, v; //, vw;
Toshihiro Shimizu 890ddd
	int p, q;
Toshihiro Shimizu 890ddd
	int x, y;
Toshihiro Shimizu 890ddd
	int lu, lv, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, mx, my;
Toshihiro Shimizu 890ddd
	//int dudp, dudq, dvdp, dvdq;
Toshihiro Shimizu 890ddd
	int topq, topy;
Toshihiro Shimizu 890ddd
	int wrapin, wrapout;
Toshihiro Shimizu 890ddd
	int flatdiamu, flatdiamv;
Toshihiro Shimizu 890ddd
	int xlo, xhi, ylo, yhi;
Toshihiro Shimizu 890ddd
	int *nocheight;
Toshihiro Shimizu 890ddd
	int nocwidth;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bufin_32 = (TPixel *)rin->pixels();
Toshihiro Shimizu 890ddd
	bufout_gr8 = (UCHAR *)rout->pixels();
Toshihiro Shimizu 890ddd
	wrapin = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrapout = rout->getWrap();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	mx = lx - 1;
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	my = ly - 1;
Toshihiro Shimizu 890ddd
	prow_base = new float[pmax - pmin + 1];
Toshihiro Shimizu 890ddd
	prow = prow_base - pmin;
Toshihiro Shimizu 890ddd
	xrow_base = new MyFloatPtr[qmax - (qmin - nrows) + 1];
Toshihiro Shimizu 890ddd
	xrow = xrow_base - (qmin - nrows);
Toshihiro Shimizu 890ddd
	topq = qmin;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//app = xrow+topq-nrows;
Toshihiro Shimizu 890ddd
	i = 0;
Toshihiro Shimizu 890ddd
	j = 3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < nrows; i++)
Toshihiro Shimizu 890ddd
		*(xrow + topq - nrows + i) = new float[lx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//while(app
Toshihiro Shimizu 890ddd
	//  *app++ = new float[lx];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	flatdiamu = flatradu * 2 + 1;
Toshihiro Shimizu 890ddd
	flatdiamv = flatradv * 2 + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; y++)
Toshihiro Shimizu 890ddd
		memset(bufout_gr8 + y * wrapout, 127, sizeof(UCHAR) * lx);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int count = 0; /* !!!!!!!!!!!!!!!!*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int *colheight;
Toshihiro Shimizu 890ddd
	UCHAR *colval;
Toshihiro Shimizu 890ddd
	int flatcols;
Toshihiro Shimizu 890ddd
	UCHAR flatval;
Toshihiro Shimizu 890ddd
	double xlo_, xhi_, ylo_, yhi_;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*  TCALLOC (colheight, lu);
Toshihiro Shimizu 890ddd
  TCALLOC (colval,    lu);*/
Toshihiro Shimizu 890ddd
	colheight = new int[lu];
Toshihiro Shimizu 890ddd
	//memset(colheight, 0, lu);
Toshihiro Shimizu 890ddd
	colval = new UCHAR[lu];
Toshihiro Shimizu 890ddd
	//memset(colval, 0, lu);
Toshihiro Shimizu 890ddd
	for (u = 0; u < (int)lu; u++) {
Toshihiro Shimizu 890ddd
		colheight[u] = 0;
Toshihiro Shimizu 890ddd
		colval[u] = BORDER_GR8;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	for (v = 0; v < (int)lv; v++) {
Toshihiro Shimizu 890ddd
		x_ = affMV1(aff, 0 - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
		y_ = affMV2(aff, 0 - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		xlo_ = tceil(x_ - flatradx_);
Toshihiro Shimizu 890ddd
		xhi_ = tfloor(x_ + flatradx_);
Toshihiro Shimizu 890ddd
		ylo_ = tceil(y_ - flatrady_);
Toshihiro Shimizu 890ddd
		yhi_ = tfloor(y_ + flatrady_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		flatcols = 0;
Toshihiro Shimizu 890ddd
		flatval = BORDER_GR8;
Toshihiro Shimizu 890ddd
		for (u = 0, in_32 = bufin_32 + v * wrapin; u < (int)lu; u++, in_32++) {
Toshihiro Shimizu 890ddd
			if (grey(*in_32) == colval[u])
Toshihiro Shimizu 890ddd
				colheight[u]++;
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				colheight[u] = 1;
Toshihiro Shimizu 890ddd
				colval[u] = grey(*in_32);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (colheight[u] >= flatdiamv)
Toshihiro Shimizu 890ddd
				if (colval[u] == flatval)
Toshihiro Shimizu 890ddd
					flatcols++;
Toshihiro Shimizu 890ddd
				else
Toshihiro Shimizu 890ddd
					flatcols = 1;
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				flatcols = 0;
Toshihiro Shimizu 890ddd
			flatval = colval[u];
Toshihiro Shimizu 890ddd
			if (flatcols >= flatdiamu) {
Toshihiro Shimizu 890ddd
#ifdef VECCHIA_MANIERA
Toshihiro Shimizu 890ddd
				x_ = AFF_M_V_1(aff, u - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
				y_ = AFF_M_V_2(aff, u - flatradu, v - flatradv);
Toshihiro Shimizu 890ddd
				xlo = CEIL(x_ - flatradx_);
Toshihiro Shimizu 890ddd
				xhi = FLOOR(x_ + flatradx_);
Toshihiro Shimizu 890ddd
				ylo = CEIL(y_ - flatrady_);
Toshihiro Shimizu 890ddd
				yhi = FLOOR(y_ + flatrady_);
Toshihiro Shimizu 890ddd
				NOT_LESS_THAN(0, xlo);
Toshihiro Shimizu 890ddd
				NOT_MORE_THAN(mx, xhi);
Toshihiro Shimizu 890ddd
				NOT_LESS_THAN(0, ylo);
Toshihiro Shimizu 890ddd
				NOT_MORE_THAN(my, yhi);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 12c444
				xlo = std::max(0, (int)xlo_);
Shinya Kitaoka 12c444
				xhi = std::min(mx, (int)xhi_);
Shinya Kitaoka 12c444
				ylo = std::max(0, (int)ylo_);
Shinya Kitaoka 12c444
				yhi = std::min(my, (int)yhi_);
Toshihiro Shimizu 890ddd
				for (y = ylo; y <= yhi; y++)
Toshihiro Shimizu 890ddd
					for (x = xlo; x <= xhi; x++)
Toshihiro Shimizu 890ddd
						bufout_gr8[x + y * wrapout] = flatval, count++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			xlo_ += aff.a11;
Toshihiro Shimizu 890ddd
			xhi_ += aff.a11;
Toshihiro Shimizu 890ddd
			ylo_ += aff.a21;
Toshihiro Shimizu 890ddd
			yhi_ += aff.a21;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	delete colval;
Toshihiro Shimizu 890ddd
	delete colheight;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	topy = 0;
Toshihiro Shimizu 890ddd
	/*TCALLOC (nocheight, lx);*/
Toshihiro Shimizu 890ddd
	nocheight = new int[lx];
Toshihiro Shimizu 890ddd
	memset(nocheight, 0, lx * sizeof(int));
Toshihiro Shimizu 890ddd
	out_gr8 = bufout_gr8;
Toshihiro Shimizu 890ddd
	for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
		if (out_gr8[x] != GREY_GR8)
Toshihiro Shimizu 890ddd
			nocheight[x]++;
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			nocheight[x] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (y = 0, yflt = colflt; y < ly; y++, yflt++) {
Toshihiro Shimizu 890ddd
		for (; topq <= yflt->last; topq++) {
Toshihiro Shimizu 890ddd
			xrow[topq] = xrow[topq - nrows];
Toshihiro Shimizu 890ddd
			xxx = xrow[topq];
Toshihiro Shimizu 890ddd
			memset(xxx, 0, sizeof(*xxx) * lx); /* 0.0 == nocalc */
Toshihiro Shimizu 890ddd
			while (topy < ly - 1 && colnoc[topy].last < topq) {
Toshihiro Shimizu 890ddd
				topy++;
Toshihiro Shimizu 890ddd
				out_gr8 = bufout_gr8 + topy * wrapout;
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					if (out_gr8[x] != GREY_GR8)
Toshihiro Shimizu 890ddd
						nocheight[x]++;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						nocheight[x] = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (topy < ly && colnoc[topy].first <= topq) {
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					if (nocheight[x] < nocdiamy)
Toshihiro Shimizu 890ddd
						xxx[x] = 1.0; /* 1.0 == calc */
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
					xxx[x] = 1.0; /* 1.0 == calc */
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			memset(prow + pmin, 0, sizeof(*prow) * (pmax - pmin + 1)); /* 0.0 == calc */
Toshihiro Shimizu 890ddd
			nocwidth = 0;
Toshihiro Shimizu 890ddd
			for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
				if (xxx[x])
Toshihiro Shimizu 890ddd
					nocwidth = 0;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					nocwidth++;
Toshihiro Shimizu 890ddd
					if (nocwidth >= nocdiamx)
Toshihiro Shimizu 890ddd
						for (p = rownoc[x].first; p <= rownoc[x].last; p++)
Toshihiro Shimizu 890ddd
							prow[p] = 1.0; /* 1.0 == nocalc */
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			get_prow_gr8(rin, invrot.a11, invrot.a12, invrot.a21, invrot.a22,
Toshihiro Shimizu 890ddd
						 pmin, pmax, topq, prow);
Toshihiro Shimizu 890ddd
			for (x = 0, xflt = rowflt; x < lx; x++, xflt++)
Toshihiro Shimizu 890ddd
				if (xxx[x]) {
Toshihiro Shimizu 890ddd
					for (tmp = 0.0, p = xflt->first; p <= xflt->last; p++)
Toshihiro Shimizu 890ddd
						tmp += xflt->w[p] * prow[p];
Toshihiro Shimizu 890ddd
					xxx[x] = tmp;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		out_gr8 = bufout_gr8 + wrapout * y;
Toshihiro Shimizu 890ddd
		for (x = 0; x < lx; x++)
Toshihiro Shimizu 890ddd
			if (out_gr8[x] == GREY_GR8) {
Toshihiro Shimizu 890ddd
				for (tmp = 0.0, q = yflt->first; q <= yflt->last; q++)
Toshihiro Shimizu 890ddd
					tmp += yflt->w[q] * xrow[q][x];
Toshihiro Shimizu 890ddd
				out_gr8[x] = TO8BIT(tmp);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//cest_plus_facile (xrow);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (q = 0; q < nrows; q++)
Toshihiro Shimizu 890ddd
		delete xrow_base[q];
Toshihiro Shimizu 890ddd
	delete xrow_base;
Toshihiro Shimizu 890ddd
	delete prow_base;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// #define USE_STATIC_VARS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void rop_resample_rgbm(TRasterPT<t> rout, const TRasterPT<t> &rin,</t></t>
Toshihiro Shimizu 890ddd
					   const TAffine &aff, TRop::ResampleFilterType flt_type, double blur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#define FILTER_RESOLUTION 1024
Toshihiro Shimizu 890ddd
#define MAX_FILTER_VAL 32767
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	static TRop::ResampleFilterType current_flt_type = TRop::None;
Shinya Kitaoka 42bfb6
	static std::unique_ptr<short[]> filter_array;</short[]>
Toshihiro Shimizu 890ddd
	static short *filter = 0;
Toshihiro Shimizu 890ddd
	static int min_filter_fg, max_filter_fg;
Toshihiro Shimizu 890ddd
	static int filter_array_size = 0;
Toshihiro Shimizu 890ddd
	static int n_pix = 0;
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_g;</int[]>
Toshihiro Shimizu 890ddd
	static int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 42bfb6
	std::unique_ptr<short[]> filter_array;</short[]>
Toshihiro Shimizu 890ddd
	short *filter = 0;
Toshihiro Shimizu 890ddd
	int min_filter_fg, max_filter_fg;
Toshihiro Shimizu 890ddd
	int filter_array_size = 0;
Toshihiro Shimizu 890ddd
	int n_pix = 0;
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_g;</int[]>
Toshihiro Shimizu 890ddd
	int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	int filter_st_radius;
Toshihiro Shimizu 890ddd
	int filter_fg_radius;
Toshihiro Shimizu 890ddd
	int filter_size;
Toshihiro Shimizu 890ddd
	int f;
Toshihiro Shimizu 890ddd
	double s_;
Toshihiro Shimizu 890ddd
	double weight_;
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
	TAffine aff_uv2xy;
Toshihiro Shimizu 890ddd
	TAffine aff_xy2uv;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2xy;
Toshihiro Shimizu 890ddd
	TAffine aff0_xy2st;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2st;
Toshihiro Shimizu 890ddd
	TAffine aff0_st2fg;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2fg;
Toshihiro Shimizu 890ddd
	TAffine aff0_fg2uv;
Toshihiro Shimizu 890ddd
	double scale_x, scale_y;
Toshihiro Shimizu 890ddd
	double inv_blur;
Toshihiro Shimizu 890ddd
	int max_n_pix;
Toshihiro Shimizu 890ddd
	double min_pix_out_u_, min_pix_out_v_;
Toshihiro Shimizu 890ddd
	double max_pix_out_u_, max_pix_out_v_;
Toshihiro Shimizu 890ddd
	int min_pix_ref_u, min_pix_ref_v;
Toshihiro Shimizu 890ddd
	int max_pix_ref_u, max_pix_ref_v;
Toshihiro Shimizu 890ddd
	int cur_pix_ref_u, cur_pix_ref_v;
Toshihiro Shimizu 890ddd
	double cur_pix_ref_f_, cur_pix_ref_g_;
Toshihiro Shimizu 890ddd
	int cur_pix_ref_f, cur_pix_ref_g;
Toshihiro Shimizu 890ddd
	double min_ref_out_f_, min_ref_out_g_;
Toshihiro Shimizu 890ddd
	double max_ref_out_f_, max_ref_out_g_;
Toshihiro Shimizu 890ddd
	int min_ref_out_f, min_ref_out_g;
Toshihiro Shimizu 890ddd
	int max_ref_out_f, max_ref_out_g;
Toshihiro Shimizu 890ddd
	int min_pix_ref_f, min_pix_ref_g;
Toshihiro Shimizu 890ddd
	int max_pix_ref_f, max_pix_ref_g;
Toshihiro Shimizu 890ddd
	int min_pix_out_f, min_pix_out_g;
Toshihiro Shimizu 890ddd
	int max_pix_out_f, max_pix_out_g;
Toshihiro Shimizu 890ddd
	int min_pix_out_fg;
Toshihiro Shimizu 890ddd
	int max_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(flt_type != TRop::None);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the filter radius in the st and fx references
Toshihiro Shimizu 890ddd
	filter_st_radius = get_filter_radius(flt_type);
Toshihiro Shimizu 890ddd
	filter_fg_radius = filter_st_radius * FILTER_RESOLUTION;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Retrieve the transformation affines among the involved references
Toshihiro Shimizu 890ddd
	//NOTE: The 0.5 translation is needed in order to make the later
Toshihiro Shimizu 890ddd
	//resample_main procedures work with pixel centers.
Toshihiro Shimizu 890ddd
	aff_uv2xy = aff * TTranslation(0.5, 0.5);
Toshihiro Shimizu 890ddd
	aff0_uv2xy = aff_uv2xy.place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
	aff_xy2uv = aff_uv2xy.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Consider the norm of (1,0) and (0,1) images.
Toshihiro Shimizu 890ddd
	scale_x = sqrt(sq(aff_uv2xy.a11) + sq(aff_uv2xy.a12));
Toshihiro Shimizu 890ddd
	scale_y = sqrt(sq(aff_uv2xy.a21) + sq(aff_uv2xy.a22));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Inserting the following scale will make shrinks look smooth.
Toshihiro Shimizu 890ddd
	aff0_xy2st = TScale((scale_x > 1.0) ? 1.0 / scale_x : 1.0,
Toshihiro Shimizu 890ddd
						(scale_y > 1.0) ? 1.0 / scale_y : 1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (blur > 1.0) //Consider the blur as a scale in the filter reference
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		inv_blur = 1.0 / blur;
Toshihiro Shimizu 890ddd
		aff0_xy2st = TScale(inv_blur, inv_blur) * aff0_xy2st;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aff0_uv2st = aff0_xy2st * aff0_uv2xy;
Toshihiro Shimizu 890ddd
	aff0_st2fg = TScale(FILTER_RESOLUTION, FILTER_RESOLUTION);
Toshihiro Shimizu 890ddd
	aff0_uv2fg = aff0_st2fg * aff0_uv2st;
Toshihiro Shimizu 890ddd
	aff0_fg2uv = aff0_uv2fg.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Take the pre-image of the filter mask in uv coordinates. This is where
Toshihiro Shimizu 890ddd
	//input pixels will be taken to find an output one.
Toshihiro Shimizu 890ddd
	minmax(-filter_fg_radius, -filter_fg_radius,
Toshihiro Shimizu 890ddd
		   filter_fg_radius, filter_fg_radius,
Toshihiro Shimizu 890ddd
		   aff0_fg2uv,
Toshihiro Shimizu 890ddd
		   min_pix_out_u_, min_pix_out_v_,
Toshihiro Shimizu 890ddd
		   max_pix_out_u_, max_pix_out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Adjust them to integer coordinates. The intent here is that
Toshihiro Shimizu 890ddd
	//of isolating their fractionary part - furthermore, we'll take
Toshihiro Shimizu 890ddd
	//the *opposites* of fractionary parts (explained later).
Toshihiro Shimizu 890ddd
	//NOTE: We'll assume we want to include in the filter mask all
Toshihiro Shimizu 890ddd
	//*integer positions around a fractionary displacement of the origin*;
Toshihiro Shimizu 890ddd
	//so the approximations below are stricly necessary.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_pix_ref_u = intLE(min_pix_out_u_);
Toshihiro Shimizu 890ddd
	min_pix_ref_v = intLE(min_pix_out_v_);
Toshihiro Shimizu 890ddd
	max_pix_ref_u = intGE(max_pix_out_u_);
Toshihiro Shimizu 890ddd
	max_pix_ref_v = intGE(max_pix_out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (blur <= 1.0) {
Toshihiro Shimizu 890ddd
		//If the blur radius has sub-pixel width
Toshihiro Shimizu 890ddd
		if (aff_uv2xy.a12 == 0.0 && aff_uv2xy.a21 == 0.0) {
Toshihiro Shimizu 890ddd
			//And it's the sole scales case
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a11 == 1.0 && isInt(aff_uv2xy.a13 - 0.5)) {
Toshihiro Shimizu 890ddd
				//And the x mapping is bijective, then prevent any filtering.
Toshihiro Shimizu 890ddd
				min_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a22 == 1.0 && isInt(aff_uv2xy.a23 - 0.5)) {
Toshihiro Shimizu 890ddd
				//And the y mapping is bijective ...
Toshihiro Shimizu 890ddd
				min_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (aff_uv2xy.a11 == 0.0 && aff_uv2xy.a22 == 0.0) {
Toshihiro Shimizu 890ddd
			//The mirrored version of the one above
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a12 == 1.0 && isInt(aff_uv2xy.a13 - 0.5)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a21 == 1.0 && isInt(aff_uv2xy.a23 - 0.5)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Take the number of pixels involved in the filter (uv reference)
Toshihiro Shimizu 890ddd
	max_n_pix = (max_pix_ref_u - min_pix_ref_u + 1) *
Toshihiro Shimizu 890ddd
				(max_pix_ref_v - min_pix_ref_v + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (max_n_pix > current_max_n_pix) {
Toshihiro Shimizu 890ddd
		current_max_n_pix = max_n_pix;
Shinya Kitaoka 42bfb6
		pix_ref_u.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_v.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_f.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_g.reset(new int[current_max_n_pix]);
Toshihiro Shimizu 890ddd
		assert(pix_ref_u && pix_ref_v && pix_ref_f && pix_ref_g);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build the image of fractionary domain from the uv to fg reference
Toshihiro Shimizu 890ddd
	minmax(-1, -1, 0, 0,
Toshihiro Shimizu 890ddd
		   aff0_uv2fg,
Toshihiro Shimizu 890ddd
		   min_ref_out_f_, min_ref_out_g_,
Toshihiro Shimizu 890ddd
		   max_ref_out_f_, max_ref_out_g_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_ref_out_f = tround(min_ref_out_f_);
Toshihiro Shimizu 890ddd
	min_ref_out_g = tround(min_ref_out_g_);
Toshihiro Shimizu 890ddd
	max_ref_out_f = tround(max_ref_out_f_);
Toshihiro Shimizu 890ddd
	max_ref_out_g = tround(max_ref_out_g_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Remember that negative fractionary parts must be subtracted from their integer counterparts
Toshihiro Shimizu 890ddd
	min_pix_ref_f = -filter_fg_radius - max_ref_out_f;
Toshihiro Shimizu 890ddd
	min_pix_ref_g = -filter_fg_radius - max_ref_out_g;
Toshihiro Shimizu 890ddd
	max_pix_ref_f = filter_fg_radius - min_ref_out_f;
Toshihiro Shimizu 890ddd
	max_pix_ref_g = filter_fg_radius - min_ref_out_g;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_pix_out_f = c_maxint;
Toshihiro Shimizu 890ddd
	min_pix_out_g = c_maxint;
Toshihiro Shimizu 890ddd
	max_pix_out_f = c_minint;
Toshihiro Shimizu 890ddd
	max_pix_out_g = c_minint;
Toshihiro Shimizu 890ddd
	n_pix = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!pix_ref_u || !pix_ref_v || !pix_ref_f || !pix_ref_g) {
Toshihiro Shimizu 890ddd
		throw TRopException("tresample.cpp line2640  function rop_resample_rgbm() : alloc pix_ref failed");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Build the *integer* part of the fg images of those coordinates inside the uv filter bounds.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//NOTE: Doing so reduces the execution time for the later resample_main procedure -
Toshihiro Shimizu 890ddd
	//the idea is the following:
Toshihiro Shimizu 890ddd
	//  We want to build the output pixel (x,y) obtained from the source image through A.
Toshihiro Shimizu 890ddd
	//  Then, we find (u,v) = (A^-1) * (x,y) = ([u],[v]) + ({u},{v}), where [] and {}
Toshihiro Shimizu 890ddd
	//  denote integer and fractionary parts.
Toshihiro Shimizu 890ddd
	//  Now, the convolution positions on fg for (u,v) can be thought of being calculated by taking
Toshihiro Shimizu 890ddd
	//  images of integer displacements of (u,v). So, their calculation is definitely *not* directly
Toshihiro Shimizu 890ddd
	//  dependent on the fractionary part of (u,v) - that is, the (i,j)th displacement position of FG(u,v)
Toshihiro Shimizu 890ddd
	//  is:
Toshihiro Shimizu 890ddd
	//          FG([u]+i,[v]+j) = FG(u+i,v+j) - FG({u},{v}) = FG(i,j) - FG({u},{v});
Toshihiro Shimizu 890ddd
	//
Toshihiro Shimizu 890ddd
	//  where it is assumed that FG(u,v) = (0,0), since the filter is to be considered centered on (u,v).
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (cur_pix_ref_v = min_pix_ref_v;
Toshihiro Shimizu 890ddd
		 cur_pix_ref_v <= max_pix_ref_v;
Toshihiro Shimizu 890ddd
		 cur_pix_ref_v++)
Toshihiro Shimizu 890ddd
		for (cur_pix_ref_u = min_pix_ref_u;
Toshihiro Shimizu 890ddd
			 cur_pix_ref_u <= max_pix_ref_u;
Toshihiro Shimizu 890ddd
			 cur_pix_ref_u++) {
Toshihiro Shimizu 890ddd
			//Get the image of current uv position
Toshihiro Shimizu 890ddd
			cur_pix_ref_f_ = affMV1(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Toshihiro Shimizu 890ddd
			cur_pix_ref_g_ = affMV2(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			//And round it to the closest integer in fg
Toshihiro Shimizu 890ddd
			cur_pix_ref_f = tround(cur_pix_ref_f_);
Toshihiro Shimizu 890ddd
			cur_pix_ref_g = tround(cur_pix_ref_g_);
Toshihiro Shimizu 890ddd
			if (min_pix_ref_f <= cur_pix_ref_f && cur_pix_ref_f <= max_pix_ref_f &&
Toshihiro Shimizu 890ddd
				min_pix_ref_g <= cur_pix_ref_g && cur_pix_ref_g <= max_pix_ref_g) {
Toshihiro Shimizu 890ddd
				pix_ref_u[n_pix] = cur_pix_ref_u;
Toshihiro Shimizu 890ddd
				pix_ref_v[n_pix] = cur_pix_ref_v;
Toshihiro Shimizu 890ddd
				pix_ref_f[n_pix] = cur_pix_ref_f;
Toshihiro Shimizu 890ddd
				pix_ref_g[n_pix] = cur_pix_ref_g;
Toshihiro Shimizu 890ddd
				notMoreThan(cur_pix_ref_f + min_ref_out_f, min_pix_out_f); //cur_pix_ref > min_pix_out - min_ref_out
Toshihiro Shimizu 890ddd
				notMoreThan(cur_pix_ref_g + min_ref_out_g, min_pix_out_g);
Toshihiro Shimizu 890ddd
				notLessThan(cur_pix_ref_f + max_ref_out_f, max_pix_out_f); //cur_pix_ref < max_pix_out - max_ref_out
Toshihiro Shimizu 890ddd
				notLessThan(cur_pix_ref_g + max_ref_out_g, max_pix_out_g);
Toshihiro Shimizu 890ddd
				n_pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	assert(n_pix > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	if (flt_type != current_flt_type) {
Toshihiro Shimizu 890ddd
		current_flt_type = flt_type;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Build a sufficient filter weights array
Toshihiro Shimizu 890ddd
		min_filter_fg = -filter_fg_radius - FILTER_RESOLUTION * 3 / 2; //???
Toshihiro Shimizu 890ddd
		max_filter_fg = filter_fg_radius + FILTER_RESOLUTION * 3 / 2;
Toshihiro Shimizu 890ddd
		filter_size = max_filter_fg - min_filter_fg + 1;
Toshihiro Shimizu 890ddd
		if (filter_size > filter_array_size) //For the static vars case...
Toshihiro Shimizu 890ddd
		{
Shinya Kitaoka 42bfb6
			filter_array.reset(new short[filter_size]);
Toshihiro Shimizu 890ddd
			assert(filter_array);
Toshihiro Shimizu 890ddd
			filter_array_size = filter_size;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka 42bfb6
		filter = filter_array.get() - min_filter_fg; //Take the position corresponding to fg's (0,0) in the array
Toshihiro Shimizu 890ddd
		filter[0] = MAX_FILTER_VAL;
Toshihiro Shimizu 890ddd
		for (f = 1, s_ = 1.0 / FILTER_RESOLUTION;
Toshihiro Shimizu 890ddd
			 f < filter_fg_radius;
Toshihiro Shimizu 890ddd
			 f++, s_ += 1.0 / FILTER_RESOLUTION) {
Toshihiro Shimizu 890ddd
			//Symmetrically build the array
Toshihiro Shimizu 890ddd
			weight_ = get_filter_value(flt_type, s_) * (double)MAX_FILTER_VAL;
Toshihiro Shimizu 890ddd
			weight = tround(weight_);
Toshihiro Shimizu 890ddd
			filter[f] = weight;
Toshihiro Shimizu 890ddd
			filter[-f] = weight;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (f = filter_fg_radius; f <= max_filter_fg; f++)
Toshihiro Shimizu 890ddd
			filter[f] = 0;
Toshihiro Shimizu 890ddd
		for (f = -filter_fg_radius; f >= min_filter_fg; f--)
Toshihiro Shimizu 890ddd
			filter[f] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Considering the bounding square in fg
Shinya Kitaoka 12c444
	min_pix_out_fg = std::min(min_pix_out_f, min_pix_out_g);
Shinya Kitaoka 12c444
	max_pix_out_fg = std::max(max_pix_out_f, max_pix_out_g);
Toshihiro Shimizu 890ddd
	if (min_pix_out_fg < min_filter_fg || max_pix_out_fg > max_filter_fg) {
Toshihiro Shimizu 890ddd
		//Reallocate the filter... and so on...
Toshihiro Shimizu 890ddd
		filter_size = max_pix_out_fg - min_pix_out_fg + 1;
Toshihiro Shimizu 890ddd
		if (filter_size > filter_array_size) {
Toshihiro Shimizu 890ddd
			//controllare!!
Toshihiro Shimizu 890ddd
			//TREALLOC (filter_array, filter_size)
Shinya Kitaoka 42bfb6
			filter_array.reset(new short[filter_size]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			assert(filter_array);
Toshihiro Shimizu 890ddd
			filter_array_size = filter_size;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka 42bfb6
		filter = filter_array.get() - min_filter_fg;
Toshihiro Shimizu 890ddd
		if (min_pix_out_fg < min_filter_fg) {
Toshihiro Shimizu 890ddd
			int delta = min_filter_fg - min_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (f = max_filter_fg; f >= min_filter_fg; f--)
Toshihiro Shimizu 890ddd
				filter[f + delta] = filter[f];
Toshihiro Shimizu 890ddd
			filter += delta;
Toshihiro Shimizu 890ddd
			for (f = min_filter_fg - 1; f >= min_pix_out_fg; f--)
Toshihiro Shimizu 890ddd
				filter[f] = 0;
Toshihiro Shimizu 890ddd
			min_filter_fg = min_pix_out_fg;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (max_pix_out_fg > max_filter_fg) {
Toshihiro Shimizu 890ddd
			for (f = max_filter_fg + 1; f <= max_pix_out_fg; f++)
Toshihiro Shimizu 890ddd
				filter[f] = 0;
Toshihiro Shimizu 890ddd
			max_filter_fg = max_pix_out_fg;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	if ((TSystem::getCPUExtensions() & TSystem::CpuSupportsSse2) && T::maxChannelValue == 255)
Toshihiro Shimizu 890ddd
		resample_main_rgbm_SSE2<t>(rout, rin, aff_xy2uv, aff0_uv2fg,</t>
Toshihiro Shimizu 890ddd
								   min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
								   max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
								   n_pix,
Shinya Kitaoka 42bfb6
								   pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 42bfb6
								   pix_ref_f.get(), pix_ref_g.get(),
Toshihiro Shimizu 890ddd
								   filter);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		if (n_pix >= 512 || T::maxChannelValue > 255)
Toshihiro Shimizu 890ddd
		resample_main_rgbm<t, tint64="">(</t,>
Toshihiro Shimizu 890ddd
			rout, rin, aff_xy2uv, aff0_uv2fg,
Toshihiro Shimizu 890ddd
			min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
			max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
			n_pix,
Shinya Kitaoka 42bfb6
			pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 42bfb6
			pix_ref_f.get(), pix_ref_g.get(),
Toshihiro Shimizu 890ddd
			filter);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		resample_main_rgbm<t, tint32="">(</t,>
Toshihiro Shimizu 890ddd
			rout, rin, aff_xy2uv, aff0_uv2fg,
Toshihiro Shimizu 890ddd
			min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
			max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
			n_pix,
Shinya Kitaoka 42bfb6
			pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 42bfb6
			pix_ref_f.get(), pix_ref_g.get(),
Toshihiro Shimizu 890ddd
			filter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static void free_filter(FILTER *filter, int lx)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (--lx; lx >= 0; lx--)
Toshihiro Shimizu 890ddd
		if (filter[lx].w_base)
Toshihiro Shimizu 890ddd
			delete (filter[lx].w_base);
Toshihiro Shimizu 890ddd
	delete (filter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void do_resample(TRasterGR8P rout, const TRasterGR8P &rin,
Toshihiro Shimizu 890ddd
				 const TAffine &aff, TRop::ResampleFilterType flt_type, double blur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double jacob;
Toshihiro Shimizu 890ddd
	double s11, s22, s13, s23;
Toshihiro Shimizu 890ddd
	FILTER *rowf, *colf;
Toshihiro Shimizu 890ddd
	NOCALC *rown, *coln;
Toshihiro Shimizu 890ddd
	int pmin, pmax, qmin, qmax;
Toshihiro Shimizu 890ddd
	int nrows, dummy;
Toshihiro Shimizu 890ddd
	double negradu_, negradv_, posradu_, posradv_;
Toshihiro Shimizu 890ddd
	double negradx_, negrady_, posradx_, posrady_;
Toshihiro Shimizu 890ddd
	int nocdiamx, nocdiamy;
Toshihiro Shimizu 890ddd
	double rad_x, rad_y;
Toshihiro Shimizu 890ddd
	TAffine rot, scale, invrot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		rout->fill(TPixelGR8::Black); //Black_rgbm
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterGR8P routGR8 = rout, rinGR8 = rin;
Toshihiro Shimizu 890ddd
	if (routGR8 && rinGR8) {
Toshihiro Shimizu 890ddd
		jacob = fabs(aff.det());
Toshihiro Shimizu 890ddd
		if (jacob == 0.0)
Toshihiro Shimizu 890ddd
			throw TRopException("AFFINE transformation has zero determinant");
Toshihiro Shimizu 890ddd
		if (jacob < 1E-30)
Toshihiro Shimizu 890ddd
			throw TRopException("AFFINE transformation has (nearly) zero determinant");
Toshihiro Shimizu 890ddd
		s11 = sqrt(jacob); /* provvisorio */
Toshihiro Shimizu 890ddd
		s22 = s11;
Toshihiro Shimizu 890ddd
		s13 = aff.a13;
Toshihiro Shimizu 890ddd
		s23 = aff.a23;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//rot = aff_place (0.0, 0.0, 0.0, 0.0, TScale(1/s11, 1/s22)*aff);//eventualmente invertire ordine
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//scale = aff_place (0.0, 0.0, s13, s23, TScale(s11, s22));
Toshihiro Shimizu 890ddd
		scale = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Toshihiro Shimizu 890ddd
		invrot = rot.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
							 rad_x, pmin, pmax, dummy);
Toshihiro Shimizu 890ddd
		colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
							 rad_y, qmin, qmax, nrows);
Toshihiro Shimizu 890ddd
		rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
							 pmin, pmax, nocdiamx);
Toshihiro Shimizu 890ddd
		coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
							 qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Toshihiro Shimizu 890ddd
		malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Toshihiro Shimizu 890ddd
		CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TAffine aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
		TAffine inv_0 = aff_0.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		minmax(-0.5, -0.5, 0.5, 0.5, aff_0,
Toshihiro Shimizu 890ddd
			   negradx_, negrady_, posradx_, posrady_);
Toshihiro Shimizu 890ddd
		double flatradx_ = posradx_;
Toshihiro Shimizu 890ddd
		double flatrady_ = posrady_;
Toshihiro Shimizu 890ddd
		minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y, inv_0,
Toshihiro Shimizu 890ddd
			   negradu_, negradv_, posradu_, posradv_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int flatradu = tceil(posradu_) - 1;
Toshihiro Shimizu 890ddd
		int flatradv = tceil(posradv_) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		rop_resample_gr8(rin, rout, aff, invrot,
Toshihiro Shimizu 890ddd
						 rowf, pmin, pmax, colf, qmin, qmax, nrows,
Toshihiro Shimizu 890ddd
						 flatradu, flatradv, flatradx_, flatrady_,
Toshihiro Shimizu 890ddd
						 rown, nocdiamx, coln, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//free_nocalc (coln);
Toshihiro Shimizu 890ddd
		if (coln)
Toshihiro Shimizu 890ddd
			delete (coln);
Toshihiro Shimizu 890ddd
		//free_nocalc (rown);
Toshihiro Shimizu 890ddd
		if (rown)
Toshihiro Shimizu 890ddd
			delete (rown);
Toshihiro Shimizu 890ddd
		free_filter(colf, rout->getLy());
Toshihiro Shimizu 890ddd
		free_filter(rowf, rout->getLx());
Toshihiro Shimizu 890ddd
		//----NON GESTIAMO ANCORA EXTRA BUFFER
Toshihiro Shimizu 890ddd
		//rop_resample_extra (rin, rout, aff);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void do_resample(TRasterGR8P rout, const TRaster32P &rin,
Toshihiro Shimizu 890ddd
				 const TAffine &aff, TRop::ResampleFilterType flt_type, double blur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double jacob;
Toshihiro Shimizu 890ddd
	double s11, s22, s13, s23;
Toshihiro Shimizu 890ddd
	FILTER *rowf, *colf;
Toshihiro Shimizu 890ddd
	NOCALC *rown, *coln;
Toshihiro Shimizu 890ddd
	int pmin, pmax, qmin, qmax;
Toshihiro Shimizu 890ddd
	int nrows, dummy;
Toshihiro Shimizu 890ddd
	double negradu_, negradv_, posradu_, posradv_;
Toshihiro Shimizu 890ddd
	double negradx_, negrady_, posradx_, posrady_;
Toshihiro Shimizu 890ddd
	int nocdiamx, nocdiamy;
Toshihiro Shimizu 890ddd
	double rad_x, rad_y;
Toshihiro Shimizu 890ddd
	TAffine rot, scale, invrot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		rout->fill(TPixelGR8::Black); //Black_rgbm
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	jacob = fabs(aff.det());
Toshihiro Shimizu 890ddd
	if (jacob == 0.0)
Toshihiro Shimizu 890ddd
		throw TRopException("AFFINE transformation has zero determinant");
Toshihiro Shimizu 890ddd
	if (jacob < 1E-30)
Toshihiro Shimizu 890ddd
		throw TRopException("AFFINE transformation has (nearly) zero determinant");
Toshihiro Shimizu 890ddd
	s11 = sqrt(jacob); /* provvisorio */
Toshihiro Shimizu 890ddd
	s22 = s11;
Toshihiro Shimizu 890ddd
	s13 = aff.a13;
Toshihiro Shimizu 890ddd
	s23 = aff.a23;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//rot = aff_place (0.0, 0.0, 0.0, 0.0, TScale(1/s11, 1/s22)*aff);//eventualmente invertire ordine
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//scale = aff_place (0.0, 0.0, s13, s23, TScale(s11, s22));
Toshihiro Shimizu 890ddd
	scale = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Toshihiro Shimizu 890ddd
	invrot = rot.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
						 rad_x, pmin, pmax, dummy);
Toshihiro Shimizu 890ddd
	colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
						 rad_y, qmin, qmax, nrows);
Toshihiro Shimizu 890ddd
	rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
						 pmin, pmax, nocdiamx);
Toshihiro Shimizu 890ddd
	coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
						 qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Toshihiro Shimizu 890ddd
	malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Toshihiro Shimizu 890ddd
	CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TAffine aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
	TAffine inv_0 = aff_0.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	minmax(-0.5, -0.5, 0.5, 0.5, aff_0,
Toshihiro Shimizu 890ddd
		   negradx_, negrady_, posradx_, posrady_);
Toshihiro Shimizu 890ddd
	double flatradx_ = posradx_;
Toshihiro Shimizu 890ddd
	double flatrady_ = posrady_;
Toshihiro Shimizu 890ddd
	minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y, inv_0,
Toshihiro Shimizu 890ddd
		   negradu_, negradv_, posradu_, posradv_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int flatradu = tceil(posradu_) - 1;
Toshihiro Shimizu 890ddd
	int flatradv = tceil(posradv_) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rop_resample_rgbm32_gr8(rin, rout, aff, invrot,
Toshihiro Shimizu 890ddd
							rowf, pmin, pmax, colf, qmin, qmax, nrows,
Toshihiro Shimizu 890ddd
							flatradu, flatradv, flatradx_, flatrady_,
Toshihiro Shimizu 890ddd
							rown, nocdiamx, coln, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//free_nocalc (coln);
Toshihiro Shimizu 890ddd
	if (coln)
Toshihiro Shimizu 890ddd
		delete (coln);
Toshihiro Shimizu 890ddd
	//free_nocalc (rown);
Toshihiro Shimizu 890ddd
	if (rown)
Toshihiro Shimizu 890ddd
		delete (rown);
Toshihiro Shimizu 890ddd
	free_filter(colf, rout->getLy());
Toshihiro Shimizu 890ddd
	free_filter(rowf, rout->getLx());
Toshihiro Shimizu 890ddd
	//----NON GESTIAMO ANCORA EXTRA BUFFER
Toshihiro Shimizu 890ddd
	//rop_resample_extra (rin, rout, aff);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// else throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void do_resample(TRasterPT<t> rout, const TRasterPT<t> &rin,</t></t>
Toshihiro Shimizu 890ddd
				 const TAffine &aff, TRop::ResampleFilterType flt_type, double blur)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifdef ALTRI_TIPI_DI_RASTER
Toshihiro Shimizu 890ddd
	double jacob;
Toshihiro Shimizu 890ddd
	double s11, s22, s13, s23;
Toshihiro Shimizu 890ddd
	FILTER *rowf, *colf;
Toshihiro Shimizu 890ddd
	NOCALC *rown, *coln;
Toshihiro Shimizu 890ddd
	int pmin, pmax, qmin, qmax;
Toshihiro Shimizu 890ddd
	int nrows, dummy;
Toshihiro Shimizu 890ddd
	double negradu_, negradv_, posradu_, posradv_;
Toshihiro Shimizu 890ddd
	double negradx_, negrady_, posradx_, posrady_;
Toshihiro Shimizu 890ddd
	int nocdiamx, nocdiamy;
Toshihiro Shimizu 890ddd
	double rad_x, rad_y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		rout->fill(T::Black); //Black_rgbm
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRasterPT<t> rout_ = rout, rin_ = rin;</t>
Toshihiro Shimizu 890ddd
	if (rout_ && rin_) {
Toshihiro Shimizu 890ddd
		rop_resample_rgbm<t>(rout, rin, aff, flt_type, blur);</t>
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef ALTRI_TIPI_DI_RASTER
Toshihiro Shimizu 890ddd
	jacob = fabs(aff.det());
Toshihiro Shimizu 890ddd
	if (jacob == 0.0)
Toshihiro Shimizu 890ddd
		throw TRopException("AFFINE transformation has zero determinant");
Toshihiro Shimizu 890ddd
	if (jacob < 1E-30)
Toshihiro Shimizu 890ddd
		throw TRopException("AFFINE transformation has (nearly) zero determinant");
Toshihiro Shimizu 890ddd
	s11 = sqrt(jacob); /* provvisorio */
Toshihiro Shimizu 890ddd
	s22 = s11;
Toshihiro Shimizu 890ddd
	s13 = aff.a13;
Toshihiro Shimizu 890ddd
	s23 = aff.a23;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scale = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Toshihiro Shimizu 890ddd
	invrot = rot.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
						 rad_x, pmin, pmax, dummy);
Toshihiro Shimizu 890ddd
	colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
						 rad_y, qmin, qmax, nrows);
Toshihiro Shimizu 890ddd
	rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Toshihiro Shimizu 890ddd
						 pmin, pmax, nocdiamx);
Toshihiro Shimizu 890ddd
	coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Toshihiro Shimizu 890ddd
						 qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Toshihiro Shimizu 890ddd
	malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Toshihiro Shimizu 890ddd
	CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
	inv_0 = aff_0.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	minmax(-0.5, -0.5, 0.5, 0.5, aff_0,
Toshihiro Shimizu 890ddd
		   negradx_, negrady_, posradx_, posrady_);
Toshihiro Shimizu 890ddd
	minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y, inv_0,
Toshihiro Shimizu 890ddd
		   negradu_, negradv_, posradu_, posradv_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (coln)
Toshihiro Shimizu 890ddd
		delete (coln);
Toshihiro Shimizu 890ddd
	if (rown)
Toshihiro Shimizu 890ddd
		delete (rown);
Toshihiro Shimizu 890ddd
	free_filter(colf, rout->getLy());
Toshihiro Shimizu 890ddd
	free_filter(rowf, rout->getLx());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef struct
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	TUINT32 val;
Toshihiro Shimizu 890ddd
	double tot;
Toshihiro Shimizu 890ddd
} BLOB24;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define MINOREQ(x, a) ((x) >= 0 && (x) <= (a))
Toshihiro Shimizu 890ddd
#define MINOR(x, a) ((x) >= 0 && (x) < (a))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
void do_resample(TRasterCM32P rout, const TRasterCM32P &rin, const TAffine &aff)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TAffine inv;
Toshihiro Shimizu 890ddd
	int lx, ly, mx, my;
Toshihiro Shimizu 890ddd
	int lu, lv, mu, mv;
Toshihiro Shimizu 890ddd
	int x, y, u, v;
Toshihiro Shimizu 890ddd
	double u_0, v_0, u_, v_;
Toshihiro Shimizu 890ddd
	double fu, fv, gu, gv;
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
	int wrapin, wrapout;
Toshihiro Shimizu 890ddd
	TUINT32 *bufin_tcm, *bufout_tcm;
Toshihiro Shimizu 890ddd
	TUINT32 *in_tcm, *out_tcm;
Toshihiro Shimizu 890ddd
	TUINT32 tcm[4];
Toshihiro Shimizu 890ddd
	double w[4];
Toshihiro Shimizu 890ddd
	TUINT32 transp;
Toshihiro Shimizu 890ddd
	BLOB24 color_blob[4], new_color_blob;
Toshihiro Shimizu 890ddd
	BLOB24 pencil_blob[4], new_pencil_blob;
Toshihiro Shimizu 890ddd
	int color_blobs;
Toshihiro Shimizu 890ddd
	int pencil_blobs;
Toshihiro Shimizu 890ddd
	bool some_pencil;
Toshihiro Shimizu 890ddd
	double tone_tot;
Toshihiro Shimizu 890ddd
	TUINT32 color_mask, pencil_mask;
Toshihiro Shimizu 890ddd
	TUINT32 tone_mask;
Toshihiro Shimizu 890ddd
	int tone;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rout->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for (y = 0; y < rout->getLy(); y++)
Toshihiro Shimizu 890ddd
			for (x = 0; x < rout->getLx(); x++)
Toshihiro Shimizu 890ddd
				((TUINT32 *)rout->getRawData())[x + y * rout->getWrap()] = 0xff;
Toshihiro Shimizu 890ddd
		rout->unlock();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rin->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bufin_tcm = (TUINT32 *)rin->getRawData();
Toshihiro Shimizu 890ddd
	bufout_tcm = (TUINT32 *)rout->getRawData();
Toshihiro Shimizu 890ddd
	wrapin = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrapout = rout->getWrap();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	mx = lx - 1;
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	my = ly - 1;
Toshihiro Shimizu 890ddd
	inv = aff.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	pencil_mask = TPixelCM32::getInkMask();
Toshihiro Shimizu 890ddd
	color_mask = TPixelCM32::getPaintMask();
Toshihiro Shimizu 890ddd
	tone_mask = TPixelCM32::getToneMask();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	transp = tone_mask;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(tone_mask & 0x1); //Ensure that tone lies in the less significative bits
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//deal with every output line independently
Toshihiro Shimizu 890ddd
	for (y = 0; y < ly; y++) {
Toshihiro Shimizu 890ddd
		//Take inv*(0,y)
Toshihiro Shimizu 890ddd
		u_0 = inv.a12 * y + inv.a13;
Toshihiro Shimizu 890ddd
		v_0 = inv.a22 * y + inv.a23;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		out_tcm = bufout_tcm + wrapout * y;
Toshihiro Shimizu 890ddd
		x = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Place transparent pixels until we reach a useful source pos.
Toshihiro Shimizu 890ddd
		for (; x < lx; x++) {
Toshihiro Shimizu 890ddd
			//Add inv*(x,0) and floor it
Toshihiro Shimizu 890ddd
			u_ = u_0 + x * inv.a11;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + x * inv.a21;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if (MINOREQ(u + 1, lu) && MINOREQ(v + 1, lv)) //u>=-1 && u<lu &&="" v="">=-1 && v</lu>
Toshihiro Shimizu 890ddd
				break;									  //Goto next for
Toshihiro Shimizu 890ddd
			*out_tcm++ = transp;						  //Otherwise, place a transparent pixel
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Deal with leftwise border pre-images
Toshihiro Shimizu 890ddd
		for (; x < lx; x++) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + x * inv.a11;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + x * inv.a21;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if (MINOR(u, lu) && MINOR(v, lv)) //u>=0 && u<lu &&="" v="">=0 && v</lu>
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			in_tcm = bufin_tcm + u + v * wrapin;
Toshihiro Shimizu 890ddd
			bool u0 = MINOREQ(u, mu);
Toshihiro Shimizu 890ddd
			bool v0 = MINOREQ(v, mv);
Toshihiro Shimizu 890ddd
			bool u1 = MINOREQ(u + 1, mv);
Toshihiro Shimizu 890ddd
			bool v1 = MINOREQ(v + 1, mv);
Toshihiro Shimizu 890ddd
			tcm[0] = (u0 && v0) ? in_tcm[0] : transp;
Toshihiro Shimizu 890ddd
			tcm[1] = (u1 && v0) ? in_tcm[1] : transp;
Toshihiro Shimizu 890ddd
			tcm[2] = (u0 && v1) ? in_tcm[wrapin] : transp;
Toshihiro Shimizu 890ddd
			tcm[3] = (u1 && v1) ? in_tcm[wrapin + 1] : transp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Toshihiro Shimizu 890ddd
				*out_tcm++ = tcm[0];
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				fu = u_ - u;
Toshihiro Shimizu 890ddd
				gu = 1. - fu;
Toshihiro Shimizu 890ddd
				fv = v_ - v;
Toshihiro Shimizu 890ddd
				gv = 1. - fv;
Toshihiro Shimizu 890ddd
				w[0] = gu * gv;
Toshihiro Shimizu 890ddd
				w[2] = gu * fv;
Toshihiro Shimizu 890ddd
				w[1] = fu * gv;
Toshihiro Shimizu 890ddd
				w[3] = fu * fv;
Toshihiro Shimizu 890ddd
				color_blobs = pencil_blobs = 0;
Toshihiro Shimizu 890ddd
				tone_tot = 0.0;
Toshihiro Shimizu 890ddd
				some_pencil = false;
Toshihiro Shimizu 890ddd
				for (i = 0; i < 4; i++) {
Toshihiro Shimizu 890ddd
					tone = tcm[i] & tone_mask;
Toshihiro Shimizu 890ddd
					if ((TUINT32)tone != tone_mask)
Toshihiro Shimizu 890ddd
						some_pencil = true;
Toshihiro Shimizu 890ddd
					tone_tot += tone * w[i];
Toshihiro Shimizu 890ddd
					new_color_blob.val = tcm[i] & color_mask;
Toshihiro Shimizu 890ddd
					new_color_blob.tot = tone * w[i];
Toshihiro Shimizu 890ddd
					for (j = 0; j < color_blobs; j++)
Toshihiro Shimizu 890ddd
						if (color_blob[j].val == new_color_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < color_blobs)
Toshihiro Shimizu 890ddd
						color_blob[j].tot += new_color_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						color_blob[color_blobs++] = new_color_blob;
Toshihiro Shimizu 890ddd
					for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(color_blob[j], color_blob[j - 1]);
Toshihiro Shimizu 890ddd
					new_pencil_blob.val = tcm[i] & pencil_mask;
Toshihiro Shimizu 890ddd
					new_pencil_blob.tot = (tone_mask - tone) * w[i];
Toshihiro Shimizu 890ddd
					for (j = 0; j < pencil_blobs; j++)
Toshihiro Shimizu 890ddd
						if (pencil_blob[j].val == new_pencil_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < pencil_blobs)
Toshihiro Shimizu 890ddd
						pencil_blob[j].tot += new_pencil_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						pencil_blob[pencil_blobs++] = new_pencil_blob;
Toshihiro Shimizu 890ddd
					for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(pencil_blob[j], pencil_blob[j - 1]);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				tone = troundp(tone_tot);
Toshihiro Shimizu 890ddd
				//if (some_pencil && (TUINT32)tone == tone_mask)
Toshihiro Shimizu 890ddd
				//  tone--;
Toshihiro Shimizu 890ddd
				//if (color_blob[0].val==0 && pencil_blob[0].val==0)
Toshihiro Shimizu 890ddd
				//  tone = 255;
Toshihiro Shimizu 890ddd
				*out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Deal with useful source positions on the output line's pre-image
Toshihiro Shimizu 890ddd
		for (; x < lx; x++) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + x * inv.a11;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + x * inv.a21;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if (!(MINOR(u, lu) && MINOR(v, lv))) //u<0 || u>=lu || v<0 || v>=lv
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			in_tcm = bufin_tcm + u + v * wrapin; //Take the associated input pixel pointer
Toshihiro Shimizu 890ddd
			tcm[0] = in_tcm[0];
Toshihiro Shimizu 890ddd
			if (u < lu - 1 && v < lv - 1) {
Toshihiro Shimizu 890ddd
				//Also take their 4 next neighours (we shall perform a kinf of bilinear interpolation)
Toshihiro Shimizu 890ddd
				tcm[1] = in_tcm[1];
Toshihiro Shimizu 890ddd
				tcm[2] = in_tcm[wrapin];
Toshihiro Shimizu 890ddd
				tcm[3] = in_tcm[wrapin + 1];
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				//Eventually, simulate the off-boundary ones
Toshihiro Shimizu 890ddd
				tcm[1] = (u == lu - 1) ? in_tcm[0] : in_tcm[1];
Toshihiro Shimizu 890ddd
				tcm[2] = (v == lv - 1) ? in_tcm[0] : in_tcm[wrapin];
Toshihiro Shimizu 890ddd
				tcm[3] = (u == lu - 1 || v == lv - 1) ? in_tcm[0] : in_tcm[wrapin + 1];
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Toshihiro Shimizu 890ddd
				*out_tcm++ = tcm[0]; //If they are all equal, it's a copy-op
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				//Otherwise, take the bilinear coordinates
Toshihiro Shimizu 890ddd
				fu = u_ - u;
Toshihiro Shimizu 890ddd
				gu = 1. - fu;
Toshihiro Shimizu 890ddd
				fv = v_ - v;
Toshihiro Shimizu 890ddd
				gv = 1. - fv;
Toshihiro Shimizu 890ddd
				w[0] = gu * gv;
Toshihiro Shimizu 890ddd
				w[2] = gu * fv; //And the associated weights
Toshihiro Shimizu 890ddd
				w[1] = fu * gv;
Toshihiro Shimizu 890ddd
				w[3] = fu * fv;
Toshihiro Shimizu 890ddd
				color_blobs = pencil_blobs = 0;
Toshihiro Shimizu 890ddd
				tone_tot = 0.0;
Toshihiro Shimizu 890ddd
				some_pencil = false;
Toshihiro Shimizu 890ddd
				//Examine all neighbouring pixels
Toshihiro Shimizu 890ddd
				for (i = 0; i < 4; i++) {
Toshihiro Shimizu 890ddd
					tone = tcm[i] & tone_mask; //Take the tone
Toshihiro Shimizu 890ddd
					if ((TUINT32)tone != tone_mask)
Toshihiro Shimizu 890ddd
						some_pencil = true;
Toshihiro Shimizu 890ddd
					tone_tot += tone * w[i]; //Build the weighted tone sum
Toshihiro Shimizu 890ddd
					new_color_blob.val = tcm[i] & color_mask;
Toshihiro Shimizu 890ddd
					new_color_blob.tot = tone * w[i]; //And the weighted paint tone for this pixel
Toshihiro Shimizu 890ddd
					//Fill in the different colors found in an array. Equal colors are stored as one
Toshihiro Shimizu 890ddd
					//with summed weighted total tone.
Toshihiro Shimizu 890ddd
					for (j = 0; j < color_blobs; j++)
Toshihiro Shimizu 890ddd
						if (color_blob[j].val == new_color_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < color_blobs)
Toshihiro Shimizu 890ddd
						color_blob[j].tot += new_color_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						color_blob[color_blobs++] = new_color_blob;
Toshihiro Shimizu 890ddd
					//Sort the stored colors for decreasing weighted total tone
Toshihiro Shimizu 890ddd
					for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(color_blob[j], color_blob[j - 1]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					//Deal the same way with ink colors.
Toshihiro Shimizu 890ddd
					new_pencil_blob.val = tcm[i] & pencil_mask;
Toshihiro Shimizu 890ddd
					new_pencil_blob.tot = (tone_mask - tone) * w[i];
Toshihiro Shimizu 890ddd
					for (j = 0; j < pencil_blobs; j++)
Toshihiro Shimizu 890ddd
						if (pencil_blob[j].val == new_pencil_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < pencil_blobs)
Toshihiro Shimizu 890ddd
						pencil_blob[j].tot += new_pencil_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						pencil_blob[pencil_blobs++] = new_pencil_blob;
Toshihiro Shimizu 890ddd
					for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(pencil_blob[j], pencil_blob[j - 1]);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				tone = tround(tone_tot);
Toshihiro Shimizu 890ddd
				//if (some_pencil && (TUINT32)tone == tone_mask)
Toshihiro Shimizu 890ddd
				//  tone--;
Toshihiro Shimizu 890ddd
				//if (color_blob[0].val==0 && pencil_blob[0].val==0)
Toshihiro Shimizu 890ddd
				//  tone = 255;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//The output colors shall be the ones with maximum weighted total tone,
Toshihiro Shimizu 890ddd
				//with the overall total tone as output tone.
Toshihiro Shimizu 890ddd
				*out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Again, deal with border pixels at the end of line's pre-image
Toshihiro Shimizu 890ddd
		for (; x < lx; x++) {
Toshihiro Shimizu 890ddd
			u_ = u_0 + x * inv.a11;
Toshihiro Shimizu 890ddd
			u = tfloor(u_);
Toshihiro Shimizu 890ddd
			v_ = v_0 + x * inv.a21;
Toshihiro Shimizu 890ddd
			v = tfloor(v_);
Toshihiro Shimizu 890ddd
			if (!(MINOREQ(u + 1, lu) && MINOREQ(v + 1, lv))) //u<-1 || u>=lu || v<-1 || v>=lv
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			in_tcm = bufin_tcm + u + v * wrapin;
Toshihiro Shimizu 890ddd
			bool u0 = MINOREQ(u, mu);
Toshihiro Shimizu 890ddd
			bool v0 = MINOREQ(v, mv);
Toshihiro Shimizu 890ddd
			bool u1 = MINOREQ(u + 1, mv);
Toshihiro Shimizu 890ddd
			bool v1 = MINOREQ(v + 1, mv);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			tcm[0] = (u0 && v0) ? in_tcm[0] : transp;
Toshihiro Shimizu 890ddd
			tcm[1] = (u1 && v0) ? in_tcm[1] : transp;
Toshihiro Shimizu 890ddd
			tcm[2] = (u0 && v1) ? in_tcm[wrapin] : transp;
Toshihiro Shimizu 890ddd
			tcm[3] = (u1 && v1) ? in_tcm[wrapin + 1] : transp;
Toshihiro Shimizu 890ddd
			if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Toshihiro Shimizu 890ddd
				*out_tcm++ = tcm[0];
Toshihiro Shimizu 890ddd
			else {
Toshihiro Shimizu 890ddd
				fu = u_ - u;
Toshihiro Shimizu 890ddd
				gu = 1. - fu;
Toshihiro Shimizu 890ddd
				fv = v_ - v;
Toshihiro Shimizu 890ddd
				gv = 1. - fv;
Toshihiro Shimizu 890ddd
				w[0] = gu * gv;
Toshihiro Shimizu 890ddd
				w[2] = gu * fv;
Toshihiro Shimizu 890ddd
				w[1] = fu * gv;
Toshihiro Shimizu 890ddd
				w[3] = fu * fv;
Toshihiro Shimizu 890ddd
				color_blobs = pencil_blobs = 0;
Toshihiro Shimizu 890ddd
				tone_tot = 0.0;
Toshihiro Shimizu 890ddd
				some_pencil = false;
Toshihiro Shimizu 890ddd
				for (i = 0; i < 4; i++) {
Toshihiro Shimizu 890ddd
					tone = tcm[i] & tone_mask;
Toshihiro Shimizu 890ddd
					if ((TUINT32)tone != tone_mask)
Toshihiro Shimizu 890ddd
						some_pencil = true;
Toshihiro Shimizu 890ddd
					tone_tot += tone * w[i];
Toshihiro Shimizu 890ddd
					new_color_blob.val = tcm[i] & color_mask;
Toshihiro Shimizu 890ddd
					new_color_blob.tot = tone * w[i];
Toshihiro Shimizu 890ddd
					for (j = 0; j < color_blobs; j++)
Toshihiro Shimizu 890ddd
						if (color_blob[j].val == new_color_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < color_blobs)
Toshihiro Shimizu 890ddd
						color_blob[j].tot += new_color_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						color_blob[color_blobs++] = new_color_blob;
Toshihiro Shimizu 890ddd
					for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(color_blob[j], color_blob[j - 1]);
Toshihiro Shimizu 890ddd
					new_pencil_blob.val = tcm[i] & pencil_mask;
Toshihiro Shimizu 890ddd
					new_pencil_blob.tot = (tone_mask - tone) * w[i];
Toshihiro Shimizu 890ddd
					for (j = 0; j < pencil_blobs; j++)
Toshihiro Shimizu 890ddd
						if (pencil_blob[j].val == new_pencil_blob.val)
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
					if (j < pencil_blobs)
Toshihiro Shimizu 890ddd
						pencil_blob[j].tot += new_pencil_blob.tot;
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						pencil_blob[pencil_blobs++] = new_pencil_blob;
Toshihiro Shimizu 890ddd
					for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Toshihiro Shimizu 890ddd
						tswap(pencil_blob[j], pencil_blob[j - 1]);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				tone = troundp(tone_tot);
Toshihiro Shimizu 890ddd
				//if (some_pencil && (TUINT32)tone == tone_mask)
Toshihiro Shimizu 890ddd
				//  tone--;
Toshihiro Shimizu 890ddd
				//if (color_blob[0].val==0 && pencil_blob[0].val==0)
Toshihiro Shimizu 890ddd
				//  tone = 255;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				*out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Finally, deal with out-of-source pixels at the end of line's pre-image
Toshihiro Shimizu 890ddd
		for (; x < lx; x++)
Toshihiro Shimizu 890ddd
			*out_tcm++ = transp;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rin->unlock();
Toshihiro Shimizu 890ddd
	rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void resample_main_cm32_rgbm_SSE2(TRasterPT<t> rout, const TRasterCM32P &rin,</t>
Toshihiro Shimizu 890ddd
								  const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
								  const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
								  int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
								  int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
								  int n_pix,
Toshihiro Shimizu 890ddd
								  int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
								  int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
								  short *filter, TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	__m128i zeros = _mm_setzero_si128();
Toshihiro Shimizu 890ddd
	const TPixelCM32 *buffer_in;
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int inside_offset_u, inside_offset_v;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	double outside_min_u_, outside_min_v_;
Toshihiro Shimizu 890ddd
	double outside_max_u_, outside_max_v_;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	T pix_value;
Toshihiro Shimizu 890ddd
	T default_value(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	float weight;
Toshihiro Shimizu 890ddd
	float sum_weights;
Toshihiro Shimizu 890ddd
	float inv_sum_weights;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T *pix_out;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 sum_contribs_packed;
Toshihiro Shimizu 890ddd
	__m128 pix_value_packed;
Toshihiro Shimizu 890ddd
	__m128 weight_packed;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	__m128 zeros2 = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float maxChannelValue = (float)T::maxChannelValue;
Toshihiro Shimizu 890ddd
	__m128 maxChanneValue_packed = _mm_load1_ps(&maxChannelValue);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		resample_clear_rgbm(rout, default_value);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inside_offset_u = -min_pix_ref_u;
Toshihiro Shimizu 890ddd
	inside_offset_v = -min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - max_pix_ref_u - inside_offset_u;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - max_pix_ref_v - inside_offset_v;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_min_v_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_max_u_ = lu - 0.5;
Toshihiro Shimizu 890ddd
	outside_max_v_ = lv - 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int count = palette->getStyleCount();
Shinya Kitaoka 12c444
	int count2 = std::max({count, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TPixelFloat *paints = (TPixelFloat *)_aligned_malloc(count2 * sizeof(TPixelFloat), 16);
Toshihiro Shimizu 890ddd
	TPixelFloat *inks = (TPixelFloat *)_aligned_malloc(count2 * sizeof(TPixelFloat), 16);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> paints2(count2);</tpixel32>
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> inks2(count2);</tpixel32>
Toshihiro Shimizu 890ddd
	for (i = 0; i < palette->getStyleCount(); i++) {
Toshihiro Shimizu 890ddd
		TPixel32 color = ::premultiply(palette->getStyle(i)->getAverageColor());
Toshihiro Shimizu 890ddd
		paints[i] = inks[i] = TPixelFloat(color);
Toshihiro Shimizu 890ddd
		paints2[i] = inks2[i] = color;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	float maxTone = (float)TPixelCM32::getMaxTone();
Toshihiro Shimizu 890ddd
	__m128 den_packed = _mm_load1_ps(&maxTone);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			pix_out = buffer_out + out_y * wrap_out + out_x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					sum_contribs_packed = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Toshihiro Shimizu 890ddd
						int tone = pix_in->getTone();
Toshihiro Shimizu 890ddd
						int paint = pix_in->getPaint();
Toshihiro Shimizu 890ddd
						int ink = pix_in->getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value_packed = _mm_load_ps((float *)&(paints[paint]));
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value_packed = _mm_load_ps((float *)&(inks[ink]));
Toshihiro Shimizu 890ddd
						else {
Toshihiro Shimizu 890ddd
							float tt = (float)tone;
Toshihiro Shimizu 890ddd
							blendBySSE2(
Toshihiro Shimizu 890ddd
								pix_value_packed, // il valore calcolato
Toshihiro Shimizu 890ddd
								(float *)&(inks[ink]),
Toshihiro Shimizu 890ddd
								(float *)&(paints[paint]),
Toshihiro Shimizu 890ddd
								&tt, den_packed, zeros);
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						weight_packed = _mm_load1_ps(&weight);
Toshihiro Shimizu 890ddd
						sum_contribs_packed = _mm_add_ps(sum_contribs_packed, _mm_mul_ps(pix_value_packed, weight_packed));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0f / sum_weights;
Toshihiro Shimizu 890ddd
					__m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128 out_fval_packed = _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packs_epi32(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packus_epi16(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					*(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Toshihiro Shimizu 890ddd
					int tone = pix_in->getTone();
Toshihiro Shimizu 890ddd
					int paint = pix_in->getPaint();
Toshihiro Shimizu 890ddd
					int ink = pix_in->getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						*pix_out = paints2[paint];
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						*pix_out = inks2[ink];
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						*pix_out = blend(inks2[ink], paints2[paint], tone, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Toshihiro Shimizu 890ddd
					   outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_packed = _mm_setzero_ps();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u);
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Toshihiro Shimizu 890ddd
						int tone = pix_in->getTone();
Toshihiro Shimizu 890ddd
						int paint = pix_in->getPaint();
Toshihiro Shimizu 890ddd
						int ink = pix_in->getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value_packed = _mm_load_ps((float *)&(paints[paint]));
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value_packed = _mm_load_ps((float *)&(inks[ink]));
Toshihiro Shimizu 890ddd
						else {
Toshihiro Shimizu 890ddd
							float tt = (float)tone;
Toshihiro Shimizu 890ddd
							blendBySSE2(
Toshihiro Shimizu 890ddd
								pix_value_packed, // il valore calcolato
Toshihiro Shimizu 890ddd
								(float *)&(inks[ink]), (float *)&(paints[paint]),
Toshihiro Shimizu 890ddd
								&tt, den_packed, zeros);
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						weight_packed = _mm_load1_ps(&weight);
Toshihiro Shimizu 890ddd
						sum_contribs_packed = _mm_add_ps(sum_contribs_packed, _mm_mul_ps(pix_value_packed, weight_packed));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0f / sum_weights;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Toshihiro Shimizu 890ddd
					__m128 out_fval_packed = _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Toshihiro Shimizu 890ddd
					out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					__m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packs_epi32(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					out_value_packed_i = _mm_packus_epi16(out_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
					*(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Toshihiro Shimizu 890ddd
					int tone = pix_in->getTone();
Toshihiro Shimizu 890ddd
					int paint = pix_in->getPaint();
Toshihiro Shimizu 890ddd
					int ink = pix_in->getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						*pix_out = paints2[paint];
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						*pix_out = inks2[ink];
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						*pix_out = blend(inks2[ink], paints2[paint], tone, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				*pix_out = default_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (calc)
Toshihiro Shimizu 890ddd
		delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void resample_main_cm32_rgbm_bigradius(TRasterPT<t> rout, const TRasterCM32P &rin,</t>
Toshihiro Shimizu 890ddd
									   const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
									   const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
									   int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
									   int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
									   int n_pix,
Toshihiro Shimizu 890ddd
									   int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
									   int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
									   short *filter,
Toshihiro Shimizu 890ddd
									   TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// bigradius: cambia solo che i sum_contribs sono double invece che int
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const TPixelCM32 *buffer_in;
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int inside_offset_u, inside_offset_v;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	double outside_min_u_, outside_min_v_;
Toshihiro Shimizu 890ddd
	double outside_max_u_, outside_max_v_;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	T pix_value;
Toshihiro Shimizu 890ddd
	T default_value;
Toshihiro Shimizu 890ddd
	float weight;
Toshihiro Shimizu 890ddd
	float sum_weights;
Toshihiro Shimizu 890ddd
	double inv_sum_weights;
Toshihiro Shimizu 890ddd
	double sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Toshihiro Shimizu 890ddd
	double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Toshihiro Shimizu 890ddd
	int out_value_r, out_value_g, out_value_b, out_value_m;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	T *pix_out;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	default_value.r = 0;
Toshihiro Shimizu 890ddd
	default_value.g = 0;
Toshihiro Shimizu 890ddd
	default_value.b = 0;
Toshihiro Shimizu 890ddd
	default_value.m = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		rout->clear();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inside_offset_u = -min_pix_ref_u;
Toshihiro Shimizu 890ddd
	inside_offset_v = -min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - max_pix_ref_u - inside_offset_u;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - max_pix_ref_v - inside_offset_v;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_min_v_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_max_u_ = lu - 0.5;
Toshihiro Shimizu 890ddd
	outside_max_v_ = lv - 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int colorCount = palette->getStyleCount();
Shinya Kitaoka 12c444
	colorCount = std::max({colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> paints(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> inks(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	for (i = 0; i < palette->getStyleCount(); i++)
Toshihiro Shimizu 890ddd
		paints[i] = inks[i] = ::premultiply(palette->getStyle(i)->getAverageColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			pix_out = buffer_out + out_y * wrap_out + out_x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
								blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					pix_out->r = out_value_r;
Toshihiro Shimizu 890ddd
					pix_out->g = out_value_g;
Toshihiro Shimizu 890ddd
					pix_out->b = out_value_b;
Toshihiro Shimizu 890ddd
					pix_out->m = out_value_m;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					// *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));</t>
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Toshihiro Shimizu 890ddd
					   outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u);
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						// pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
								blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					pix_out->r = out_value_r;
Toshihiro Shimizu 890ddd
					pix_out->g = out_value_g;
Toshihiro Shimizu 890ddd
					pix_out->b = out_value_b;
Toshihiro Shimizu 890ddd
					pix_out->m = out_value_m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						*pix_out = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
							blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				*pix_out = default_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (calc)
Toshihiro Shimizu 890ddd
		delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void resample_main_cm32_rgbm(TRasterPT<t> rout, const TRasterCM32P &rin,</t>
Toshihiro Shimizu 890ddd
							 const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
							 const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
							 int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
							 int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
							 int n_pix,
Toshihiro Shimizu 890ddd
							 int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
							 int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
							 short *filter,
Toshihiro Shimizu 890ddd
							 TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const TPixelCM32 *buffer_in;
Toshihiro Shimizu 890ddd
	T *buffer_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int inside_offset_u, inside_offset_v;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	double outside_min_u_, outside_min_v_;
Toshihiro Shimizu 890ddd
	double outside_max_u_, outside_max_v_;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	T pix_value;
Toshihiro Shimizu 890ddd
	T default_value(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
	int sum_weights;
Toshihiro Shimizu 890ddd
	double inv_sum_weights;
Toshihiro Shimizu 890ddd
	int sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Toshihiro Shimizu 890ddd
	double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Toshihiro Shimizu 890ddd
	int out_value_r, out_value_g, out_value_b, out_value_m;
Toshihiro Shimizu 890ddd
	T out_value;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (n_pix >= 512 || T::maxChannelValue > 255) {
Toshihiro Shimizu 890ddd
		resample_main_cm32_rgbm_bigradius<t>(rout, rin,</t>
Toshihiro Shimizu 890ddd
											 aff_xy2uv,
Toshihiro Shimizu 890ddd
											 aff0_uv2fg,
Toshihiro Shimizu 890ddd
											 min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
											 max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
											 n_pix,
Toshihiro Shimizu 890ddd
											 pix_ref_u, pix_ref_v,
Toshihiro Shimizu 890ddd
											 pix_ref_f, pix_ref_g,
Toshihiro Shimizu 890ddd
											 filter, palette);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		resample_clear_rgbm<t>(rout, default_value);</t>
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inside_offset_u = -min_pix_ref_u;
Toshihiro Shimizu 890ddd
	inside_offset_v = -min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - max_pix_ref_u - inside_offset_u;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - max_pix_ref_v - inside_offset_v;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_min_v_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_max_u_ = lu - 0.5;
Toshihiro Shimizu 890ddd
	outside_max_v_ = lv - 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int colorCount = palette->getStyleCount();
Shinya Kitaoka 12c444
	colorCount = std::max({colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> paints(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> inks(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	for (i = 0; i < palette->getStyleCount(); i++)
Toshihiro Shimizu 890ddd
		paints[i] = inks[i] = ::premultiply(palette->getStyle(i)->getAverageColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						// pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
								blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					out_value.r = out_value_r;
Toshihiro Shimizu 890ddd
					out_value.g = out_value_g;
Toshihiro Shimizu 890ddd
					out_value.b = out_value_b;
Toshihiro Shimizu 890ddd
					out_value.m = out_value_m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					// out_value = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
							blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Toshihiro Shimizu 890ddd
					   outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u);
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						// pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
						else if (tone == 0)
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
								blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(T::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					out_value.r = out_value_r;
Toshihiro Shimizu 890ddd
					out_value.g = out_value_g;
Toshihiro Shimizu 890ddd
					out_value.b = out_value_b;
Toshihiro Shimizu 890ddd
					out_value.m = out_value_m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					// out_value = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int tone = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int paint = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int ink = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (tone == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(paints[paint]);</t>
Toshihiro Shimizu 890ddd
					else if (tone == 0)
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(inks[ink]);</t>
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						out_value = Converter<t>::convert(</t>
Toshihiro Shimizu 890ddd
							blend(inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				out_value = default_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			buffer_out[out_x + out_y * wrap_out] = out_value;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (calc)
Toshihiro Shimizu 890ddd
		delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void resample_cm32_rgbm(TRaster32P rout, const TRasterCM32P &rin,
Toshihiro Shimizu 890ddd
						const TAffine &aff_xy2uv,
Toshihiro Shimizu 890ddd
						const TAffine &aff0_uv2fg,
Toshihiro Shimizu 890ddd
						int min_pix_ref_u, int min_pix_ref_v,
Toshihiro Shimizu 890ddd
						int max_pix_ref_u, int max_pix_ref_v,
Toshihiro Shimizu 890ddd
						int n_pix,
Toshihiro Shimizu 890ddd
						int *pix_ref_u, int *pix_ref_v,
Toshihiro Shimizu 890ddd
						int *pix_ref_f, int *pix_ref_g,
Toshihiro Shimizu 890ddd
						short *filter, TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const TPixelCM32 *buffer_in;
Toshihiro Shimizu 890ddd
	/*T*/ TPixel32 *buffer_out;
Toshihiro Shimizu 890ddd
	int lu, lv, wrap_in, mu, mv;
Toshihiro Shimizu 890ddd
	int lx, ly, wrap_out;
Toshihiro Shimizu 890ddd
	int out_x, out_y;
Toshihiro Shimizu 890ddd
	double out_x_, out_y_;
Toshihiro Shimizu 890ddd
	double out_u_, out_v_;
Toshihiro Shimizu 890ddd
	int ref_u, ref_v;
Toshihiro Shimizu 890ddd
	int pix_u, pix_v;
Toshihiro Shimizu 890ddd
	double ref_out_u_, ref_out_v_;
Toshihiro Shimizu 890ddd
	double ref_out_f_, ref_out_g_;
Toshihiro Shimizu 890ddd
	int ref_out_f, ref_out_g;
Toshihiro Shimizu 890ddd
	int pix_out_f, pix_out_g;
Toshihiro Shimizu 890ddd
	int inside_offset_u, inside_offset_v;
Toshihiro Shimizu 890ddd
	UINT inside_limit_u, inside_limit_v;
Toshihiro Shimizu 890ddd
	int inside_nonempty;
Toshihiro Shimizu 890ddd
	double outside_min_u_, outside_min_v_;
Toshihiro Shimizu 890ddd
	double outside_max_u_, outside_max_v_;
Toshihiro Shimizu 890ddd
	UCHAR *calc;
Toshihiro Shimizu 890ddd
	int calc_allocsize;
Toshihiro Shimizu 890ddd
	int calc_bytewrap;
Toshihiro Shimizu 890ddd
	UCHAR calc_value;
Toshihiro Shimizu 890ddd
	bool must_calc;
Toshihiro Shimizu 890ddd
	/*T*/ TPixel32 pix_value;
Toshihiro Shimizu 890ddd
	/*T*/ TPixel32 default_value(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
	int sum_weights;
Toshihiro Shimizu 890ddd
	double inv_sum_weights;
Toshihiro Shimizu 890ddd
	int sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Toshihiro Shimizu 890ddd
	double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Toshihiro Shimizu 890ddd
	int out_value_r, out_value_g, out_value_b, out_value_m;
Toshihiro Shimizu 890ddd
	/*T*/ TPixel32 out_value;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (n_pix >= 512 || /*T*/ TPixel32::maxChannelValue > 255) {
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
		/*
Toshihiro Shimizu 890ddd
    resample_main_rgbm_bigradius<t>( rout, rin,</t>
Toshihiro Shimizu 890ddd
				                          aff_xy2uv,
Toshihiro Shimizu 890ddd
		                           		aff0_uv2fg,
Toshihiro Shimizu 890ddd
				                          min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
				                          max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				                          n_pix,
Toshihiro Shimizu 890ddd
				                          pix_ref_u, pix_ref_v,
Toshihiro Shimizu 890ddd
				                          pix_ref_f, pix_ref_g,
Toshihiro Shimizu 890ddd
			                           	filter );
Toshihiro Shimizu 890ddd
    */
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rout->getLx() > 0 && rout->getLy() > 0))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Toshihiro Shimizu 890ddd
		resample_clear_rgbm(rout, default_value);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int colorCount = palette->getStyleCount();
Shinya Kitaoka 12c444
	colorCount = std::max({colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> paints(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	std::vector<tpixel32> inks(colorCount);</tpixel32>
Toshihiro Shimizu 890ddd
	for (i = 0; i < palette->getStyleCount(); i++)
Toshihiro Shimizu 890ddd
		paints[i] = inks[i] = ::premultiply(palette->getStyle(i)->getAverageColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	calc = 0;
Toshihiro Shimizu 890ddd
	calc_allocsize = 0;
Toshihiro Shimizu 890ddd
	create_calc(rin, min_pix_ref_u, max_pix_ref_u,
Toshihiro Shimizu 890ddd
				min_pix_ref_v, max_pix_ref_v,
Toshihiro Shimizu 890ddd
				calc, calc_allocsize, calc_bytewrap);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	buffer_in = rin->pixels();
Toshihiro Shimizu 890ddd
	buffer_out = rout->pixels();
Toshihiro Shimizu 890ddd
	lu = rin->getLx();
Toshihiro Shimizu 890ddd
	lx = rout->getLx();
Toshihiro Shimizu 890ddd
	lv = rin->getLy();
Toshihiro Shimizu 890ddd
	ly = rout->getLy();
Toshihiro Shimizu 890ddd
	wrap_in = rin->getWrap();
Toshihiro Shimizu 890ddd
	wrap_out = rout->getWrap();
Toshihiro Shimizu 890ddd
	mu = lu - 1;
Toshihiro Shimizu 890ddd
	mv = lv - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	inside_offset_u = -min_pix_ref_u;
Toshihiro Shimizu 890ddd
	inside_offset_v = -min_pix_ref_v;
Toshihiro Shimizu 890ddd
	inside_limit_u = lu - max_pix_ref_u - inside_offset_u;
Toshihiro Shimizu 890ddd
	inside_limit_v = lv - max_pix_ref_v - inside_offset_v;
Toshihiro Shimizu 890ddd
	inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Toshihiro Shimizu 890ddd
	outside_min_u_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_min_v_ = -0.5;
Toshihiro Shimizu 890ddd
	outside_max_u_ = lu - 0.5;
Toshihiro Shimizu 890ddd
	outside_max_v_ = lv - 0.5;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Toshihiro Shimizu 890ddd
		for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Toshihiro Shimizu 890ddd
			out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Toshihiro Shimizu 890ddd
			ref_u = intLE(out_u_);
Toshihiro Shimizu 890ddd
			ref_v = intLE(out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (inside_nonempty &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Toshihiro Shimizu 890ddd
				(UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Toshihiro Shimizu 890ddd
				calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
				if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						//pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int t = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int p = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int i = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (t == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = paints[p];
Toshihiro Shimizu 890ddd
						else if (t == 0)
Toshihiro Shimizu 890ddd
							pix_value = inks[i];
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					out_value.r = out_value_r;
Toshihiro Shimizu 890ddd
					out_value.g = out_value_g;
Toshihiro Shimizu 890ddd
					out_value.b = out_value_b;
Toshihiro Shimizu 890ddd
					out_value.m = out_value_m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int t = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int p = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int i = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (t == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						out_value = paints[p];
Toshihiro Shimizu 890ddd
					else if (t == 0)
Toshihiro Shimizu 890ddd
						out_value = inks[i];
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						out_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					// out_value = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Toshihiro Shimizu 890ddd
					   outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Toshihiro Shimizu 890ddd
				if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Toshihiro Shimizu 890ddd
					must_calc = true;
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Toshihiro Shimizu 890ddd
					must_calc = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				if (must_calc) {
Toshihiro Shimizu 890ddd
					ref_out_u_ = ref_u - out_u_;
Toshihiro Shimizu 890ddd
					ref_out_v_ = ref_v - out_v_;
Toshihiro Shimizu 890ddd
					ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Toshihiro Shimizu 890ddd
					ref_out_f = tround(ref_out_f_);
Toshihiro Shimizu 890ddd
					ref_out_g = tround(ref_out_g_);
Toshihiro Shimizu 890ddd
					sum_weights = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_r = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_g = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_b = 0;
Toshihiro Shimizu 890ddd
					sum_contribs_m = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					for (i = n_pix - 1; i >= 0; i--) {
Toshihiro Shimizu 890ddd
						pix_out_f = pix_ref_f[i] + ref_out_f;
Toshihiro Shimizu 890ddd
						pix_out_g = pix_ref_g[i] + ref_out_g;
Toshihiro Shimizu 890ddd
						weight = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Toshihiro Shimizu 890ddd
						pix_u = pix_ref_u[i] + ref_u;
Toshihiro Shimizu 890ddd
						pix_v = pix_ref_v[i] + ref_v;
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_u);
Toshihiro Shimizu 890ddd
						notLessThan(0, pix_v);
Toshihiro Shimizu 890ddd
						notMoreThan(mu, pix_u);
Toshihiro Shimizu 890ddd
						notMoreThan(mv, pix_v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						//pix_value = buffer_in[pix_u + pix_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						int pix_in_pos = pix_u + pix_v * wrap_in;
Toshihiro Shimizu 890ddd
						int t = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
						int p = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
						int i = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						if (t == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
							pix_value = paints[p];
Toshihiro Shimizu 890ddd
						else if (t == 0)
Toshihiro Shimizu 890ddd
							pix_value = inks[i];
Toshihiro Shimizu 890ddd
						else
Toshihiro Shimizu 890ddd
							pix_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
						sum_contribs_r += (int)pix_value.r * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_g += (int)pix_value.g * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_b += (int)pix_value.b * weight;
Toshihiro Shimizu 890ddd
						sum_contribs_m += (int)pix_value.m * weight;
Toshihiro Shimizu 890ddd
						sum_weights += weight;
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					inv_sum_weights = 1.0 / sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_r = sum_contribs_r * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_g = sum_contribs_g * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_b = sum_contribs_b * inv_sum_weights;
Toshihiro Shimizu 890ddd
					out_fval_m = sum_contribs_m * inv_sum_weights;
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_r);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_g);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_b);
Toshihiro Shimizu 890ddd
					notLessThan(0.0, out_fval_m);
Toshihiro Shimizu 890ddd
					out_value_r = troundp(out_fval_r);
Toshihiro Shimizu 890ddd
					out_value_g = troundp(out_fval_g);
Toshihiro Shimizu 890ddd
					out_value_b = troundp(out_fval_b);
Toshihiro Shimizu 890ddd
					out_value_m = troundp(out_fval_m);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_r);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_g);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_b);
Toshihiro Shimizu 890ddd
					notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_m);
Toshihiro Shimizu 890ddd
					out_value.r = out_value_r;
Toshihiro Shimizu 890ddd
					out_value.g = out_value_g;
Toshihiro Shimizu 890ddd
					out_value.b = out_value_b;
Toshihiro Shimizu 890ddd
					out_value.m = out_value_m;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					// out_value = buffer_in[ref_u + ref_v * wrap_in];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					int pix_in_pos = ref_u + ref_v * wrap_in;
Toshihiro Shimizu 890ddd
					int t = buffer_in[pix_in_pos].getTone();
Toshihiro Shimizu 890ddd
					int p = buffer_in[pix_in_pos].getPaint();
Toshihiro Shimizu 890ddd
					int i = buffer_in[pix_in_pos].getInk();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
					if (t == TPixelCM32::getMaxTone())
Toshihiro Shimizu 890ddd
						out_value = paints[p];
Toshihiro Shimizu 890ddd
					else if (t == 0)
Toshihiro Shimizu 890ddd
						out_value = inks[i];
Toshihiro Shimizu 890ddd
					else
Toshihiro Shimizu 890ddd
						out_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				out_value = default_value;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			buffer_out[out_x + out_y * wrap_out] = out_value;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (calc)
Toshihiro Shimizu 890ddd
		delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
void rop_resample_rgbm_2(TRasterPT<t> rout, const TRasterCM32P &rin,</t>
Toshihiro Shimizu 890ddd
						 const TAffine &aff, TRop::ResampleFilterType flt_type, double blur, TPalette *palette)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#define FILTER_RESOLUTION 1024
Toshihiro Shimizu 890ddd
#define MAX_FILTER_VAL 32767
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	static TRop::ResampleFilterType current_flt_type = TRop::None;
Shinya Kitaoka 42bfb6
	static std::unique_ptr<short[]> filter_array;</short[]>
Toshihiro Shimizu 890ddd
	static short *filter = 0;
Toshihiro Shimizu 890ddd
	static int min_filter_fg, max_filter_fg;
Toshihiro Shimizu 890ddd
	static int filter_array_size = 0;
Toshihiro Shimizu 890ddd
	static int n_pix = 0;
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 42bfb6
	static std::unique_ptr<int[]> pix_ref_g;</int[]>
Toshihiro Shimizu 890ddd
	static int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 42bfb6
	std::unique_ptr<short[]> filter_array;</short[]>
Toshihiro Shimizu 890ddd
	short *filter = 0;
Toshihiro Shimizu 890ddd
	int min_filter_fg, max_filter_fg;
Toshihiro Shimizu 890ddd
	int filter_array_size = 0;
Toshihiro Shimizu 890ddd
	int n_pix = 0;
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 42bfb6
	std::unique_ptr<int[]> pix_ref_g;</int[]>
Toshihiro Shimizu 890ddd
	int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int filter_st_radius;
Toshihiro Shimizu 890ddd
	int filter_fg_radius;
Toshihiro Shimizu 890ddd
	int filter_size;
Toshihiro Shimizu 890ddd
	int f;
Toshihiro Shimizu 890ddd
	double s_;
Toshihiro Shimizu 890ddd
	double weight_;
Toshihiro Shimizu 890ddd
	int weight;
Toshihiro Shimizu 890ddd
	TAffine aff_uv2xy;
Toshihiro Shimizu 890ddd
	TAffine aff_xy2uv;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2xy;
Toshihiro Shimizu 890ddd
	TAffine aff0_xy2st;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2st;
Toshihiro Shimizu 890ddd
	TAffine aff0_st2fg;
Toshihiro Shimizu 890ddd
	TAffine aff0_uv2fg;
Toshihiro Shimizu 890ddd
	TAffine aff0_fg2uv;
Toshihiro Shimizu 890ddd
	double scale_x, scale_y;
Toshihiro Shimizu 890ddd
	double inv_blur;
Toshihiro Shimizu 890ddd
	int max_n_pix;
Toshihiro Shimizu 890ddd
	double min_pix_out_u_, min_pix_out_v_;
Toshihiro Shimizu 890ddd
	double max_pix_out_u_, max_pix_out_v_;
Toshihiro Shimizu 890ddd
	int min_pix_ref_u, min_pix_ref_v;
Toshihiro Shimizu 890ddd
	int max_pix_ref_u, max_pix_ref_v;
Toshihiro Shimizu 890ddd
	int cur_pix_ref_u, cur_pix_ref_v;
Toshihiro Shimizu 890ddd
	double cur_pix_ref_f_, cur_pix_ref_g_;
Toshihiro Shimizu 890ddd
	int cur_pix_ref_f, cur_pix_ref_g;
Toshihiro Shimizu 890ddd
	double min_ref_out_f_, min_ref_out_g_;
Toshihiro Shimizu 890ddd
	double max_ref_out_f_, max_ref_out_g_;
Toshihiro Shimizu 890ddd
	int min_ref_out_f, min_ref_out_g;
Toshihiro Shimizu 890ddd
	int max_ref_out_f, max_ref_out_g;
Toshihiro Shimizu 890ddd
	int min_pix_ref_f, min_pix_ref_g;
Toshihiro Shimizu 890ddd
	int max_pix_ref_f, max_pix_ref_g;
Toshihiro Shimizu 890ddd
	int min_pix_out_f, min_pix_out_g;
Toshihiro Shimizu 890ddd
	int max_pix_out_f, max_pix_out_g;
Toshihiro Shimizu 890ddd
	int min_pix_out_fg;
Toshihiro Shimizu 890ddd
	int max_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
	double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(flt_type != TRop::None);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	filter_st_radius = get_filter_radius(flt_type);
Toshihiro Shimizu 890ddd
	filter_fg_radius = filter_st_radius * FILTER_RESOLUTION;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aff_uv2xy = aff;
Toshihiro Shimizu 890ddd
	aff0_uv2xy = aff_uv2xy.place(0.0, 0.0, 0.0, 0.0);
Toshihiro Shimizu 890ddd
	aff_xy2uv = aff_uv2xy.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	scale_x = sqrt(sq(aff_uv2xy.a11) + sq(aff_uv2xy.a12));
Toshihiro Shimizu 890ddd
	scale_y = sqrt(sq(aff_uv2xy.a21) + sq(aff_uv2xy.a22));
Toshihiro Shimizu 890ddd
	aff0_xy2st = TScale((scale_x > 1.0) ? 1.0 / scale_x : 1.0,
Toshihiro Shimizu 890ddd
						(scale_y > 1.0) ? 1.0 / scale_y : 1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (blur > 1.0) //per ora il blur e' 1.0
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		inv_blur = 1.0 / blur;
Toshihiro Shimizu 890ddd
		aff0_xy2st = TScale(inv_blur, inv_blur) * aff0_xy2st;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	aff0_uv2st = aff0_xy2st * aff0_uv2xy;
Toshihiro Shimizu 890ddd
	aff0_st2fg = TScale(FILTER_RESOLUTION, FILTER_RESOLUTION);
Toshihiro Shimizu 890ddd
	aff0_uv2fg = aff0_st2fg * aff0_uv2st;
Toshihiro Shimizu 890ddd
	aff0_fg2uv = aff0_uv2fg.inv();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	minmax(-filter_fg_radius, -filter_fg_radius,
Toshihiro Shimizu 890ddd
		   filter_fg_radius, filter_fg_radius,
Toshihiro Shimizu 890ddd
		   aff0_fg2uv,
Toshihiro Shimizu 890ddd
		   min_pix_out_u_, min_pix_out_v_,
Toshihiro Shimizu 890ddd
		   max_pix_out_u_, max_pix_out_v_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_pix_ref_u = intGT(min_pix_out_u_);
Toshihiro Shimizu 890ddd
	min_pix_ref_v = intGT(min_pix_out_v_);
Toshihiro Shimizu 890ddd
	max_pix_ref_u = intLT(max_pix_out_u_) + 1;
Toshihiro Shimizu 890ddd
	max_pix_ref_v = intLT(max_pix_out_v_) + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (blur <= 1.0) {
Toshihiro Shimizu 890ddd
		if (aff_uv2xy.a12 == 0.0 && aff_uv2xy.a21 == 0.0) {
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a11 == 1.0 && isInt(aff_uv2xy.a13)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a22 == 1.0 && isInt(aff_uv2xy.a23)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (aff_uv2xy.a11 == 0.0 && aff_uv2xy.a22 == 0.0) {
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a12 == 1.0 && isInt(aff_uv2xy.a13)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_v = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (aff_uv2xy.a21 == 1.0 && isInt(aff_uv2xy.a23)) {
Toshihiro Shimizu 890ddd
				min_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
				max_pix_ref_u = 0;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	max_n_pix = (max_pix_ref_u - min_pix_ref_u + 1) *
Toshihiro Shimizu 890ddd
				(max_pix_ref_v - min_pix_ref_v + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (max_n_pix > current_max_n_pix) {
Toshihiro Shimizu 890ddd
		current_max_n_pix = max_n_pix;
Shinya Kitaoka 42bfb6
		pix_ref_u.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_v.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_f.reset(new int[current_max_n_pix]);
Shinya Kitaoka 42bfb6
		pix_ref_g.reset(new int[current_max_n_pix]);
Toshihiro Shimizu 890ddd
		assert(pix_ref_u && pix_ref_v && pix_ref_f && pix_ref_g);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	minmax(-1, -1, 0, 0,
Toshihiro Shimizu 890ddd
		   aff0_uv2fg,
Toshihiro Shimizu 890ddd
		   min_ref_out_f_, min_ref_out_g_,
Toshihiro Shimizu 890ddd
		   max_ref_out_f_, max_ref_out_g_);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_ref_out_f = tround(min_ref_out_f_);
Toshihiro Shimizu 890ddd
	min_ref_out_g = tround(min_ref_out_g_);
Toshihiro Shimizu 890ddd
	max_ref_out_f = tround(max_ref_out_f_);
Toshihiro Shimizu 890ddd
	max_ref_out_g = tround(max_ref_out_g_);
Toshihiro Shimizu 890ddd
	min_pix_ref_f = -filter_fg_radius - max_ref_out_f;
Toshihiro Shimizu 890ddd
	min_pix_ref_g = -filter_fg_radius - max_ref_out_g;
Toshihiro Shimizu 890ddd
	max_pix_ref_f = filter_fg_radius - min_ref_out_f;
Toshihiro Shimizu 890ddd
	max_pix_ref_g = filter_fg_radius - min_ref_out_g;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	min_pix_out_f = c_maxint;
Toshihiro Shimizu 890ddd
	min_pix_out_g = c_maxint;
Toshihiro Shimizu 890ddd
	max_pix_out_f = c_minint;
Toshihiro Shimizu 890ddd
	max_pix_out_g = c_minint;
Toshihiro Shimizu 890ddd
	n_pix = 0;
Toshihiro Shimizu 890ddd
	for (cur_pix_ref_v = min_pix_ref_v;
Toshihiro Shimizu 890ddd
		 cur_pix_ref_v <= max_pix_ref_v;
Toshihiro Shimizu 890ddd
		 cur_pix_ref_v++)
Toshihiro Shimizu 890ddd
		for (cur_pix_ref_u = min_pix_ref_u;
Toshihiro Shimizu 890ddd
			 cur_pix_ref_u <= max_pix_ref_u;
Toshihiro Shimizu 890ddd
			 cur_pix_ref_u++) {
Toshihiro Shimizu 890ddd
			cur_pix_ref_f_ = affMV1(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Toshihiro Shimizu 890ddd
			cur_pix_ref_g_ = affMV2(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Toshihiro Shimizu 890ddd
			cur_pix_ref_f = tround(cur_pix_ref_f_);
Toshihiro Shimizu 890ddd
			cur_pix_ref_g = tround(cur_pix_ref_g_);
Toshihiro Shimizu 890ddd
			if (min_pix_ref_f <= cur_pix_ref_f && cur_pix_ref_f <= max_pix_ref_f &&
Toshihiro Shimizu 890ddd
				min_pix_ref_g <= cur_pix_ref_g && cur_pix_ref_g <= max_pix_ref_g) {
Toshihiro Shimizu 890ddd
				pix_ref_u[n_pix] = cur_pix_ref_u;
Toshihiro Shimizu 890ddd
				pix_ref_v[n_pix] = cur_pix_ref_v;
Toshihiro Shimizu 890ddd
				pix_ref_f[n_pix] = cur_pix_ref_f;
Toshihiro Shimizu 890ddd
				pix_ref_g[n_pix] = cur_pix_ref_g;
Toshihiro Shimizu 890ddd
				notMoreThan(cur_pix_ref_f + min_ref_out_f, min_pix_out_f);
Toshihiro Shimizu 890ddd
				notMoreThan(cur_pix_ref_g + min_ref_out_g, min_pix_out_g);
Toshihiro Shimizu 890ddd
				notLessThan(cur_pix_ref_f + max_ref_out_f, max_pix_out_f);
Toshihiro Shimizu 890ddd
				notLessThan(cur_pix_ref_g + max_ref_out_g, max_pix_out_g);
Toshihiro Shimizu 890ddd
				n_pix++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	assert(n_pix > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	if (flt_type != current_flt_type) {
Toshihiro Shimizu 890ddd
		current_flt_type = flt_type;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		min_filter_fg = -filter_fg_radius - FILTER_RESOLUTION * 3 / 2;
Toshihiro Shimizu 890ddd
		max_filter_fg = filter_fg_radius + FILTER_RESOLUTION * 3 / 2;
Toshihiro Shimizu 890ddd
		filter_size = max_filter_fg - min_filter_fg + 1;
Toshihiro Shimizu 890ddd
		if (filter_size > filter_array_size) {
Shinya Kitaoka 42bfb6
			filter_array.reset(new short[filter_size]);
Toshihiro Shimizu 890ddd
			assert(filter_array);
Toshihiro Shimizu 890ddd
			filter_array_size = filter_size;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka 42bfb6
		filter = filter_array.get() - min_filter_fg;
Toshihiro Shimizu 890ddd
		filter[0] = MAX_FILTER_VAL;
Toshihiro Shimizu 890ddd
		for (f = 1, s_ = 1.0 / FILTER_RESOLUTION;
Toshihiro Shimizu 890ddd
			 f < filter_fg_radius;
Toshihiro Shimizu 890ddd
			 f++, s_ += 1.0 / FILTER_RESOLUTION) {
Toshihiro Shimizu 890ddd
			weight_ = get_filter_value(flt_type, s_) * (double)MAX_FILTER_VAL;
Toshihiro Shimizu 890ddd
			weight = tround(weight_);
Toshihiro Shimizu 890ddd
			filter[f] = weight;
Toshihiro Shimizu 890ddd
			filter[-f] = weight;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (f = filter_fg_radius; f <= max_filter_fg; f++)
Toshihiro Shimizu 890ddd
			filter[f] = 0;
Toshihiro Shimizu 890ddd
		for (f = -filter_fg_radius; f >= min_filter_fg; f--)
Toshihiro Shimizu 890ddd
			filter[f] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 12c444
	min_pix_out_fg = std::min(min_pix_out_f, min_pix_out_g);
Shinya Kitaoka 12c444
	max_pix_out_fg = std::max(max_pix_out_f, max_pix_out_g);
Toshihiro Shimizu 890ddd
	if (min_pix_out_fg < min_filter_fg || max_pix_out_fg > max_filter_fg) {
Toshihiro Shimizu 890ddd
		filter_size = max_pix_out_fg - min_pix_out_fg + 1;
Toshihiro Shimizu 890ddd
		if (filter_size > filter_array_size) {
Toshihiro Shimizu 890ddd
			//controllare!!
Toshihiro Shimizu 890ddd
			//TREALLOC (filter_array, filter_size)
Shinya Kitaoka 42bfb6
			filter_array.reset(new short[filter_size]);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			assert(filter_array);
Toshihiro Shimizu 890ddd
			filter_array_size = filter_size;
Toshihiro Shimizu 890ddd
		}
Shinya Kitaoka 42bfb6
		filter = filter_array.get() - min_filter_fg;
Toshihiro Shimizu 890ddd
		if (min_pix_out_fg < min_filter_fg) {
Toshihiro Shimizu 890ddd
			int delta = min_filter_fg - min_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (f = max_filter_fg; f >= min_filter_fg; f--)
Toshihiro Shimizu 890ddd
				filter[f + delta] = filter[f];
Toshihiro Shimizu 890ddd
			filter += delta;
Toshihiro Shimizu 890ddd
			for (f = min_filter_fg - 1; f >= min_pix_out_fg; f--)
Toshihiro Shimizu 890ddd
				filter[f] = 0;
Toshihiro Shimizu 890ddd
			min_filter_fg = min_pix_out_fg;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (max_pix_out_fg > max_filter_fg) {
Toshihiro Shimizu 890ddd
			for (f = max_filter_fg + 1; f <= max_pix_out_fg; f++)
Toshihiro Shimizu 890ddd
				filter[f] = 0;
Toshihiro Shimizu 890ddd
			max_filter_fg = max_pix_out_fg;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
	TRaster32P rout32 = rout;
Toshihiro Shimizu 890ddd
	if ((TSystem::getCPUExtensions() & TSystem::CpuSupportsSse2) && rout32)
Toshihiro Shimizu 890ddd
		resample_main_cm32_rgbm_SSE2<tpixel32>(rout32, rin, aff_xy2uv, aff0_uv2fg,</tpixel32>
Toshihiro Shimizu 890ddd
											   min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
											   max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
											   n_pix,
Shinya Kitaoka 42bfb6
											   pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 42bfb6
											   pix_ref_f.get(), pix_ref_g.get(),
Toshihiro Shimizu 890ddd
											   filter, palette);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		resample_main_cm32_rgbm<t>(rout, rin, aff_xy2uv, aff0_uv2fg,</t>
Toshihiro Shimizu 890ddd
								   min_pix_ref_u, min_pix_ref_v,
Toshihiro Shimizu 890ddd
								   max_pix_ref_u, max_pix_ref_v,
Toshihiro Shimizu 890ddd
								   n_pix,
Shinya Kitaoka 42bfb6
								   pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 42bfb6
								   pix_ref_f.get(), pix_ref_g.get(),
Toshihiro Shimizu 890ddd
								   filter, palette);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
void TRop::resample(const TRasterP &out,
Toshihiro Shimizu 890ddd
					const TRasterCM32P &in,
Toshihiro Shimizu 890ddd
					const TPaletteP palette,
Toshihiro Shimizu 890ddd
					const TAffine &aff,
Toshihiro Shimizu 890ddd
					TRop::ResampleFilterType filterType,
Toshihiro Shimizu 890ddd
					double blur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TRasterP rin = in;
Toshihiro Shimizu 890ddd
	TRaster32P rout32 = out;
Toshihiro Shimizu 890ddd
	in->lock();
Toshihiro Shimizu 890ddd
	out->lock();
Toshihiro Shimizu 890ddd
	if (rout32)
Toshihiro Shimizu 890ddd
		rop_resample_rgbm_2<tpixel32>(rout32, rin, aff, filterType, blur, palette.getPointer());</tpixel32>
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		TRaster64P rout64 = out;
Toshihiro Shimizu 890ddd
		if (rout64)
Toshihiro Shimizu 890ddd
			rop_resample_rgbm_2<tpixel64>(rout64, rin, aff, filterType, blur, palette.getPointer());</tpixel64>
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			in->unlock();
Toshihiro Shimizu 890ddd
			out->unlock();
Toshihiro Shimizu 890ddd
			throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	in->unlock();
Toshihiro Shimizu 890ddd
	out->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif //TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRop::resample(const TRasterP &rout, const TRasterP &rin,
Toshihiro Shimizu 890ddd
					const TAffine &aff, ResampleFilterType filterType, double blur)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	rin->lock();
Toshihiro Shimizu 890ddd
	rout->lock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (filterType == ClosestPixel ||
Toshihiro Shimizu 890ddd
		filterType == Bilinear) {
Toshihiro Shimizu 890ddd
		if ((TRaster64P)rout || (TRaster64P)rin)
Toshihiro Shimizu 890ddd
			filterType = Triangle;
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			quickResample(rout, rin, aff, filterType);
Toshihiro Shimizu 890ddd
			rin->unlock();
Toshihiro Shimizu 890ddd
			rout->unlock();
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRaster32P rout32 = rout, rin32 = rin;
Toshihiro Shimizu 890ddd
	if (rout32) {
Toshihiro Shimizu 890ddd
		if (!rin32) {
Toshihiro Shimizu 890ddd
			rin32 = TRaster32P(rin->getLx(), rin->getLy());
Toshihiro Shimizu 890ddd
			TRop::convert(rin32, rin);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		do_resample<tpixel32>(rout32, rin32, aff, filterType, blur);</tpixel32>
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
		TRasterCM32P routCM32 = rout, rinCM32 = rin;
Toshihiro Shimizu 890ddd
		if (routCM32 && rinCM32)
Toshihiro Shimizu 890ddd
			do_resample(routCM32, rinCM32, aff);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			TRaster64P rout64 = rout, rin64 = rin;
Toshihiro Shimizu 890ddd
			if (rout64) {
Toshihiro Shimizu 890ddd
				if (!rin64) {
Toshihiro Shimizu 890ddd
					rin64 = TRaster64P(rin->getLx(), rin->getLy());
Toshihiro Shimizu 890ddd
					TRop::convert(rin64, rin);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				do_resample<tpixel64>(rout64, rin64, aff, filterType, blur);</tpixel64>
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				TRasterGR8P routGR8 = rout, rinGR8 = rin;
Toshihiro Shimizu 890ddd
				TRaster32P rin32 = rin;
Toshihiro Shimizu 890ddd
				if (routGR8 && rinGR8)
Toshihiro Shimizu 890ddd
					do_resample(routGR8, rinGR8, aff, filterType, blur);
Toshihiro Shimizu 890ddd
				else if (routGR8 && rin32)
Toshihiro Shimizu 890ddd
					do_resample(routGR8, rin32, aff, filterType, blur);
Toshihiro Shimizu 890ddd
				else {
Toshihiro Shimizu 890ddd
					rin->unlock();
Toshihiro Shimizu 890ddd
					rout->unlock();
Toshihiro Shimizu 890ddd
					throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	rin->unlock();
Toshihiro Shimizu 890ddd
	rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------