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
Shinya Kitaoka 120a6e
#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
Shinya Kitaoka 120a6e
-filter_fg_radius - max_ref_out_fg < pix_ref_fg < filter_fg_radius -
Shinya Kitaoka 120a6e
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
Shinya Kitaoka 120a6e
    // 2^36 * 1.5,  (52-_shiftamt=36) uses limited precision to floor
Shinya Kitaoka 120a6e
    const double _double2fixmagic = 68719476736.0 * 1.5;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// 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
Shinya Kitaoka 120a6e
inline TINT32 Double2Int(double val) {
Shinya Kitaoka 120a6e
  val = val + _double2fixmagic;
Shinya Kitaoka 120a6e
  return ((TINT32 *)&val)[iman_] >> _shiftamt;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#define DOUBLE_TO_INT32(D)                                                     \
Shinya Kitaoka 120a6e
  (d2iaux = D, d2iaux += _double2fixmagic,                                     \
Shinya Kitaoka 120a6e
   (((TINT32 *)&(d2iaux))[iman_] >> _shiftamt))
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//#define USE_DOUBLE_TO_INT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double sinc0(double x, int a) {
Shinya Kitaoka 120a6e
  return sin((M_PI / (a)) * (x)) / ((M_PI / (a)) * (x));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double sinc(double x, int a) {
Shinya Kitaoka 120a6e
  return (x) == 0.0 ? 1.0 : sin((M_PI / (a)) * (x)) / ((M_PI / (a)) * (x));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline UCHAR TO8BIT(float X) {
Shinya Kitaoka 120a6e
  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;
Shinya Kitaoka 120a6e
const UCHAR GREY_GR8   = 127;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double aff0MV1(const TAffine &aff, double v1, double v2) {
Shinya Kitaoka 120a6e
  return aff.a11 * v1 + aff.a12 * v2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double affMV1(const TAffine &aff, double v1, double v2) {
Shinya Kitaoka 120a6e
  return aff.a11 * v1 + aff.a12 * v2 + aff.a13;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double aff0MV2(const TAffine &aff, double v1, double v2) {
Shinya Kitaoka 120a6e
  return aff.a21 * v1 + aff.a22 * v2;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double affMV2(const TAffine &aff, double v1, double v2) {
Shinya Kitaoka 120a6e
  return aff.a21 * v1 + aff.a22 * v2 + aff.a23;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#else  // !USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
#define ROUND(x)                                                               \
Shinya Kitaoka 120a6e
  ((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
Shinya Kitaoka 120a6e
#define ROUND(x)                                                               \
Shinya Kitaoka 120a6e
  (DOUBLE_TO_INT32(((int)(-0.9F) == 0 && (x) < 0.0F) ? ((x)-0.5F)              \
Shinya Kitaoka 120a6e
                                                     : ((x) + 0.5F)))
Toshihiro Shimizu 890ddd
#define ROUNDP(x) (DOUBLE_TO_INT32((x) + 0.5F))
Shinya Kitaoka 120a6e
#define FLOOR(x)                                                               \
Shinya Kitaoka 120a6e
  (DOUBLE_TO_INT32(x) > (x) ? DOUBLE_TO_INT32(x) - 1 : DOUBLE_TO_INT32(x))
Shinya Kitaoka 120a6e
#define CEIL(x)                                                                \
Shinya Kitaoka 120a6e
  (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
Shinya Kitaoka 120a6e
#define NOT_LESS_THAN(MIN, X)                                                  \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    if ((X) < (MIN)) (X) = (MIN);                                              \
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
#define NOT_MORE_THAN(MAX, X)                                                  \
Shinya Kitaoka 120a6e
  {                                                                            \
Shinya Kitaoka 120a6e
    if ((X) > (MAX)) (X) = (MAX);                                              \
Shinya Kitaoka 120a6e
  }
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
Shinya Kitaoka 120a6e
#endif  // USE_INLINE_FUNS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct FILTER {
Shinya Kitaoka 120a6e
  int first, last;
Shinya Kitaoka 120a6e
  float *w;
Shinya Kitaoka 120a6e
  float *w_base;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct NOCALC {
Shinya Kitaoka 120a6e
  int first, last;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Shinya Kitaoka 120a6e
inline int get_filter_radius(TRop::ResampleFilterType flt_type) {
Shinya Kitaoka 120a6e
  switch (flt_type) {
Shinya Kitaoka 120a6e
  case TRop::Triangle:
Shinya Kitaoka 120a6e
    return 1;
Shinya Kitaoka 120a6e
  case TRop::Mitchell:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Cubic5:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Cubic75:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Cubic1:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Hann2:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Hann3:
Shinya Kitaoka 120a6e
    return 3;
Shinya Kitaoka 120a6e
  case TRop::Hamming2:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Hamming3:
Shinya Kitaoka 120a6e
    return 3;
Shinya Kitaoka 120a6e
  case TRop::Lanczos2:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  case TRop::Lanczos3:
Shinya Kitaoka 120a6e
    return 3;
Shinya Kitaoka 120a6e
  case TRop::Gauss:
Shinya Kitaoka 120a6e
    return 2;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(!"bad filter type");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
//! Equivalent to aff * TRectD(u0, v0, u1, v0).
Shinya Kitaoka 120a6e
inline void minmax(double u0, double v0, double u1, double v1,
Shinya Kitaoka 120a6e
                   const TAffine &aff, double &x0, double &y0, double &x1,
Shinya Kitaoka 120a6e
                   double &y1) {
Shinya Kitaoka 120a6e
  double xmin, ymin;
Shinya Kitaoka 120a6e
  double xmax, ymax;
Shinya Kitaoka 120a6e
  double x_a, y_a;
Shinya Kitaoka 120a6e
  double x_b, y_b;
Shinya Kitaoka 120a6e
  double x_c, y_c;
Shinya Kitaoka 120a6e
  double x_d, y_d;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  x_a  = affMV1(aff, u0, v0);
Shinya Kitaoka 120a6e
  y_a  = affMV2(aff, u0, v0);
Shinya Kitaoka 120a6e
  x_b  = affMV1(aff, u1, v0);
Shinya Kitaoka 120a6e
  y_b  = affMV2(aff, u1, v0);
Shinya Kitaoka 120a6e
  x_c  = affMV1(aff, u1, v1);
Shinya Kitaoka 120a6e
  y_c  = affMV2(aff, u1, v1);
Shinya Kitaoka 120a6e
  x_d  = affMV1(aff, u0, v1);
Shinya Kitaoka 120a6e
  y_d  = affMV2(aff, u0, v1);
Shinya Kitaoka 120a6e
  xmin = std::min(x_a, x_b);
Shinya Kitaoka 120a6e
  xmax = std::max(x_a, x_b);
Shinya Kitaoka 120a6e
  xmin = std::min(xmin, x_c);
Shinya Kitaoka 120a6e
  xmax = std::max(xmax, x_c);
Shinya Kitaoka 120a6e
  xmin = std::min(xmin, x_d);
Shinya Kitaoka 120a6e
  xmax = std::max(xmax, x_d);
Shinya Kitaoka 120a6e
  ymin = std::min(y_a, y_b);
Shinya Kitaoka 120a6e
  ymax = std::max(y_a, y_b);
Shinya Kitaoka 120a6e
  ymin = std::min(ymin, y_c);
Shinya Kitaoka 120a6e
  ymax = std::max(ymax, y_c);
Shinya Kitaoka 120a6e
  ymin = std::min(ymin, y_d);
Shinya Kitaoka 120a6e
  ymax = std::max(ymax, y_d);
Shinya Kitaoka 120a6e
  x0   = xmin;
Shinya Kitaoka 120a6e
  y0   = ymin;
Shinya Kitaoka 120a6e
  x1   = xmax;
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
inline void mitchellinit(double b, double c) {
Shinya Kitaoka 120a6e
  p0 = (6.0 - 2.0 * b) / 6.0;
Shinya Kitaoka 120a6e
  p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0;
Shinya Kitaoka 120a6e
  p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0;
Shinya Kitaoka 120a6e
  q0 = (8.0 * b + 24.0 * c) / 6.0;
Shinya Kitaoka 120a6e
  q1 = (-12.0 * b - 48.0 * c) / 6.0;
Shinya Kitaoka 120a6e
  q2 = (6.0 * b + 30.0 * c) / 6.0;
Shinya Kitaoka 120a6e
  q3 = (-b - 6.0 * c) / 6.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradMitchell = 2;
Shinya Kitaoka 120a6e
static inline double flt_mitchell(
Shinya Kitaoka 120a6e
    double x) /*Mitchell & Netravali's two-param cubic*/
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  static int mitfirsted;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!mitfirsted) {
Shinya Kitaoka 120a6e
    mitchellinit(1.0 / 3.0, 1.0 / 3.0);
Shinya Kitaoka 120a6e
    mitfirsted = 1;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (x < -2.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < -1.0) return (q0 - x * (q1 - x * (q2 - x * q3)));
Shinya Kitaoka 120a6e
  if (x < 0.0) return (p0 + x * x * (p2 - x * p3));
Shinya Kitaoka 120a6e
  if (x < 1.0) return (p0 + x * x * (p2 + x * p3));
Shinya Kitaoka 120a6e
  if (x < 2.0) return (q0 + x * (q1 + x * (q2 + x * q3)));
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradTriangle = 1;
Shinya Kitaoka 120a6e
static inline double flt_triangle(double x) {
Shinya Kitaoka 120a6e
  if (x < -1.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 0.0) return 1.0 + x;
Shinya Kitaoka 120a6e
  if (x < 1.0) return 1.0 - x;
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic5 = 2;
Shinya Kitaoka 120a6e
static inline double flt_cubic_5(double x) {
Shinya Kitaoka 120a6e
  if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
  if (x < 1.0) return 2.5 * x * x * x - 3.5 * x * x + 1;
Shinya Kitaoka 120a6e
  if (x < 2.0) return 0.5 * x * x * x - 2.5 * x * x + 4 * x - 2;
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic75 = 2;
Shinya Kitaoka 120a6e
static inline double flt_cubic_75(double x) {
Shinya Kitaoka 120a6e
  if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
  if (x < 1.0) return 2.75 * x * x * x - 3.75 * x * x + 1;
Shinya Kitaoka 120a6e
  if (x < 2.0) return 0.75 * x * x * x - 3.75 * x * x + 6 * x - 3;
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradCubic1 = 2;
Shinya Kitaoka 120a6e
static inline double flt_cubic_1(double x) {
Shinya Kitaoka 120a6e
  if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
  if (x < 1.0) return 3 * x * x * x - 4 * x * x + 1;
Shinya Kitaoka 120a6e
  if (x < 2.0) return x * x * x - 5 * x * x + 8 * x - 4;
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHann2 = 2;
Shinya Kitaoka 120a6e
static inline double flt_hann2(double x) {
Shinya Kitaoka 120a6e
  if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 2.0) return sinc(x, 1) * (0.5 + 0.5 * cos(M_PI_2 * x));
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHann3 = 3;
Shinya Kitaoka 120a6e
static inline double flt_hann3(double x) {
Shinya Kitaoka 120a6e
  if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 3.0) return sinc(x, 1) * (0.5 + 0.5 * cos(M_PI_3 * x));
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHamming2 = 2;
Shinya Kitaoka 120a6e
static inline double flt_hamming2(double x) {
Shinya Kitaoka 120a6e
  if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 2.0) return sinc(x, 1) * (0.54 + 0.46 * cos(M_PI_2 * x));
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradHamming3 = 3;
Shinya Kitaoka 120a6e
static inline double flt_hamming3(double x) {
Shinya Kitaoka 120a6e
  if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 3.0) return sinc(x, 1) * (0.54 + 0.46 * cos(M_PI_3 * x));
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradLanczos2 = 2;
Shinya Kitaoka 120a6e
static inline double flt_lanczos2(double x) {
Shinya Kitaoka 120a6e
  if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 2.0) return sinc(x, 1) * sinc(x, 2);
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradLanczos3 = 3;
Shinya Kitaoka 120a6e
static inline double flt_lanczos3(double x) {
Shinya Kitaoka 120a6e
  if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 3.0) return sinc(x, 1) * sinc(x, 3);
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int fltradGauss = 2;
Shinya Kitaoka 120a6e
static inline double flt_gauss(double x) {
Shinya Kitaoka 120a6e
  if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
  if (x < 2.0) return exp(-M_PI * x * x);
Shinya Kitaoka 120a6e
  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;
Shinya Kitaoka 120a6e
static inline double flt_w_1(double x) {
Shinya Kitaoka 120a6e
  if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
  if (x < 0.5) return 1 - 0.5 * x;
Shinya Kitaoka 120a6e
  if (x < 1.0) return 1.5 - 1.5 * x;
Shinya Kitaoka 120a6e
  if (x < 1.5) return 0.5 - 0.5 * x;
Shinya Kitaoka 120a6e
  if (x < 2.0) return 0.5 * x - 1.0;
Shinya Kitaoka 120a6e
  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,
Shinya Kitaoka 120a6e
                                   double (**flt_fun)(double),
Shinya Kitaoka 120a6e
                                   double &flt_rad) {
Shinya Kitaoka 120a6e
  double (*fun)(double);
Shinya Kitaoka 120a6e
  double rad;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  switch (flt_type) {
Shinya Kitaoka 120a6e
  case TRop::Triangle:
Shinya Kitaoka 120a6e
    fun = flt_triangle;
Shinya Kitaoka 120a6e
    rad = fltradTriangle;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Mitchell:
Shinya Kitaoka 120a6e
    fun = flt_mitchell;
Shinya Kitaoka 120a6e
    rad = fltradMitchell;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Cubic5:
Shinya Kitaoka 120a6e
    fun = flt_cubic_5;
Shinya Kitaoka 120a6e
    rad = fltradCubic5;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Cubic75:
Shinya Kitaoka 120a6e
    fun = flt_cubic_75;
Shinya Kitaoka 120a6e
    rad = fltradCubic75;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Cubic1:
Shinya Kitaoka 120a6e
    fun = flt_cubic_1;
Shinya Kitaoka 120a6e
    rad = fltradCubic1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Hann2:
Shinya Kitaoka 120a6e
    fun = flt_hann2;
Shinya Kitaoka 120a6e
    rad = fltradHann2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Hann3:
Shinya Kitaoka 120a6e
    fun = flt_hann3;
Shinya Kitaoka 120a6e
    rad = fltradHann3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Hamming2:
Shinya Kitaoka 120a6e
    fun = flt_hamming2;
Shinya Kitaoka 120a6e
    rad = fltradHamming2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Hamming3:
Shinya Kitaoka 120a6e
    fun = flt_hamming3;
Shinya Kitaoka 120a6e
    rad = fltradHamming3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Lanczos2:
Shinya Kitaoka 120a6e
    fun = flt_lanczos2;
Shinya Kitaoka 120a6e
    rad = fltradLanczos2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Lanczos3:
Shinya Kitaoka 120a6e
    fun = flt_lanczos3;
Shinya Kitaoka 120a6e
    rad = fltradLanczos3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case TRop::Gauss:
Shinya Kitaoka 120a6e
    fun = flt_gauss;
Shinya Kitaoka 120a6e
    rad = fltradGauss;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  case 101:
Shinya Kitaoka 120a6e
    fun = flt_w_1;
Shinya Kitaoka 120a6e
    rad = fltradW1;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    fun = flt_triangle;
Shinya Kitaoka 120a6e
    rad = fltradTriangle;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (flt_fun) *flt_fun = fun;
Shinya Kitaoka 120a6e
  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,
Shinya Kitaoka 120a6e
                             double dx_du, double delta_x, int lx, double &xrad,
Shinya Kitaoka 120a6e
                             int &umin, int &umax, int &uwidth) {
Shinya Kitaoka 120a6e
  double (*flt_fun)(double);
Shinya Kitaoka 120a6e
  FILTER *filter, *f;
Shinya Kitaoka 120a6e
  double du_dx;
Shinya Kitaoka 120a6e
  int x;
Shinya Kitaoka 120a6e
  double u_;
Shinya Kitaoka 120a6e
  int u, ulo, uhi, ulomin, uhimax, m, n, nmax;
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  get_flt_fun_rad(flt_type, &flt_fun, flt_rad);
Shinya Kitaoka 120a6e
  du_dx = 1 / dx_du;
Shinya Kitaoka 120a6e
  if (dx_du > 1)
Shinya Kitaoka 120a6e
    nodedist_u = blur; /* magnification */
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    nodedist_u = du_dx * blur; /* minification */
Shinya Kitaoka 120a6e
  rad_u        = flt_rad * nodedist_u;
Shinya Kitaoka 120a6e
  rad_x        = rad_u * dx_du;
Shinya Kitaoka 120a6e
  nodefreq_u   = 1 / nodedist_u;
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
mu = lu - 1;
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  filter = new FILTER[lx];
Shinya Kitaoka 120a6e
  nmax   = 0;
Shinya Kitaoka 120a6e
  ulomin = c_maxint - 1;
Shinya Kitaoka 120a6e
  uhimax = c_minint + 1;
Shinya Kitaoka 120a6e
  for (x = 0; x < lx; x++) {
Shinya Kitaoka 120a6e
    f   = filter + x;
Shinya Kitaoka 120a6e
    u_  = (x - delta_x) * du_dx;
Shinya Kitaoka 120a6e
    ulo = intGT(u_ - rad_u);
Shinya Kitaoka 120a6e
    uhi = intLT(u_ + rad_u);
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
NOT_LESS_THAN( 0, ulo)
Shinya Kitaoka 120a6e
NOT_MORE_THAN(mu, uhi)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
    m = uhi - ulo + 1;
Shinya Kitaoka 120a6e
    if (m > 0) {
Shinya Kitaoka 120a6e
      f->w_base = new float[m];
Shinya Kitaoka 120a6e
      f->w      = f->w_base - ulo;
Shinya Kitaoka 120a6e
      for (sum = 0.0, u = ulo; u <= uhi; u++) {
Shinya Kitaoka 120a6e
        w = (*flt_fun)((u - u_) * nodefreq_u);
Shinya Kitaoka 120a6e
        sum += w;
Shinya Kitaoka 120a6e
        f->w[u] = (float)w;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      for (; ulo <= uhi; ulo++)
Shinya Kitaoka 120a6e
        if (f->w[ulo]) break;
Shinya Kitaoka 120a6e
      for (; uhi >= ulo; uhi--)
Shinya Kitaoka 120a6e
        if (f->w[uhi]) break;
Shinya Kitaoka 120a6e
      if (ulo < ulomin) ulomin = ulo;
Shinya Kitaoka 120a6e
      if (uhi > uhimax) uhimax = uhi;
Shinya Kitaoka 120a6e
      n                        = uhi - ulo + 1;
Shinya Kitaoka 120a6e
      if (n > nmax) nmax       = n;
Shinya Kitaoka 120a6e
      f->first                 = ulo;
Shinya Kitaoka 120a6e
      f->last                  = uhi;
Shinya Kitaoka 120a6e
      norm                     = 1 / sum;
Shinya Kitaoka 120a6e
      for (u = ulo; u <= uhi; u++) f->w[u] *= (float)norm;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      f->w_base = 0;
Shinya Kitaoka 120a6e
      f->first  = ulo;
Shinya Kitaoka 120a6e
      f->last   = uhi;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  xrad   = rad_x;
Shinya Kitaoka 120a6e
  umin   = ulomin;
Shinya Kitaoka 120a6e
  umax   = uhimax;
Shinya Kitaoka 120a6e
  uwidth = nmax;
Shinya Kitaoka 120a6e
  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,
Shinya Kitaoka 120a6e
                             double dx_du, double delta_x, int lx, int umin,
Shinya Kitaoka 120a6e
                             int umax, int &xwidth) {
Shinya Kitaoka 120a6e
  /*
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
Shinya Kitaoka 120a6e
  NOCALC *nocalc;
Shinya Kitaoka 120a6e
  int width;
Shinya Kitaoka 120a6e
  double flt_rad;
Shinya Kitaoka 120a6e
  double rad_x;
Shinya Kitaoka 120a6e
  double du_dx;
Shinya Kitaoka 120a6e
  double ulo_, uhi_;
Shinya Kitaoka 120a6e
  int ulo, uhi;
Shinya Kitaoka 120a6e
  int x;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  du_dx = 1 / dx_du;
Shinya Kitaoka 120a6e
  get_flt_fun_rad(flt_type, 0, flt_rad);
Shinya Kitaoka 120a6e
  if (dx_du > 1) /* sto ingrandendo */
Shinya Kitaoka 120a6e
    rad_x = flt_rad * blur * dx_du;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    rad_x = flt_rad * blur;
Shinya Kitaoka 120a6e
  rad_x += 0.5; /* ?!?!?!?!? */
Shinya Kitaoka 120a6e
  width  = intGT(2 * rad_x + 1);
Shinya Kitaoka 120a6e
  nocalc = new NOCALC[lx + width - 1];
Shinya Kitaoka 120a6e
  for (x = 0; x < lx + width - 1; x++) {
Shinya Kitaoka 120a6e
    ulo_            = (x - rad_x - delta_x) * du_dx;
Shinya Kitaoka 120a6e
    uhi_            = ulo_ + du_dx;
Shinya Kitaoka 120a6e
    ulo             = intGE(ulo_);
Shinya Kitaoka 120a6e
    uhi             = intLT(uhi_);
Shinya Kitaoka 120a6e
    nocalc[x].first = std::max(umin, ulo);
Shinya Kitaoka 120a6e
    nocalc[x].last  = std::min(umax, uhi);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  xwidth = width;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  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
*/
Shinya Kitaoka 120a6e
#define CALC_VALUE_INIT                                                        \
Shinya Kitaoka 120a6e
  { calc_value = 0xffffU; }
Toshihiro Shimizu 890ddd
#define CALC_VALUE_EMPTY (calc_value == 0xffffU)
Toshihiro Shimizu 890ddd
#define CALC_VALUE_READY (calc_value <= 0x1ffU)
Shinya Kitaoka 120a6e
#define CALC_VALUE_ADVANCE                                                     \
Shinya Kitaoka 120a6e
  { calc_value >>= 1; }
Shinya Kitaoka 120a6e
#define CALC_VALUE_NOCALC                                                      \
Shinya Kitaoka 120a6e
  { calc_value &= ~0x80U; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename pixtype=""></typename>
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
__forceinline
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    void
Shinya Kitaoka 120a6e
    ResampleCalcAlgo(PixType *buffer_in, int lu, int lv, int wrap_in,
Shinya Kitaoka 120a6e
                     int max_pix_ref_u, int min_pix_ref_u, int max_pix_ref_v,
Shinya Kitaoka 120a6e
                     int min_pix_ref_v, UCHAR *calc, int calc_bytesize,
Shinya Kitaoka 120a6e
                     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
{
Shinya Kitaoka 120a6e
  PixType *prev_line_in;
Shinya Kitaoka 120a6e
  PixType *last_line_in;
Shinya Kitaoka 120a6e
  PixType prev_value;
Shinya Kitaoka 120a6e
  PixType left_value;
Shinya Kitaoka 120a6e
  PixType last_value;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT calc_value;
Shinya Kitaoka 120a6e
  UCHAR *calc_byte = 0;
Shinya Kitaoka 120a6e
  int goodcols;
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> col_height(new int[lu]);</int[]>
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int filter_diam_u = max_pix_ref_u - min_pix_ref_u + 1;
Shinya Kitaoka 120a6e
  int filter_diam_v = max_pix_ref_v - min_pix_ref_v + 1;
Shinya Kitaoka 120a6e
  int last_u, last_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int *ch;
Shinya Kitaoka 120a6e
  int *ch_end;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(col_height);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  CALC_VALUE_INIT
Shinya Kitaoka 120a6e
  ch     = col_height.get();
Shinya Kitaoka 120a6e
  ch_end = ch + lu;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  while (ch < ch_end) {
Shinya Kitaoka 120a6e
    *ch = filter_diam_v;
Shinya Kitaoka 120a6e
    ++ch;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  last_line_in = buffer_in;
Shinya Kitaoka 120a6e
  for (last_v = 1, ref_v = last_v - max_pix_ref_v; ref_v < 0;
Shinya Kitaoka 120a6e
       last_v++, ref_v++) {
Shinya Kitaoka 120a6e
    prev_line_in = last_line_in;
Shinya Kitaoka 120a6e
    last_line_in = buffer_in + last_v * wrap_in;
Shinya Kitaoka 120a6e
    for (last_u = 0; last_u < lu; last_u++) {
Shinya Kitaoka 120a6e
      last_value = last_line_in[last_u];
Shinya Kitaoka 120a6e
      prev_value = prev_line_in[last_u];
Shinya Kitaoka 120a6e
      if (last_value == prev_value)
Shinya Kitaoka 120a6e
        col_height[last_u]++;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        col_height[last_u] = 1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; last_v < lv; last_v++, ref_v++) {
Shinya Kitaoka 120a6e
    prev_line_in = last_line_in;
Shinya Kitaoka 120a6e
    last_line_in = buffer_in + last_v * wrap_in;
Shinya Kitaoka 120a6e
    last_value   = last_line_in[0];
Shinya Kitaoka 120a6e
    goodcols     = 0;
Shinya Kitaoka 120a6e
    for (last_u = 0, ref_u = last_u - max_pix_ref_u; ref_u < 0;
Shinya Kitaoka 120a6e
         last_u++, ref_u++) {
Shinya Kitaoka 120a6e
      left_value = last_value;
Shinya Kitaoka 120a6e
      last_value = last_line_in[last_u];
Shinya Kitaoka 120a6e
      prev_value = prev_line_in[last_u];
Shinya Kitaoka 120a6e
      if (last_value == prev_value) {
Shinya Kitaoka 120a6e
        col_height[last_u]++;
Shinya Kitaoka 120a6e
        if (col_height[last_u] >= filter_diam_v)
Shinya Kitaoka 120a6e
          if (last_value == left_value)
Shinya Kitaoka 120a6e
            goodcols++;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            goodcols = 1;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          goodcols = 0;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        col_height[last_u] = 1;
Shinya Kitaoka 120a6e
        goodcols           = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    calc_byte = calc + calc_bytewrap * ref_v;
Shinya Kitaoka 120a6e
    CALC_VALUE_INIT
Shinya Kitaoka 120a6e
    for (; last_u < lu; last_u++, ref_u++) {
Shinya Kitaoka 120a6e
      left_value = last_value;
Shinya Kitaoka 120a6e
      last_value = last_line_in[last_u];
Shinya Kitaoka 120a6e
      prev_value = prev_line_in[last_u];
Shinya Kitaoka 120a6e
      if (last_value == prev_value) {
Shinya Kitaoka 120a6e
        col_height[last_u]++;
Shinya Kitaoka 120a6e
        if (col_height[last_u] >= filter_diam_v)
Shinya Kitaoka 120a6e
          if (last_value == left_value) {
Shinya Kitaoka 120a6e
            goodcols++;
Shinya Kitaoka 120a6e
            if (goodcols >= filter_diam_u) CALC_VALUE_NOCALC
Shinya Kitaoka 120a6e
          } else
Shinya Kitaoka 120a6e
            goodcols = 1;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          goodcols = 0;
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        col_height[last_u] = 1;
Shinya Kitaoka 120a6e
        goodcols           = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (CALC_VALUE_READY) {
Shinya Kitaoka 120a6e
        *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
        CALC_VALUE_INIT
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (; ref_u < lu; last_u++, ref_u++) {
Shinya Kitaoka 120a6e
      if (CALC_VALUE_READY) {
Shinya Kitaoka 120a6e
        *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
        CALC_VALUE_INIT
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!CALC_VALUE_EMPTY) {
Shinya Kitaoka 120a6e
      while (!CALC_VALUE_READY) CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
      *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (; ref_v < lv; last_v++, ref_v++) {
Shinya Kitaoka 120a6e
    for (last_u = 0, ref_u = last_u - max_pix_ref_u; ref_u < 0;
Shinya Kitaoka 120a6e
         last_u++, ref_u++) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    calc_byte = calc + calc_bytewrap * ref_v;
Shinya Kitaoka 120a6e
    CALC_VALUE_INIT
Shinya Kitaoka 120a6e
    for (; last_u < lu; last_u++, ref_u++) {
Shinya Kitaoka 120a6e
      if (CALC_VALUE_READY) {
Shinya Kitaoka 120a6e
        *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
        CALC_VALUE_INIT
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (; ref_u < lu; last_u++, ref_u++) {
Shinya Kitaoka 120a6e
      if (CALC_VALUE_READY) {
Shinya Kitaoka 120a6e
        *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
        CALC_VALUE_INIT
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (!CALC_VALUE_EMPTY) {
Shinya Kitaoka 120a6e
      while (!CALC_VALUE_READY) CALC_VALUE_ADVANCE
Shinya Kitaoka 120a6e
      *calc_byte++ = (UCHAR)calc_value;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
void create_calc(const TRasterPT<t> &rin, int min_pix_ref_u, int max_pix_ref_u,</t>
Shinya Kitaoka 120a6e
                 int min_pix_ref_v, int max_pix_ref_v, UCHAR *&p_calc,
Shinya Kitaoka 120a6e
                 int &p_calc_allocsize, int &p_calc_bytewrap) {
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int lu, lv;
Shinya Kitaoka 120a6e
  int wrap_in;
Shinya Kitaoka 120a6e
  int calc_bytesize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  lu      = rin->getLx();
Shinya Kitaoka 120a6e
  lv      = rin->getLy();
Shinya Kitaoka 120a6e
  wrap_in = rin->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  p_calc_bytewrap = (lu + 7) >> 3;  // ceil(lu/8)
Shinya Kitaoka 120a6e
  calc_bytewrap   = p_calc_bytewrap;
Shinya Kitaoka 120a6e
  calc_bytesize   = calc_bytewrap * lv;  // lv * ceil(lu/8)
Shinya Kitaoka 120a6e
  if (calc_bytesize > p_calc_allocsize) {
Shinya Kitaoka 120a6e
    if (p_calc_allocsize) delete[](p_calc);
Shinya Kitaoka 120a6e
    // TMALLOC (*p_calc, calc_bytesize)
Shinya Kitaoka 120a6e
    p_calc = new UCHAR[calc_bytesize];
Shinya Kitaoka 120a6e
    assert(p_calc);
Shinya Kitaoka 120a6e
    memset(p_calc, 0xff, calc_bytesize);
Shinya Kitaoka 120a6e
    p_calc_allocsize = calc_bytesize;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  calc = p_calc;
Shinya Kitaoka 120a6e
  if (lu < max_pix_ref_u + 1 || lv < max_pix_ref_v + 1) {
Shinya Kitaoka 120a6e
    memset(calc, 0xff, calc_bytesize);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // RESAMPLE_CALC_ALGO
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ResampleCalcAlgo<t>(rin->pixels(), lu, lv, wrap_in, max_pix_ref_u,</t>
Shinya Kitaoka 120a6e
                      min_pix_ref_u, max_pix_ref_v, min_pix_ref_v, calc,
Shinya Kitaoka 120a6e
                      calc_bytesize, calc_bytewrap);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
class Converter {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static inline T convert(const TPixel32 &pixin) { return pixin; }
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 <>
Shinya Kitaoka 120a6e
class Converter<tpixel64> {</tpixel64>
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static inline TPixel64 convert(const TPixel32 &pix) {
Shinya Kitaoka 120a6e
    return TPixel64(USHORT_FROM_BYTE(pix.r), USHORT_FROM_BYTE(pix.g),
Shinya Kitaoka 120a6e
                    USHORT_FROM_BYTE(pix.b), USHORT_FROM_BYTE(pix.m));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline double get_filter_value(TRop::ResampleFilterType flt_type, double x) {
Shinya Kitaoka 120a6e
  // it is assumed that x != 0 (not checked only for speed reasons)
Shinya Kitaoka 120a6e
  switch (flt_type) {
Shinya Kitaoka 120a6e
  case TRop::Triangle:
Shinya Kitaoka 120a6e
    if (x < -1.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 0.0) return 1.0 + x;
Shinya Kitaoka 120a6e
    if (x < 1.0) return 1.0 - x;
Shinya Kitaoka 120a6e
    return 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Mitchell: {
Shinya Kitaoka 120a6e
    static double p0, p2, p3, q0, q1, q2, q3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!p0) {
Shinya Kitaoka 120a6e
      const double b = 1.0 / 3.0;
Shinya Kitaoka 120a6e
      const double c = 1.0 / 3.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      p0 = (6.0 - 2.0 * b) / 6.0;
Shinya Kitaoka 120a6e
      p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0;
Shinya Kitaoka 120a6e
      p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0;
Shinya Kitaoka 120a6e
      q0 = (8.0 * b + 24.0 * c) / 6.0;
Shinya Kitaoka 120a6e
      q1 = (-12.0 * b - 48.0 * c) / 6.0;
Shinya Kitaoka 120a6e
      q2 = (6.0 * b + 30.0 * c) / 6.0;
Shinya Kitaoka 120a6e
      q3 = (-b - 6.0 * c) / 6.0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (x < -2.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < -1.0) return (q0 - x * (q1 - x * (q2 - x * q3)));
Shinya Kitaoka 120a6e
    if (x < 0.0) return (p0 + x * x * (p2 - x * p3));
Shinya Kitaoka 120a6e
    if (x < 1.0) return (p0 + x * x * (p2 + x * p3));
Shinya Kitaoka 120a6e
    if (x < 2.0) return (q0 + x * (q1 + x * (q2 + x * q3)));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Cubic5:
Shinya Kitaoka 120a6e
    if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
    if (x < 1.0) return 2.5 * x * x * x - 3.5 * x * x + 1;
Shinya Kitaoka 120a6e
    if (x < 2.0) return 0.5 * x * x * x - 2.5 * x * x + 4 * x - 2;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Cubic75:
Shinya Kitaoka 120a6e
    if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
    if (x < 1.0) return 2.75 * x * x * x - 3.75 * x * x + 1;
Shinya Kitaoka 120a6e
    if (x < 2.0) return 0.75 * x * x * x - 3.75 * x * x + 6 * x - 3;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Cubic1:
Shinya Kitaoka 120a6e
    if (x < 0.0) x = -x;
Shinya Kitaoka 120a6e
    if (x < 1.0) return 3 * x * x * x - 4 * x * x + 1;
Shinya Kitaoka 120a6e
    if (x < 2.0) return x * x * x - 5 * x * x + 8 * x - 4;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Hann2:
Shinya Kitaoka 120a6e
    if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 2.0) return sinc0(x, 1) * (0.5 + 0.5 * cos(M_PI_2 * x));
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Hann3:
Shinya Kitaoka 120a6e
    if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 3.0) return sinc0(x, 1) * (0.5 + 0.5 * cos(M_PI_3 * x));
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Hamming2:
Shinya Kitaoka 120a6e
    if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 2.0) return sinc0(x, 1) * (0.54 + 0.46 * cos(M_PI_2 * x));
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Hamming3:
Shinya Kitaoka 120a6e
    if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 3.0) return sinc0(x, 1) * (0.54 + 0.46 * cos(M_PI_3 * x));
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Lanczos2:
Shinya Kitaoka 120a6e
    if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 2.0) return sinc0(x, 1) * sinc0(x, 2);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Lanczos3:
Shinya Kitaoka 120a6e
    if (x <= -3.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 3.0) return sinc0(x, 1) * sinc0(x, 3);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRop::Gauss:
Shinya Kitaoka 120a6e
    if (x <= -2.0) return 0.0;
Shinya Kitaoka 120a6e
    if (x < 2.0) return exp(-M_PI * x * x); /* exp(-M_PI*2*2)~=3.5*10^-6 */
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  default:
Shinya Kitaoka 120a6e
    assert(!"bad filter type");
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return 0.0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void resample_clear_rgbm(TRasterPT<t> rout, T default_value) {</t>
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  for (int out_y = 0; out_y < rout->getLy(); out_y++)
Shinya Kitaoka 120a6e
    for (int out_x = 0; out_x < rout->getLx(); out_x++)
Shinya Kitaoka 120a6e
      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>
Shinya Kitaoka 120a6e
                        const TAffine &aff_xy2uv, const TAffine &aff0_uv2fg,
Shinya Kitaoka 120a6e
                        int min_pix_ref_u, int min_pix_ref_v, int max_pix_ref_u,
Shinya Kitaoka 120a6e
                        int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
                        int *pix_ref_v, int *pix_ref_f, int *pix_ref_g,
Shinya Kitaoka 120a6e
                        short *filter) {
Shinya Kitaoka 120a6e
  const T *buffer_in;
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  T *pix_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int filter_mu, filter_mv;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  int outside_min_u, outside_min_v;
Shinya Kitaoka 120a6e
  int outside_max_u, outside_max_v;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  T pix_value, default_value(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  SUMS_TYPE weight, sum_weights;
Shinya Kitaoka 120a6e
  double inv_sum_weights;
Shinya Kitaoka 120a6e
  SUMS_TYPE sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Shinya Kitaoka 120a6e
  double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Shinya Kitaoka 120a6e
  int out_value_r, out_value_g, out_value_b, out_value_m;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    rout->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Create a bit array, each indicating whether a pixel has to be calculated or
Shinya Kitaoka 120a6e
  // not
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  filter_mu       = max_pix_ref_u - min_pix_ref_u;
Shinya Kitaoka 120a6e
  filter_mv       = max_pix_ref_v - min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - filter_mu;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - filter_mv;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u   = -max_pix_ref_u;
Shinya Kitaoka 120a6e
  outside_min_v   = -max_pix_ref_v;
Shinya Kitaoka 120a6e
  outside_max_u   = mu - min_pix_ref_u;
Shinya Kitaoka 120a6e
  outside_max_v   = mv - min_pix_ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // For every pixel of the output image
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.5; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.5; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      pix_out = buffer_out + out_y * wrap_out + out_x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Take the pre-image of the pixel through the passed affine
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Convert to integer coordinates
Shinya Kitaoka 120a6e
      ref_u = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // NOTE: The following condition is equivalent to:
Shinya Kitaoka 120a6e
      // (ref_u + min_pix_ref_u >= 0 && ref_v + min_pix_ref_v >= 0 &&
Shinya Kitaoka 120a6e
      //  ref_u + max_pix_ref_u < lu && ref_v + max_pix_ref_v < lv)
Shinya Kitaoka 120a6e
      // - since the presence of (UINT) makes integeres < 0 become >> 0
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u + min_pix_ref_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v + min_pix_ref_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        // The filter mask starting around (ref_u, ref_v) is completely
Shinya Kitaoka 120a6e
        // contained
Shinya Kitaoka 120a6e
        // in the source raster
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // Get the calculation array mask byte
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) &
Shinya Kitaoka 120a6e
                           1))  // If the mask bit for this pixel is on
Shinya Kitaoka 120a6e
        {
Shinya Kitaoka 120a6e
          ref_out_u_ = ref_u - out_u_;  // Fractionary part of the pre-image
Shinya Kitaoka 120a6e
          ref_out_v_ = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_ = aff0MV1(aff0_uv2fg, ref_out_u_,
Shinya Kitaoka 120a6e
                               ref_out_v_);  // Make the image of it into fg
Shinya Kitaoka 120a6e
          ref_out_g_ = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f  = tround(ref_out_f_);  // Convert to integer coordinates
Shinya Kitaoka 120a6e
          ref_out_g  = tround(ref_out_g_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // Make the weighted sum of source pixels
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; --i) {
Shinya Kitaoka 120a6e
            // Build the weight for this pixel
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;  // image of the integer part
Shinya Kitaoka 120a6e
                                                   // + that of the fractionary
Shinya Kitaoka 120a6e
                                                   // part
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // Add the weighted pixel contribute
Shinya Kitaoka 120a6e
            pix_u = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
            sum_contribs_r += (SUMS_TYPE)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (SUMS_TYPE)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (SUMS_TYPE)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (SUMS_TYPE)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          pix_out->r = out_value_r;
Shinya Kitaoka 120a6e
          pix_out->g = out_value_g;
Shinya Kitaoka 120a6e
          pix_out->b = out_value_b;
Shinya Kitaoka 120a6e
          pix_out->m = out_value_m;
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          // The pixel is copied from the corresponding source...
Shinya Kitaoka 120a6e
          *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
      } else if (outside_min_u <= ref_u && ref_u <= outside_max_u &&
Shinya Kitaoka 120a6e
                 outside_min_v <= ref_v && ref_v <= outside_max_v) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; --i) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (pix_u < 0 || pix_u > mu || pix_v < 0 || pix_v > mv) {
Shinya Kitaoka 120a6e
              sum_weights += weight;  // 0-padding
Shinya Kitaoka 120a6e
              continue;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);  // Copy-padding
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
            sum_contribs_r += (SUMS_TYPE)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (SUMS_TYPE)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (SUMS_TYPE)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (SUMS_TYPE)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          pix_out->r = out_value_r;
Shinya Kitaoka 120a6e
          pix_out->g = out_value_g;
Shinya Kitaoka 120a6e
          pix_out->b = out_value_b;
Shinya Kitaoka 120a6e
          pix_out->m = out_value_m;
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        *pix_out = default_value;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
__declspec(align(16)) class TPixelFloat {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TPixelFloat() : b(0), g(0), r(0), m(0) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPixelFloat(float rr, float gg, float bb, float mm)
Shinya Kitaoka 120a6e
      : b(bb), g(gg), r(rr), m(mm) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPixelFloat(const TPixel32 &pix) : b(pix.b), g(pix.g), r(pix.r), m(pix.m) {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  float b, g, r, m;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // 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>
Shinya Kitaoka 120a6e
                             const TAffine &aff_xy2uv,
Shinya Kitaoka 120a6e
                             const TAffine &aff0_uv2fg, int min_pix_ref_u,
Shinya Kitaoka 120a6e
                             int min_pix_ref_v, int max_pix_ref_u,
Shinya Kitaoka 120a6e
                             int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
                             int *pix_ref_v, int *pix_ref_f, int *pix_ref_g,
Shinya Kitaoka 120a6e
                             short *filter) {
Shinya Kitaoka 120a6e
  __m128i zeros = _mm_setzero_si128();
Shinya Kitaoka 120a6e
  const T *buffer_in;
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int filter_mu, filter_mv;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  // double outside_min_u_,  outside_min_v_;
Shinya Kitaoka 120a6e
  // double outside_max_u_,  outside_max_v_;
Shinya Kitaoka 120a6e
  int outside_min_u, outside_min_v;
Shinya Kitaoka 120a6e
  int outside_max_u, outside_max_v;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  T pix_value;
Shinya Kitaoka 120a6e
  T default_value(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  float weight;
Shinya Kitaoka 120a6e
  float sum_weights;
Shinya Kitaoka 120a6e
  float inv_sum_weights;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  T *pix_out;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128 sum_contribs_packed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128i pix_value_packed_i;
Shinya Kitaoka 120a6e
  __m128 pix_value_packed;
Shinya Kitaoka 120a6e
  __m128 weight_packed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128 zeros2 = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float maxChannelValue        = (float)T::maxChannelValue;
Shinya Kitaoka 120a6e
  __m128 maxChanneValue_packed = _mm_load1_ps(&maxChannelValue);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    resample_clear_rgbm(rout, default_value);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  filter_mu       = max_pix_ref_u - min_pix_ref_u;
Shinya Kitaoka 120a6e
  filter_mv       = max_pix_ref_v - min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - filter_mu;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - filter_mv;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u   = -max_pix_ref_u;
Shinya Kitaoka 120a6e
  outside_min_v   = -max_pix_ref_v;
Shinya Kitaoka 120a6e
  outside_max_u   = mu - min_pix_ref_u;
Shinya Kitaoka 120a6e
  outside_max_v   = mv - min_pix_ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.5; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.5; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      pix_out = buffer_out + out_y * wrap_out + out_x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      ref_u  = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v  = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u + min_pix_ref_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v + min_pix_ref_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Shinya Kitaoka 120a6e
          ref_out_u_  = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_  = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_  = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_  = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f   = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g   = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          sum_contribs_packed = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            pix_value          = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
            pix_value_packed_i = _mm_unpacklo_epi8(
Shinya Kitaoka 120a6e
                _mm_cvtsi32_si128(*(DWORD *)&pix_value), zeros);
Shinya Kitaoka 120a6e
            pix_value_packed =
Shinya Kitaoka 120a6e
                _mm_cvtepi32_ps(_mm_unpacklo_epi16(pix_value_packed_i, zeros));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            weight_packed = _mm_load1_ps(&weight);
Shinya Kitaoka 120a6e
            sum_contribs_packed =
Shinya Kitaoka 120a6e
                _mm_add_ps(sum_contribs_packed,
Shinya Kitaoka 120a6e
                           _mm_mul_ps(pix_value_packed, weight_packed));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights               = 1.0f / sum_weights;
Shinya Kitaoka 120a6e
          __m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128 out_fval_packed =
Shinya Kitaoka 120a6e
              _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packs_epi32(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packus_epi16(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          *(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
          // if( outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Shinya Kitaoka 120a6e
          //    outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_ )
Shinya Kitaoka 120a6e
          if (outside_min_u <= ref_u && ref_u <= outside_max_u &&
Shinya Kitaoka 120a6e
              outside_min_v <= ref_v && ref_v <= outside_max_v) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_          = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_          = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_          = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_          = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f           = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g           = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights         = 0;
Shinya Kitaoka 120a6e
          sum_contribs_packed = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (pix_u < 0 || pix_u > mu || pix_v < 0 || pix_v > mv) {
Shinya Kitaoka 120a6e
              sum_weights += weight;
Shinya Kitaoka 120a6e
              continue;
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            pix_value          = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
            pix_value_packed_i = _mm_unpacklo_epi8(
Shinya Kitaoka 120a6e
                _mm_cvtsi32_si128(*(DWORD *)&pix_value), zeros);
Shinya Kitaoka 120a6e
            pix_value_packed =
Shinya Kitaoka 120a6e
                _mm_cvtepi32_ps(_mm_unpacklo_epi16(pix_value_packed_i, zeros));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            weight_packed = _mm_load1_ps(&weight);
Shinya Kitaoka 120a6e
            sum_contribs_packed =
Shinya Kitaoka 120a6e
                _mm_add_ps(sum_contribs_packed,
Shinya Kitaoka 120a6e
                           _mm_mul_ps(pix_value_packed, weight_packed));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0f / sum_weights;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Shinya Kitaoka 120a6e
          __m128 out_fval_packed =
Shinya Kitaoka 120a6e
              _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packs_epi32(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packus_epi16(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          *(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        *pix_out = default_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (calc) delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void inline blendBySSE2(TPixel32 *pix_out, float *ink, float *paint,
Shinya Kitaoka 120a6e
                        float *tone, const __m128 &maxtone_packed,
Shinya Kitaoka 120a6e
                        const __m128i &zeros) {
Shinya Kitaoka 120a6e
  __m128 a_packed = _mm_load_ps(ink);
Shinya Kitaoka 120a6e
  __m128 b_packed = _mm_load_ps(paint);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  __m128 num_packed  = _mm_load1_ps(tone);
Shinya Kitaoka 120a6e
  __m128 diff_packed = _mm_sub_ps(maxtone_packed, num_packed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // calcola in modo vettoriale out = ((den-num)*a + num*b)/den
Shinya Kitaoka 120a6e
  __m128 pix_value_packed = _mm_mul_ps(diff_packed, a_packed);
Shinya Kitaoka 120a6e
  __m128 tmpPix_packed    = _mm_mul_ps(num_packed, b_packed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  pix_value_packed = _mm_add_ps(pix_value_packed, tmpPix_packed);
Shinya Kitaoka 120a6e
  pix_value_packed = _mm_div_ps(pix_value_packed, maxtone_packed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // converte i canali da float a char
Shinya Kitaoka 120a6e
  __m128i pix_value_packed_i = _mm_cvtps_epi32(pix_value_packed);
Shinya Kitaoka 120a6e
  pix_value_packed_i         = _mm_packs_epi32(pix_value_packed_i, zeros);
Shinya Kitaoka 120a6e
  pix_value_packed_i         = _mm_packus_epi16(pix_value_packed_i, zeros);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  *(DWORD *)(pix_out) = _mm_cvtsi128_si32(pix_value_packed_i);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void inline blendBySSE2(__m128 &pix_out_packed, float *ink, float *paint,
Shinya Kitaoka 120a6e
                        float *tone, const __m128 &maxtone_packed,
Shinya Kitaoka 120a6e
                        const __m128i &zeros) {
Shinya Kitaoka 120a6e
  __m128 a_packed = _mm_load_ps(ink);
Shinya Kitaoka 120a6e
  __m128 b_packed = _mm_load_ps(paint);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  __m128 num_packed  = _mm_load1_ps(tone);
Shinya Kitaoka 120a6e
  __m128 diff_packed = _mm_sub_ps(maxtone_packed, num_packed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // calcola in modo vettoriale out = ((den-num)*a + num*b)/den
Shinya Kitaoka 120a6e
  pix_out_packed       = _mm_mul_ps(diff_packed, a_packed);
Shinya Kitaoka 120a6e
  __m128 tmpPix_packed = _mm_mul_ps(num_packed, b_packed);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  pix_out_packed = _mm_add_ps(pix_out_packed, tmpPix_packed);
Shinya Kitaoka 120a6e
  pix_out_packed = _mm_div_ps(pix_out_packed, maxtone_packed);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // _WIN32
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static void get_prow_gr8(const TRasterGR8P &rin, double a11, double a12,
Shinya Kitaoka 120a6e
                         double a21, double a22, int pmin, int pmax, int q,
Shinya Kitaoka 120a6e
                         float *prow) {
Shinya Kitaoka 120a6e
  UCHAR *bufin_gr8, *in_gr8;
Shinya Kitaoka 120a6e
  int u, v;
Shinya Kitaoka 120a6e
  int p, p1, p2;
Shinya Kitaoka 120a6e
  UINT lu, lv;
Shinya Kitaoka 120a6e
  UINT mu, mv;
Shinya Kitaoka 120a6e
  int du, dv;
Shinya Kitaoka 120a6e
  double u_0, v_0;
Shinya Kitaoka 120a6e
  double u_, v_;
Shinya Kitaoka 120a6e
  double fu, fv;
Shinya Kitaoka 120a6e
  double gu, gv;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
  bufin_gr8 = (UCHAR *)rin->pixels();
Shinya Kitaoka 120a6e
  lu        = rin->getLx();
Shinya Kitaoka 120a6e
  mu        = lu - 1;
Shinya Kitaoka 120a6e
  lv        = rin->getLy();
Shinya Kitaoka 120a6e
  mv        = lv - 1;
Shinya Kitaoka 120a6e
  du        = 1;
Shinya Kitaoka 120a6e
  dv        = rin->getWrap();
Shinya Kitaoka 120a6e
  u_0       = a12 * q;
Shinya Kitaoka 120a6e
  v_0       = a22 * q;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (p = pmin; p <= pmax; p++)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_ = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if ((UINT)u < mu && (UINT)v < mv) break;
Shinya Kitaoka 120a6e
      fu      = u_ - u;
Shinya Kitaoka 120a6e
      gu      = 1. - fu;
Shinya Kitaoka 120a6e
      fv      = v_ - v;
Shinya Kitaoka 120a6e
      gv      = 1. - fv;
Shinya Kitaoka 120a6e
      in_gr8  = bufin_gr8 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] = (float)troundp(
Shinya Kitaoka 120a6e
          fu * gv *
Shinya Kitaoka 120a6e
              (((UINT)(u + 1) < lu && (UINT)v < lv) ? in_gr8[du] : BORDER) +
Shinya Kitaoka 120a6e
          fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv)
Shinya Kitaoka 120a6e
                         ? in_gr8[du + dv]
Shinya Kitaoka 120a6e
                         : BORDER) +
Shinya Kitaoka 120a6e
          gu * gv * (((UINT)u < lu && (UINT)v < lv) ? in_gr8[0] : BORDER) +
Shinya Kitaoka 120a6e
          gu * fv *
Shinya Kitaoka 120a6e
              (((UINT)u < lu && (UINT)(v + 1) < lv) ? in_gr8[dv] : BORDER));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  p1 = p;
Shinya Kitaoka 120a6e
  for (p = pmax; p > p1; p--)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_ = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if ((UINT)u < mu && (UINT)v < mv) break;
Shinya Kitaoka 120a6e
      fu      = u_ - u;
Shinya Kitaoka 120a6e
      gu      = 1. - fu;
Shinya Kitaoka 120a6e
      fv      = v_ - v;
Shinya Kitaoka 120a6e
      gv      = 1. - fv;
Shinya Kitaoka 120a6e
      in_gr8  = bufin_gr8 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] = (float)troundp(
Shinya Kitaoka 120a6e
          fu * gv *
Shinya Kitaoka 120a6e
              (((UINT)(u + 1) < lu && (UINT)v < lv) ? in_gr8[du] : BORDER) +
Shinya Kitaoka 120a6e
          fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv)
Shinya Kitaoka 120a6e
                         ? in_gr8[du + dv]
Shinya Kitaoka 120a6e
                         : BORDER) +
Shinya Kitaoka 120a6e
          gu * gv * (((UINT)u < lu && (UINT)v < lv) ? in_gr8[0] : BORDER) +
Shinya Kitaoka 120a6e
          gu * fv *
Shinya Kitaoka 120a6e
              (((UINT)u < lu && (UINT)(v + 1) < lv) ? in_gr8[dv] : BORDER));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  p2 = p;
Shinya Kitaoka 120a6e
  for (p = p1; p <= p2; p++)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_     = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u      = (int)(u_);
Shinya Kitaoka 120a6e
      v_     = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v      = (int)(v_);
Shinya Kitaoka 120a6e
      fu     = u_ - u;
Shinya Kitaoka 120a6e
      gu     = 1. - fu;
Shinya Kitaoka 120a6e
      fv     = v_ - v;
Shinya Kitaoka 120a6e
      gv     = 1. - fv;
Shinya Kitaoka 120a6e
      in_gr8 = bufin_gr8 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] =
Shinya Kitaoka 120a6e
          (float)troundp(fu * gv * in_gr8[du] + fu * fv * in_gr8[du + dv] +
Shinya Kitaoka 120a6e
                         gu * gv * in_gr8[0] + gu * fv * in_gr8[dv]);
Shinya Kitaoka 120a6e
    }
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
Shinya Kitaoka 120a6e
static void get_prow_gr8(const TRaster32P &rin, double a11, double a12,
Shinya Kitaoka 120a6e
                         double a21, double a22, int pmin, int pmax, int q,
Shinya Kitaoka 120a6e
                         float *prow) {
Shinya Kitaoka 120a6e
  TPixel *bufin_32, *in_32;
Shinya Kitaoka 120a6e
  int u, v;
Shinya Kitaoka 120a6e
  int p, p1, p2;
Shinya Kitaoka 120a6e
  UINT lu, lv;
Shinya Kitaoka 120a6e
  UINT mu, mv;
Shinya Kitaoka 120a6e
  int du, dv;
Shinya Kitaoka 120a6e
  double u_0, v_0;
Shinya Kitaoka 120a6e
  double u_, v_;
Shinya Kitaoka 120a6e
  double fu, fv;
Shinya Kitaoka 120a6e
  double gu, gv;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  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
Shinya Kitaoka 120a6e
  bufin_32 = (TPixel *)rin->pixels();
Shinya Kitaoka 120a6e
  lu       = rin->getLx();
Shinya Kitaoka 120a6e
  mu       = lu - 1;
Shinya Kitaoka 120a6e
  lv       = rin->getLy();
Shinya Kitaoka 120a6e
  mv       = lv - 1;
Shinya Kitaoka 120a6e
  du       = 1;
Shinya Kitaoka 120a6e
  dv       = rin->getWrap();
Shinya Kitaoka 120a6e
  u_0      = a12 * q;
Shinya Kitaoka 120a6e
  v_0      = a22 * q;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (p = pmin; p <= pmax; p++)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_ = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if ((UINT)u < mu && (UINT)v < mv) break;
Shinya Kitaoka 120a6e
      fu      = u_ - u;
Shinya Kitaoka 120a6e
      gu      = 1. - fu;
Shinya Kitaoka 120a6e
      fv      = v_ - v;
Shinya Kitaoka 120a6e
      gv      = 1. - fv;
Shinya Kitaoka 120a6e
      in_32   = bufin_32 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] = (float)troundp(
Shinya Kitaoka 120a6e
          fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? grey(in_32[du])
Shinya Kitaoka 120a6e
                                                          : BORDER) +
Shinya Kitaoka 120a6e
          fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv)
Shinya Kitaoka 120a6e
                         ? grey(in_32[du + dv])
Shinya Kitaoka 120a6e
                         : BORDER) +
Shinya Kitaoka 120a6e
          gu * gv * (((UINT)u < lu && (UINT)v < lv) ? grey(in_32[0]) : BORDER) +
Shinya Kitaoka 120a6e
          gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? grey(in_32[dv])
Shinya Kitaoka 120a6e
                                                          : BORDER));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  p1 = p;
Shinya Kitaoka 120a6e
  for (p = pmax; p > p1; p--)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_ = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if ((UINT)u < mu && (UINT)v < mv) break;
Shinya Kitaoka 120a6e
      fu      = u_ - u;
Shinya Kitaoka 120a6e
      gu      = 1. - fu;
Shinya Kitaoka 120a6e
      fv      = v_ - v;
Shinya Kitaoka 120a6e
      gv      = 1. - fv;
Shinya Kitaoka 120a6e
      in_32   = bufin_32 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] = (float)troundp(
Shinya Kitaoka 120a6e
          fu * gv * (((UINT)(u + 1) < lu && (UINT)v < lv) ? grey(in_32[du])
Shinya Kitaoka 120a6e
                                                          : BORDER) +
Shinya Kitaoka 120a6e
          fu * fv * (((UINT)(u + 1) < lu && (UINT)(v + 1) < lv)
Shinya Kitaoka 120a6e
                         ? grey(in_32[du + dv])
Shinya Kitaoka 120a6e
                         : BORDER) +
Shinya Kitaoka 120a6e
          gu * gv * (((UINT)u < lu && (UINT)v < lv) ? grey(in_32[0]) : BORDER) +
Shinya Kitaoka 120a6e
          gu * fv * (((UINT)u < lu && (UINT)(v + 1) < lv) ? grey(in_32[dv])
Shinya Kitaoka 120a6e
                                                          : BORDER));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  p2 = p;
Shinya Kitaoka 120a6e
  for (p = p1; p <= p2; p++)
Shinya Kitaoka 120a6e
    if (!prow[p]) {
Shinya Kitaoka 120a6e
      u_      = u_0 + a11 * p;
Shinya Kitaoka 120a6e
      u       = (int)(u_);
Shinya Kitaoka 120a6e
      v_      = v_0 + a21 * p;
Shinya Kitaoka 120a6e
      v       = (int)(v_);
Shinya Kitaoka 120a6e
      fu      = u_ - u;
Shinya Kitaoka 120a6e
      gu      = 1. - fu;
Shinya Kitaoka 120a6e
      fv      = v_ - v;
Shinya Kitaoka 120a6e
      gv      = 1. - fv;
Shinya Kitaoka 120a6e
      in_32   = bufin_32 + (u * du + v * dv);
Shinya Kitaoka 120a6e
      prow[p] = (float)troundp(
Shinya Kitaoka 120a6e
          fu * gv * grey(in_32[du]) + fu * fv * grey(in_32[du + dv]) +
Shinya Kitaoka 120a6e
          gu * gv * grey(in_32[0]) + gu * fv * grey(in_32[dv]));
Shinya Kitaoka 120a6e
    }
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,
Shinya Kitaoka 120a6e
                             const TAffine &aff, const TAffine &invrot,
Shinya Kitaoka 120a6e
                             FILTER *rowflt, int pmin, int pmax, FILTER *colflt,
Shinya Kitaoka 120a6e
                             int qmin, int qmax, int nrows, int flatradu,
Shinya Kitaoka 120a6e
                             int flatradv, double flatradx_, double flatrady_,
Shinya Kitaoka 120a6e
                             NOCALC *rownoc, int nocdiamx, NOCALC *colnoc,
Shinya Kitaoka 120a6e
                             int nocdiamy) {
Shinya Kitaoka 120a6e
  FILTER *xflt, *yflt;
Shinya Kitaoka 120a6e
  UCHAR *bufin_gr8, *bufout_gr8, *in_gr8, *out_gr8;
Shinya Kitaoka 120a6e
  float *prow_base, *prow, **xrow_base, **xrow, *xxx, tmp;
Shinya Kitaoka 120a6e
  double x_, y_;
Shinya Kitaoka 120a6e
  int u, v;  //, vw;
Shinya Kitaoka 120a6e
  int p, q;
Shinya Kitaoka 120a6e
  int x, y;
Shinya Kitaoka 120a6e
  int lu, lv, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, mx, my;
Shinya Kitaoka 120a6e
  // int dudp, dudq, dvdp, dvdq;
Shinya Kitaoka 120a6e
  int topq, topy;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int flatdiamu, flatdiamv;
Shinya Kitaoka 120a6e
  int xlo, xhi, ylo, yhi;
Shinya Kitaoka 120a6e
  int *nocheight;
Shinya Kitaoka 120a6e
  int nocwidth;
Shinya Kitaoka 120a6e
  int i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bufin_gr8  = (UCHAR *)rin->pixels();
Shinya Kitaoka 120a6e
  bufout_gr8 = (UCHAR *)rout->pixels();
Shinya Kitaoka 120a6e
  wrapin     = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout    = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  lu        = rin->getLx();
Shinya Kitaoka 120a6e
  mu        = lu - 1;
Shinya Kitaoka 120a6e
  lv        = rin->getLy();
Shinya Kitaoka 120a6e
  mv        = lv - 1;
Shinya Kitaoka 120a6e
  lx        = rout->getLx();
Shinya Kitaoka 120a6e
  mx        = lx - 1;
Shinya Kitaoka 120a6e
  ly        = rout->getLy();
Shinya Kitaoka 120a6e
  my        = ly - 1;
Shinya Kitaoka 120a6e
  prow_base = new float[pmax - pmin + 1];
Shinya Kitaoka 120a6e
  prow      = prow_base - pmin;
Shinya Kitaoka 120a6e
  xrow_base = new MyFloatPtr[qmax - (qmin - nrows) + 1];
Shinya Kitaoka 120a6e
  xrow      = xrow_base - (qmin - nrows);
Shinya Kitaoka 120a6e
  topq      = qmin;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // app = xrow+topq-nrows;
Shinya Kitaoka 120a6e
  i = 0;
Shinya Kitaoka 120a6e
  j = 3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < nrows; i++) *(xrow + topq - nrows + i) = new float[lx];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // while(app
Shinya Kitaoka 120a6e
  //  *app++ = new float[lx];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  flatdiamu = flatradu * 2 + 1;
Shinya Kitaoka 120a6e
  flatdiamv = flatradv * 2 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = 0; y < ly; y++)
Shinya Kitaoka 120a6e
    memset(bufout_gr8 + y * wrapout, 127, sizeof(UCHAR) * lx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int count = 0; /* !!!!!!!!!!!!!!!!*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int *colheight;
Shinya Kitaoka 120a6e
  UCHAR *colval;
Shinya Kitaoka 120a6e
  int flatcols;
Shinya Kitaoka 120a6e
  UCHAR flatval;
Shinya Kitaoka 120a6e
  double xlo_, xhi_, ylo_, yhi_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*  TCALLOC (colheight, lu);
Shinya Kitaoka 120a6e
TCALLOC (colval,    lu);*/
Shinya Kitaoka 120a6e
  colheight = new int[lu];
Shinya Kitaoka 120a6e
  // memset(colheight, 0, lu);
Shinya Kitaoka 120a6e
  colval = new UCHAR[lu];
Shinya Kitaoka 120a6e
  // memset(colval, 0, lu);
Shinya Kitaoka 120a6e
  for (u = 0; u < (int)lu; u++) {
Shinya Kitaoka 120a6e
    colheight[u] = 0;
Shinya Kitaoka 120a6e
    colval[u]    = BORDER_GR8;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (v = 0; v < (int)lv; v++) {
Shinya Kitaoka 120a6e
    x_ = affMV1(aff, 0 - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
    y_ = affMV2(aff, 0 - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    xlo_ = tceil(x_ - flatradx_);
Shinya Kitaoka 120a6e
    xhi_ = tfloor(x_ + flatradx_);
Shinya Kitaoka 120a6e
    ylo_ = tceil(y_ - flatrady_);
Shinya Kitaoka 120a6e
    yhi_ = tfloor(y_ + flatrady_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    flatcols = 0;
Shinya Kitaoka 120a6e
    flatval  = BORDER_GR8;
Shinya Kitaoka 120a6e
    for (u = 0, in_gr8 = bufin_gr8 + v * wrapin; u < (int)lu; u++, in_gr8++) {
Shinya Kitaoka 120a6e
      if (*in_gr8 == colval[u])
Shinya Kitaoka 120a6e
        colheight[u]++;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        colheight[u] = 1;
Shinya Kitaoka 120a6e
        colval[u]    = *in_gr8;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (colheight[u] >= flatdiamv)
Shinya Kitaoka 120a6e
        if (colval[u] == flatval)
Shinya Kitaoka 120a6e
          flatcols++;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          flatcols = 1;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        flatcols = 0;
Shinya Kitaoka 120a6e
      flatval    = colval[u];
Shinya Kitaoka 120a6e
      if (flatcols >= flatdiamu) {
Toshihiro Shimizu 890ddd
#ifdef VECCHIA_MANIERA
Shinya Kitaoka 120a6e
        x_  = AFF_M_V_1(aff, u - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
        y_  = AFF_M_V_2(aff, u - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
        xlo = CEIL(x_ - flatradx_);
Shinya Kitaoka 120a6e
        xhi = FLOOR(x_ + flatradx_);
Shinya Kitaoka 120a6e
        ylo = CEIL(y_ - flatrady_);
Shinya Kitaoka 120a6e
        yhi = FLOOR(y_ + flatrady_);
Shinya Kitaoka 120a6e
        NOT_LESS_THAN(0, xlo);
Shinya Kitaoka 120a6e
        NOT_MORE_THAN(mx, xhi);
Shinya Kitaoka 120a6e
        NOT_LESS_THAN(0, ylo);
Shinya Kitaoka 120a6e
        NOT_MORE_THAN(my, yhi);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
        xlo = std::max(0, (int)xlo_);
Shinya Kitaoka 120a6e
        xhi = std::min(mx, (int)xhi_);
Shinya Kitaoka 120a6e
        ylo = std::max(0, (int)ylo_);
Shinya Kitaoka 120a6e
        yhi = std::min(my, (int)yhi_);
Shinya Kitaoka 120a6e
        for (y = ylo; y <= yhi; y++)
Shinya Kitaoka 120a6e
          for (x                        = xlo; x <= xhi; x++)
Shinya Kitaoka 120a6e
            bufout_gr8[x + y * wrapout] = flatval, count++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      xlo_ += aff.a11;
Shinya Kitaoka 120a6e
      xhi_ += aff.a11;
Shinya Kitaoka 120a6e
      ylo_ += aff.a21;
Shinya Kitaoka 120a6e
      yhi_ += aff.a21;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  delete colval;
Shinya Kitaoka 120a6e
  delete colheight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  topy = 0;
Shinya Kitaoka 120a6e
  /*TCALLOC (nocheight, lx);*/
Shinya Kitaoka 120a6e
  nocheight = new int[lx];
Shinya Kitaoka 120a6e
  memset(nocheight, 0, lx * sizeof(int));
Shinya Kitaoka 120a6e
  out_gr8 = bufout_gr8;
Shinya Kitaoka 120a6e
  for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
    if (out_gr8[x] != GREY_GR8)
Shinya Kitaoka 120a6e
      nocheight[x]++;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      nocheight[x] = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = 0, yflt = colflt; y < ly; y++, yflt++) {
Shinya Kitaoka 120a6e
    for (; topq <= yflt->last; topq++) {
Shinya Kitaoka 120a6e
      xrow[topq] = xrow[topq - nrows];
Shinya Kitaoka 120a6e
      xxx        = xrow[topq];
Shinya Kitaoka 120a6e
      memset(xxx, 0, sizeof(*xxx) * lx); /* 0.0 == nocalc */
Shinya Kitaoka 120a6e
      while (topy < ly - 1 && colnoc[topy].last < topq) {
Shinya Kitaoka 120a6e
        topy++;
Shinya Kitaoka 120a6e
        out_gr8 = bufout_gr8 + topy * wrapout;
Shinya Kitaoka 120a6e
        for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
          if (out_gr8[x] != GREY_GR8)
Shinya Kitaoka 120a6e
            nocheight[x]++;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            nocheight[x] = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (topy < ly && colnoc[topy].first <= topq) {
Shinya Kitaoka 120a6e
        for (x                                = 0; x < lx; x++)
Shinya Kitaoka 120a6e
          if (nocheight[x] < nocdiamy) xxx[x] = 1.0; /* 1.0 == calc */
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        for (x = 0; x < lx; x++) xxx[x] = 1.0; /* 1.0 == calc */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      memset(prow + pmin, 0,
Shinya Kitaoka 120a6e
             sizeof(*prow) * (pmax - pmin + 1)); /* 0.0 == calc */
Shinya Kitaoka 120a6e
      nocwidth = 0;
Shinya Kitaoka 120a6e
      for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
        if (xxx[x])
Shinya Kitaoka 120a6e
          nocwidth = 0;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          nocwidth++;
Shinya Kitaoka 120a6e
          if (nocwidth >= nocdiamx)
Shinya Kitaoka 120a6e
            for (p    = rownoc[x].first; p <= rownoc[x].last; p++)
Shinya Kitaoka 120a6e
              prow[p] = 1.0; /* 1.0 == nocalc */
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      get_prow_gr8(rin, invrot.a11, invrot.a12, invrot.a21, invrot.a22, pmin,
Shinya Kitaoka 120a6e
                   pmax, topq, prow);
Shinya Kitaoka 120a6e
      for (x = 0, xflt = rowflt; x < lx; x++, xflt++)
Shinya Kitaoka 120a6e
        if (xxx[x]) {
Shinya Kitaoka 120a6e
          for (tmp = 0.0, p = xflt->first; p <= xflt->last; p++)
Shinya Kitaoka 120a6e
            tmp += xflt->w[p] * prow[p];
Shinya Kitaoka 120a6e
          xxx[x] = tmp;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    out_gr8 = bufout_gr8 + wrapout * y;
Shinya Kitaoka 120a6e
    for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
      if (out_gr8[x] == GREY_GR8) {
Shinya Kitaoka 120a6e
        for (tmp = 0.0, q = yflt->first; q <= yflt->last; q++)
Shinya Kitaoka 120a6e
          tmp += yflt->w[q] * xrow[q][x];
Shinya Kitaoka 120a6e
        out_gr8[x] = TO8BIT(tmp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // cest_plus_facile (xrow);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (q = 0; q < nrows; q++) delete xrow_base[q];
Shinya Kitaoka 120a6e
  delete xrow_base;
Shinya Kitaoka 120a6e
  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,
Shinya Kitaoka 120a6e
                                    const TAffine &aff, const TAffine &invrot,
Shinya Kitaoka 120a6e
                                    FILTER *rowflt, int pmin, int pmax,
Shinya Kitaoka 120a6e
                                    FILTER *colflt, int qmin, int qmax,
Shinya Kitaoka 120a6e
                                    int nrows, int flatradu, int flatradv,
Shinya Kitaoka 120a6e
                                    double flatradx_, double flatrady_,
Shinya Kitaoka 120a6e
                                    NOCALC *rownoc, int nocdiamx,
Shinya Kitaoka 120a6e
                                    NOCALC *colnoc, int nocdiamy) {
Shinya Kitaoka 120a6e
  FILTER *xflt, *yflt;
Shinya Kitaoka 120a6e
  UCHAR *bufout_gr8, *out_gr8;
Shinya Kitaoka 120a6e
  TPixel *bufin_32, *in_32;
Shinya Kitaoka 120a6e
  float *prow_base, *prow, **xrow_base, **xrow, *xxx, tmp;
Shinya Kitaoka 120a6e
  double x_, y_;
Shinya Kitaoka 120a6e
  int u, v;  //, vw;
Shinya Kitaoka 120a6e
  int p, q;
Shinya Kitaoka 120a6e
  int x, y;
Shinya Kitaoka 120a6e
  int lu, lv, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, mx, my;
Shinya Kitaoka 120a6e
  // int dudp, dudq, dvdp, dvdq;
Shinya Kitaoka 120a6e
  int topq, topy;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  int flatdiamu, flatdiamv;
Shinya Kitaoka 120a6e
  int xlo, xhi, ylo, yhi;
Shinya Kitaoka 120a6e
  int *nocheight;
Shinya Kitaoka 120a6e
  int nocwidth;
Shinya Kitaoka 120a6e
  int i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bufin_32   = (TPixel *)rin->pixels();
Shinya Kitaoka 120a6e
  bufout_gr8 = (UCHAR *)rout->pixels();
Shinya Kitaoka 120a6e
  wrapin     = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout    = rout->getWrap();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  lu        = rin->getLx();
Shinya Kitaoka 120a6e
  mu        = lu - 1;
Shinya Kitaoka 120a6e
  lv        = rin->getLy();
Shinya Kitaoka 120a6e
  mv        = lv - 1;
Shinya Kitaoka 120a6e
  lx        = rout->getLx();
Shinya Kitaoka 120a6e
  mx        = lx - 1;
Shinya Kitaoka 120a6e
  ly        = rout->getLy();
Shinya Kitaoka 120a6e
  my        = ly - 1;
Shinya Kitaoka 120a6e
  prow_base = new float[pmax - pmin + 1];
Shinya Kitaoka 120a6e
  prow      = prow_base - pmin;
Shinya Kitaoka 120a6e
  xrow_base = new MyFloatPtr[qmax - (qmin - nrows) + 1];
Shinya Kitaoka 120a6e
  xrow      = xrow_base - (qmin - nrows);
Shinya Kitaoka 120a6e
  topq      = qmin;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // app = xrow+topq-nrows;
Shinya Kitaoka 120a6e
  i = 0;
Shinya Kitaoka 120a6e
  j = 3;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < nrows; i++) *(xrow + topq - nrows + i) = new float[lx];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // while(app
Shinya Kitaoka 120a6e
  //  *app++ = new float[lx];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  flatdiamu = flatradu * 2 + 1;
Shinya Kitaoka 120a6e
  flatdiamv = flatradv * 2 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = 0; y < ly; y++)
Shinya Kitaoka 120a6e
    memset(bufout_gr8 + y * wrapout, 127, sizeof(UCHAR) * lx);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int count = 0; /* !!!!!!!!!!!!!!!!*/
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int *colheight;
Shinya Kitaoka 120a6e
  UCHAR *colval;
Shinya Kitaoka 120a6e
  int flatcols;
Shinya Kitaoka 120a6e
  UCHAR flatval;
Shinya Kitaoka 120a6e
  double xlo_, xhi_, ylo_, yhi_;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*  TCALLOC (colheight, lu);
Shinya Kitaoka 120a6e
TCALLOC (colval,    lu);*/
Shinya Kitaoka 120a6e
  colheight = new int[lu];
Shinya Kitaoka 120a6e
  // memset(colheight, 0, lu);
Shinya Kitaoka 120a6e
  colval = new UCHAR[lu];
Shinya Kitaoka 120a6e
  // memset(colval, 0, lu);
Shinya Kitaoka 120a6e
  for (u = 0; u < (int)lu; u++) {
Shinya Kitaoka 120a6e
    colheight[u] = 0;
Shinya Kitaoka 120a6e
    colval[u]    = BORDER_GR8;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (v = 0; v < (int)lv; v++) {
Shinya Kitaoka 120a6e
    x_ = affMV1(aff, 0 - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
    y_ = affMV2(aff, 0 - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    xlo_ = tceil(x_ - flatradx_);
Shinya Kitaoka 120a6e
    xhi_ = tfloor(x_ + flatradx_);
Shinya Kitaoka 120a6e
    ylo_ = tceil(y_ - flatrady_);
Shinya Kitaoka 120a6e
    yhi_ = tfloor(y_ + flatrady_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    flatcols = 0;
Shinya Kitaoka 120a6e
    flatval  = BORDER_GR8;
Shinya Kitaoka 120a6e
    for (u = 0, in_32 = bufin_32 + v * wrapin; u < (int)lu; u++, in_32++) {
Shinya Kitaoka 120a6e
      if (grey(*in_32) == colval[u])
Shinya Kitaoka 120a6e
        colheight[u]++;
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        colheight[u] = 1;
Shinya Kitaoka 120a6e
        colval[u]    = grey(*in_32);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (colheight[u] >= flatdiamv)
Shinya Kitaoka 120a6e
        if (colval[u] == flatval)
Shinya Kitaoka 120a6e
          flatcols++;
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          flatcols = 1;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        flatcols = 0;
Shinya Kitaoka 120a6e
      flatval    = colval[u];
Shinya Kitaoka 120a6e
      if (flatcols >= flatdiamu) {
Toshihiro Shimizu 890ddd
#ifdef VECCHIA_MANIERA
Shinya Kitaoka 120a6e
        x_  = AFF_M_V_1(aff, u - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
        y_  = AFF_M_V_2(aff, u - flatradu, v - flatradv);
Shinya Kitaoka 120a6e
        xlo = CEIL(x_ - flatradx_);
Shinya Kitaoka 120a6e
        xhi = FLOOR(x_ + flatradx_);
Shinya Kitaoka 120a6e
        ylo = CEIL(y_ - flatrady_);
Shinya Kitaoka 120a6e
        yhi = FLOOR(y_ + flatrady_);
Shinya Kitaoka 120a6e
        NOT_LESS_THAN(0, xlo);
Shinya Kitaoka 120a6e
        NOT_MORE_THAN(mx, xhi);
Shinya Kitaoka 120a6e
        NOT_LESS_THAN(0, ylo);
Shinya Kitaoka 120a6e
        NOT_MORE_THAN(my, yhi);
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
        xlo = std::max(0, (int)xlo_);
Shinya Kitaoka 120a6e
        xhi = std::min(mx, (int)xhi_);
Shinya Kitaoka 120a6e
        ylo = std::max(0, (int)ylo_);
Shinya Kitaoka 120a6e
        yhi = std::min(my, (int)yhi_);
Shinya Kitaoka 120a6e
        for (y = ylo; y <= yhi; y++)
Shinya Kitaoka 120a6e
          for (x                        = xlo; x <= xhi; x++)
Shinya Kitaoka 120a6e
            bufout_gr8[x + y * wrapout] = flatval, count++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      xlo_ += aff.a11;
Shinya Kitaoka 120a6e
      xhi_ += aff.a11;
Shinya Kitaoka 120a6e
      ylo_ += aff.a21;
Shinya Kitaoka 120a6e
      yhi_ += aff.a21;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  delete colval;
Shinya Kitaoka 120a6e
  delete colheight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  topy = 0;
Shinya Kitaoka 120a6e
  /*TCALLOC (nocheight, lx);*/
Shinya Kitaoka 120a6e
  nocheight = new int[lx];
Shinya Kitaoka 120a6e
  memset(nocheight, 0, lx * sizeof(int));
Shinya Kitaoka 120a6e
  out_gr8 = bufout_gr8;
Shinya Kitaoka 120a6e
  for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
    if (out_gr8[x] != GREY_GR8)
Shinya Kitaoka 120a6e
      nocheight[x]++;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      nocheight[x] = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (y = 0, yflt = colflt; y < ly; y++, yflt++) {
Shinya Kitaoka 120a6e
    for (; topq <= yflt->last; topq++) {
Shinya Kitaoka 120a6e
      xrow[topq] = xrow[topq - nrows];
Shinya Kitaoka 120a6e
      xxx        = xrow[topq];
Shinya Kitaoka 120a6e
      memset(xxx, 0, sizeof(*xxx) * lx); /* 0.0 == nocalc */
Shinya Kitaoka 120a6e
      while (topy < ly - 1 && colnoc[topy].last < topq) {
Shinya Kitaoka 120a6e
        topy++;
Shinya Kitaoka 120a6e
        out_gr8 = bufout_gr8 + topy * wrapout;
Shinya Kitaoka 120a6e
        for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
          if (out_gr8[x] != GREY_GR8)
Shinya Kitaoka 120a6e
            nocheight[x]++;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            nocheight[x] = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (topy < ly && colnoc[topy].first <= topq) {
Shinya Kitaoka 120a6e
        for (x                                = 0; x < lx; x++)
Shinya Kitaoka 120a6e
          if (nocheight[x] < nocdiamy) xxx[x] = 1.0; /* 1.0 == calc */
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        for (x = 0; x < lx; x++) xxx[x] = 1.0; /* 1.0 == calc */
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      memset(prow + pmin, 0,
Shinya Kitaoka 120a6e
             sizeof(*prow) * (pmax - pmin + 1)); /* 0.0 == calc */
Shinya Kitaoka 120a6e
      nocwidth = 0;
Shinya Kitaoka 120a6e
      for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
        if (xxx[x])
Shinya Kitaoka 120a6e
          nocwidth = 0;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          nocwidth++;
Shinya Kitaoka 120a6e
          if (nocwidth >= nocdiamx)
Shinya Kitaoka 120a6e
            for (p    = rownoc[x].first; p <= rownoc[x].last; p++)
Shinya Kitaoka 120a6e
              prow[p] = 1.0; /* 1.0 == nocalc */
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      get_prow_gr8(rin, invrot.a11, invrot.a12, invrot.a21, invrot.a22, pmin,
Shinya Kitaoka 120a6e
                   pmax, topq, prow);
Shinya Kitaoka 120a6e
      for (x = 0, xflt = rowflt; x < lx; x++, xflt++)
Shinya Kitaoka 120a6e
        if (xxx[x]) {
Shinya Kitaoka 120a6e
          for (tmp = 0.0, p = xflt->first; p <= xflt->last; p++)
Shinya Kitaoka 120a6e
            tmp += xflt->w[p] * prow[p];
Shinya Kitaoka 120a6e
          xxx[x] = tmp;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    out_gr8 = bufout_gr8 + wrapout * y;
Shinya Kitaoka 120a6e
    for (x = 0; x < lx; x++)
Shinya Kitaoka 120a6e
      if (out_gr8[x] == GREY_GR8) {
Shinya Kitaoka 120a6e
        for (tmp = 0.0, q = yflt->first; q <= yflt->last; q++)
Shinya Kitaoka 120a6e
          tmp += yflt->w[q] * xrow[q][x];
Shinya Kitaoka 120a6e
        out_gr8[x] = TO8BIT(tmp);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // cest_plus_facile (xrow);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (q = 0; q < nrows; q++) delete xrow_base[q];
Shinya Kitaoka 120a6e
  delete xrow_base;
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
                       const TAffine &aff, TRop::ResampleFilterType flt_type,
Shinya Kitaoka 120a6e
                       double blur) {
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
Shinya Kitaoka 120a6e
  static TRop::ResampleFilterType current_flt_type = TRop::None;
Shinya Kitaoka 120a6e
  static std::unique_ptr<short[]> filter_array;</short[]>
Shinya Kitaoka 120a6e
  static short *filter = 0;
Shinya Kitaoka 120a6e
  static int min_filter_fg, max_filter_fg;
Shinya Kitaoka 120a6e
  static int filter_array_size = 0;
Shinya Kitaoka 120a6e
  static int n_pix             = 0;
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_g;</int[]>
Shinya Kitaoka 120a6e
  static int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  std::unique_ptr<short[]> filter_array;</short[]>
Shinya Kitaoka 120a6e
  short *filter = 0;
Shinya Kitaoka 120a6e
  int min_filter_fg, max_filter_fg;
Shinya Kitaoka 120a6e
  int filter_array_size = 0;
Shinya Kitaoka 120a6e
  int n_pix             = 0;
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_g;</int[]>
Shinya Kitaoka 120a6e
  int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  int filter_st_radius;
Shinya Kitaoka 120a6e
  int filter_fg_radius;
Shinya Kitaoka 120a6e
  int filter_size;
Shinya Kitaoka 120a6e
  int f;
Shinya Kitaoka 120a6e
  double s_;
Shinya Kitaoka 120a6e
  double weight_;
Shinya Kitaoka 120a6e
  int weight;
Shinya Kitaoka 120a6e
  TAffine aff_uv2xy;
Shinya Kitaoka 120a6e
  TAffine aff_xy2uv;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2xy;
Shinya Kitaoka 120a6e
  TAffine aff0_xy2st;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2st;
Shinya Kitaoka 120a6e
  TAffine aff0_st2fg;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2fg;
Shinya Kitaoka 120a6e
  TAffine aff0_fg2uv;
Shinya Kitaoka 120a6e
  double scale_x, scale_y;
Shinya Kitaoka 120a6e
  double inv_blur;
Shinya Kitaoka 120a6e
  int max_n_pix;
Shinya Kitaoka 120a6e
  double min_pix_out_u_, min_pix_out_v_;
Shinya Kitaoka 120a6e
  double max_pix_out_u_, max_pix_out_v_;
Shinya Kitaoka 120a6e
  int min_pix_ref_u, min_pix_ref_v;
Shinya Kitaoka 120a6e
  int max_pix_ref_u, max_pix_ref_v;
Shinya Kitaoka 120a6e
  int cur_pix_ref_u, cur_pix_ref_v;
Shinya Kitaoka 120a6e
  double cur_pix_ref_f_, cur_pix_ref_g_;
Shinya Kitaoka 120a6e
  int cur_pix_ref_f, cur_pix_ref_g;
Shinya Kitaoka 120a6e
  double min_ref_out_f_, min_ref_out_g_;
Shinya Kitaoka 120a6e
  double max_ref_out_f_, max_ref_out_g_;
Shinya Kitaoka 120a6e
  int min_ref_out_f, min_ref_out_g;
Shinya Kitaoka 120a6e
  int max_ref_out_f, max_ref_out_g;
Shinya Kitaoka 120a6e
  int min_pix_ref_f, min_pix_ref_g;
Shinya Kitaoka 120a6e
  int max_pix_ref_f, max_pix_ref_g;
Shinya Kitaoka 120a6e
  int min_pix_out_f, min_pix_out_g;
Shinya Kitaoka 120a6e
  int max_pix_out_f, max_pix_out_g;
Shinya Kitaoka 120a6e
  int min_pix_out_fg;
Shinya Kitaoka 120a6e
  int max_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(flt_type != TRop::None);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the filter radius in the st and fx references
Shinya Kitaoka 120a6e
  filter_st_radius = get_filter_radius(flt_type);
Shinya Kitaoka 120a6e
  filter_fg_radius = filter_st_radius * FILTER_RESOLUTION;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Retrieve the transformation affines among the involved references
Shinya Kitaoka 120a6e
  // NOTE: The 0.5 translation is needed in order to make the later
Shinya Kitaoka 120a6e
  // resample_main procedures work with pixel centers.
Shinya Kitaoka 120a6e
  aff_uv2xy  = aff * TTranslation(0.5, 0.5);
Shinya Kitaoka 120a6e
  aff0_uv2xy = aff_uv2xy.place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
  aff_xy2uv  = aff_uv2xy.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Consider the norm of (1,0) and (0,1) images.
Shinya Kitaoka 120a6e
  scale_x = sqrt(sq(aff_uv2xy.a11) + sq(aff_uv2xy.a12));
Shinya Kitaoka 120a6e
  scale_y = sqrt(sq(aff_uv2xy.a21) + sq(aff_uv2xy.a22));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Inserting the following scale will make shrinks look smooth.
Shinya Kitaoka 120a6e
  aff0_xy2st = TScale((scale_x > 1.0) ? 1.0 / scale_x : 1.0,
Shinya Kitaoka 120a6e
                      (scale_y > 1.0) ? 1.0 / scale_y : 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (blur > 1.0)  // Consider the blur as a scale in the filter reference
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    inv_blur   = 1.0 / blur;
Shinya Kitaoka 120a6e
    aff0_xy2st = TScale(inv_blur, inv_blur) * aff0_xy2st;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  aff0_uv2st = aff0_xy2st * aff0_uv2xy;
Shinya Kitaoka 120a6e
  aff0_st2fg = TScale(FILTER_RESOLUTION, FILTER_RESOLUTION);
Shinya Kitaoka 120a6e
  aff0_uv2fg = aff0_st2fg * aff0_uv2st;
Shinya Kitaoka 120a6e
  aff0_fg2uv = aff0_uv2fg.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Take the pre-image of the filter mask in uv coordinates. This is where
Shinya Kitaoka 120a6e
  // input pixels will be taken to find an output one.
Shinya Kitaoka 120a6e
  minmax(-filter_fg_radius, -filter_fg_radius, filter_fg_radius,
Shinya Kitaoka 120a6e
         filter_fg_radius, aff0_fg2uv, min_pix_out_u_, min_pix_out_v_,
Shinya Kitaoka 120a6e
         max_pix_out_u_, max_pix_out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Adjust them to integer coordinates. The intent here is that
Shinya Kitaoka 120a6e
  // of isolating their fractionary part - furthermore, we'll take
Shinya Kitaoka 120a6e
  // the *opposites* of fractionary parts (explained later).
Shinya Kitaoka 120a6e
  // NOTE: We'll assume we want to include in the filter mask all
Shinya Kitaoka 120a6e
  //*integer positions around a fractionary displacement of the origin*;
Shinya Kitaoka 120a6e
  // so the approximations below are stricly necessary.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_pix_ref_u = intLE(min_pix_out_u_);
Shinya Kitaoka 120a6e
  min_pix_ref_v = intLE(min_pix_out_v_);
Shinya Kitaoka 120a6e
  max_pix_ref_u = intGE(max_pix_out_u_);
Shinya Kitaoka 120a6e
  max_pix_ref_v = intGE(max_pix_out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (blur <= 1.0) {
Shinya Kitaoka 120a6e
    // If the blur radius has sub-pixel width
Shinya Kitaoka 120a6e
    if (aff_uv2xy.a12 == 0.0 && aff_uv2xy.a21 == 0.0) {
Shinya Kitaoka 120a6e
      // And it's the sole scales case
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a11 == 1.0 && isInt(aff_uv2xy.a13 - 0.5)) {
Shinya Kitaoka 120a6e
        // And the x mapping is bijective, then prevent any filtering.
Shinya Kitaoka 120a6e
        min_pix_ref_u = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_u = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a22 == 1.0 && isInt(aff_uv2xy.a23 - 0.5)) {
Shinya Kitaoka 120a6e
        // And the y mapping is bijective ...
Shinya Kitaoka 120a6e
        min_pix_ref_v = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_v = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (aff_uv2xy.a11 == 0.0 && aff_uv2xy.a22 == 0.0) {
Shinya Kitaoka 120a6e
      // The mirrored version of the one above
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a12 == 1.0 && isInt(aff_uv2xy.a13 - 0.5)) {
Shinya Kitaoka 120a6e
        min_pix_ref_v = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_v = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a21 == 1.0 && isInt(aff_uv2xy.a23 - 0.5)) {
Shinya Kitaoka 120a6e
        min_pix_ref_u = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_u = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Take the number of pixels involved in the filter (uv reference)
Shinya Kitaoka 120a6e
  max_n_pix =
Shinya Kitaoka 120a6e
      (max_pix_ref_u - min_pix_ref_u + 1) * (max_pix_ref_v - min_pix_ref_v + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (max_n_pix > current_max_n_pix) {
Shinya Kitaoka 120a6e
    current_max_n_pix = max_n_pix;
Shinya Kitaoka 120a6e
    pix_ref_u.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_v.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_f.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_g.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    assert(pix_ref_u && pix_ref_v && pix_ref_f && pix_ref_g);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build the image of fractionary domain from the uv to fg reference
Shinya Kitaoka 120a6e
  minmax(-1, -1, 0, 0, aff0_uv2fg, min_ref_out_f_, min_ref_out_g_,
Shinya Kitaoka 120a6e
         max_ref_out_f_, max_ref_out_g_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_ref_out_f = tround(min_ref_out_f_);
Shinya Kitaoka 120a6e
  min_ref_out_g = tround(min_ref_out_g_);
Shinya Kitaoka 120a6e
  max_ref_out_f = tround(max_ref_out_f_);
Shinya Kitaoka 120a6e
  max_ref_out_g = tround(max_ref_out_g_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Remember that negative fractionary parts must be subtracted from their
Shinya Kitaoka 120a6e
  // integer counterparts
Shinya Kitaoka 120a6e
  min_pix_ref_f = -filter_fg_radius - max_ref_out_f;
Shinya Kitaoka 120a6e
  min_pix_ref_g = -filter_fg_radius - max_ref_out_g;
Shinya Kitaoka 120a6e
  max_pix_ref_f = filter_fg_radius - min_ref_out_f;
Shinya Kitaoka 120a6e
  max_pix_ref_g = filter_fg_radius - min_ref_out_g;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_pix_out_f = c_maxint;
Shinya Kitaoka 120a6e
  min_pix_out_g = c_maxint;
Shinya Kitaoka 120a6e
  max_pix_out_f = c_minint;
Shinya Kitaoka 120a6e
  max_pix_out_g = c_minint;
Shinya Kitaoka 120a6e
  n_pix         = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!pix_ref_u || !pix_ref_v || !pix_ref_f || !pix_ref_g) {
Shinya Kitaoka 120a6e
    throw TRopException(
Shinya Kitaoka 120a6e
        "tresample.cpp line2640  function rop_resample_rgbm() : alloc pix_ref "
Shinya Kitaoka 120a6e
        "failed");
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Build the *integer* part of the fg images of those coordinates inside the
Shinya Kitaoka 120a6e
  // uv filter bounds.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NOTE: Doing so reduces the execution time for the later resample_main
Shinya Kitaoka 120a6e
  // procedure -
Shinya Kitaoka 120a6e
  // the idea is the following:
Shinya Kitaoka 120a6e
  //  We want to build the output pixel (x,y) obtained from the source image
Shinya Kitaoka 120a6e
  //  through A.
Shinya Kitaoka 120a6e
  //  Then, we find (u,v) = (A^-1) * (x,y) = ([u],[v]) + ({u},{v}), where [] and
Shinya Kitaoka 120a6e
  //  {}
Shinya Kitaoka 120a6e
  //  denote integer and fractionary parts.
Shinya Kitaoka 120a6e
  //  Now, the convolution positions on fg for (u,v) can be thought of being
Shinya Kitaoka 120a6e
  //  calculated by taking
Shinya Kitaoka 120a6e
  //  images of integer displacements of (u,v). So, their calculation is
Shinya Kitaoka 120a6e
  //  definitely *not* directly
Shinya Kitaoka 120a6e
  //  dependent on the fractionary part of (u,v) - that is, the (i,j)th
Shinya Kitaoka 120a6e
  //  displacement position of FG(u,v)
Shinya Kitaoka 120a6e
  //  is:
Shinya Kitaoka 120a6e
  //          FG([u]+i,[v]+j) = FG(u+i,v+j) - FG({u},{v}) = FG(i,j) -
Shinya Kitaoka 120a6e
  //          FG({u},{v});
Shinya Kitaoka 120a6e
  //
Shinya Kitaoka 120a6e
  //  where it is assumed that FG(u,v) = (0,0), since the filter is to be
Shinya Kitaoka 120a6e
  //  considered centered on (u,v).
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (cur_pix_ref_v = min_pix_ref_v; cur_pix_ref_v <= max_pix_ref_v;
Shinya Kitaoka 120a6e
       cur_pix_ref_v++)
Shinya Kitaoka 120a6e
    for (cur_pix_ref_u = min_pix_ref_u; cur_pix_ref_u <= max_pix_ref_u;
Shinya Kitaoka 120a6e
         cur_pix_ref_u++) {
Shinya Kitaoka 120a6e
      // Get the image of current uv position
Shinya Kitaoka 120a6e
      cur_pix_ref_f_ = affMV1(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Shinya Kitaoka 120a6e
      cur_pix_ref_g_ = affMV2(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // And round it to the closest integer in fg
Shinya Kitaoka 120a6e
      cur_pix_ref_f = tround(cur_pix_ref_f_);
Shinya Kitaoka 120a6e
      cur_pix_ref_g = tround(cur_pix_ref_g_);
Shinya Kitaoka 120a6e
      if (min_pix_ref_f <= cur_pix_ref_f && cur_pix_ref_f <= max_pix_ref_f &&
Shinya Kitaoka 120a6e
          min_pix_ref_g <= cur_pix_ref_g && cur_pix_ref_g <= max_pix_ref_g) {
Shinya Kitaoka 120a6e
        pix_ref_u[n_pix] = cur_pix_ref_u;
Shinya Kitaoka 120a6e
        pix_ref_v[n_pix] = cur_pix_ref_v;
Shinya Kitaoka 120a6e
        pix_ref_f[n_pix] = cur_pix_ref_f;
Shinya Kitaoka 120a6e
        pix_ref_g[n_pix] = cur_pix_ref_g;
Shinya Kitaoka 120a6e
        notMoreThan(cur_pix_ref_f + min_ref_out_f,
Shinya Kitaoka 120a6e
                    min_pix_out_f);  // cur_pix_ref > min_pix_out - min_ref_out
Shinya Kitaoka 120a6e
        notMoreThan(cur_pix_ref_g + min_ref_out_g, min_pix_out_g);
Shinya Kitaoka 120a6e
        notLessThan(cur_pix_ref_f + max_ref_out_f,
Shinya Kitaoka 120a6e
                    max_pix_out_f);  // cur_pix_ref < max_pix_out - max_ref_out
Shinya Kitaoka 120a6e
        notLessThan(cur_pix_ref_g + max_ref_out_g, max_pix_out_g);
Shinya Kitaoka 120a6e
        n_pix++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  assert(n_pix > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Shinya Kitaoka 120a6e
  if (flt_type != current_flt_type) {
Shinya Kitaoka 120a6e
    current_flt_type = flt_type;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Build a sufficient filter weights array
Shinya Kitaoka 120a6e
    min_filter_fg = -filter_fg_radius - FILTER_RESOLUTION * 3 / 2;  //???
Shinya Kitaoka 120a6e
    max_filter_fg = filter_fg_radius + FILTER_RESOLUTION * 3 / 2;
Shinya Kitaoka 120a6e
    filter_size   = max_filter_fg - min_filter_fg + 1;
Shinya Kitaoka 120a6e
    if (filter_size > filter_array_size)  // For the static vars case...
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      filter_array.reset(new short[filter_size]);
Shinya Kitaoka 120a6e
      assert(filter_array);
Shinya Kitaoka 120a6e
      filter_array_size = filter_size;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    filter = filter_array.get() - min_filter_fg;  // Take the position
Shinya Kitaoka 120a6e
                                                  // corresponding to fg's (0,0)
Shinya Kitaoka 120a6e
                                                  // in the array
Shinya Kitaoka 120a6e
    filter[0] = MAX_FILTER_VAL;
Shinya Kitaoka 120a6e
    for (f = 1, s_ = 1.0 / FILTER_RESOLUTION; f < filter_fg_radius;
Shinya Kitaoka 120a6e
         f++, s_ += 1.0 / FILTER_RESOLUTION) {
Shinya Kitaoka 120a6e
      // Symmetrically build the array
Shinya Kitaoka 120a6e
      weight_    = get_filter_value(flt_type, s_) * (double)MAX_FILTER_VAL;
Shinya Kitaoka 120a6e
      weight     = tround(weight_);
Shinya Kitaoka 120a6e
      filter[f]  = weight;
Shinya Kitaoka 120a6e
      filter[-f] = weight;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (f = filter_fg_radius; f <= max_filter_fg; f++) filter[f] = 0;
Shinya Kitaoka 120a6e
    for (f = -filter_fg_radius; f >= min_filter_fg; f--) filter[f] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Considering the bounding square in fg
Shinya Kitaoka 120a6e
  min_pix_out_fg = std::min(min_pix_out_f, min_pix_out_g);
Shinya Kitaoka 120a6e
  max_pix_out_fg = std::max(max_pix_out_f, max_pix_out_g);
Shinya Kitaoka 120a6e
  if (min_pix_out_fg < min_filter_fg || max_pix_out_fg > max_filter_fg) {
Shinya Kitaoka 120a6e
    // Reallocate the filter... and so on...
Shinya Kitaoka 120a6e
    filter_size = max_pix_out_fg - min_pix_out_fg + 1;
Shinya Kitaoka 120a6e
    if (filter_size > filter_array_size) {
Shinya Kitaoka 120a6e
      // controllare!!
Shinya Kitaoka 120a6e
      // TREALLOC (filter_array, filter_size)
Shinya Kitaoka 120a6e
      filter_array.reset(new short[filter_size]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      assert(filter_array);
Shinya Kitaoka 120a6e
      filter_array_size = filter_size;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    filter = filter_array.get() - min_filter_fg;
Shinya Kitaoka 120a6e
    if (min_pix_out_fg < min_filter_fg) {
Shinya Kitaoka 120a6e
      int delta = min_filter_fg - min_pix_out_fg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (f              = max_filter_fg; f >= min_filter_fg; f--)
Shinya Kitaoka 120a6e
        filter[f + delta] = filter[f];
Shinya Kitaoka 120a6e
      filter += delta;
Shinya Kitaoka 120a6e
      for (f = min_filter_fg - 1; f >= min_pix_out_fg; f--) filter[f] = 0;
Shinya Kitaoka 120a6e
      min_filter_fg = min_pix_out_fg;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (max_pix_out_fg > max_filter_fg) {
Shinya Kitaoka 120a6e
      for (f = max_filter_fg + 1; f <= max_pix_out_fg; f++) filter[f] = 0;
Shinya Kitaoka 120a6e
      max_filter_fg = max_pix_out_fg;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  if ((TSystem::getCPUExtensions() & TSystem::CpuSupportsSse2) &&
Shinya Kitaoka 120a6e
      T::maxChannelValue == 255)
Shinya Kitaoka 120a6e
    resample_main_rgbm_SSE2<t>(rout, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u,</t>
Shinya Kitaoka 120a6e
                               min_pix_ref_v, max_pix_ref_u, max_pix_ref_v,
Shinya Kitaoka 120a6e
                               n_pix, pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 120a6e
                               pix_ref_f.get(), pix_ref_g.get(), filter);
Shinya Kitaoka 120a6e
  else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
      if (n_pix >= 512 || T::maxChannelValue > 255)
Shinya Kitaoka 120a6e
    resample_main_rgbm<t, tint64="">(</t,>
Shinya Kitaoka 120a6e
        rout, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
        max_pix_ref_u, max_pix_ref_v, n_pix, pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 120a6e
        pix_ref_f.get(), pix_ref_g.get(), filter);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    resample_main_rgbm<t, tint32="">(</t,>
Shinya Kitaoka 120a6e
        rout, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
        max_pix_ref_u, max_pix_ref_v, n_pix, pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 120a6e
        pix_ref_f.get(), pix_ref_g.get(), filter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
static void free_filter(FILTER *filter, int lx) {
Shinya Kitaoka 120a6e
  for (--lx; lx >= 0; lx--)
Shinya Kitaoka 120a6e
    if (filter[lx].w_base) delete (filter[lx].w_base);
Shinya Kitaoka 120a6e
  delete (filter);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_resample(TRasterGR8P rout, const TRasterGR8P &rin, const TAffine &aff,
Shinya Kitaoka 120a6e
                 TRop::ResampleFilterType flt_type, double blur) {
Shinya Kitaoka 120a6e
  double jacob;
Shinya Kitaoka 120a6e
  double s11, s22, s13, s23;
Shinya Kitaoka 120a6e
  FILTER *rowf, *colf;
Shinya Kitaoka 120a6e
  NOCALC *rown, *coln;
Shinya Kitaoka 120a6e
  int pmin, pmax, qmin, qmax;
Shinya Kitaoka 120a6e
  int nrows, dummy;
Shinya Kitaoka 120a6e
  double negradu_, negradv_, posradu_, posradv_;
Shinya Kitaoka 120a6e
  double negradx_, negrady_, posradx_, posrady_;
Shinya Kitaoka 120a6e
  int nocdiamx, nocdiamy;
Shinya Kitaoka 120a6e
  double rad_x, rad_y;
Shinya Kitaoka 120a6e
  TAffine rot, scale, invrot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    rout->fill(TPixelGR8::Black);  // Black_rgbm
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterGR8P routGR8 = rout, rinGR8 = rin;
Shinya Kitaoka 120a6e
  if (routGR8 && rinGR8) {
Shinya Kitaoka 120a6e
    jacob = fabs(aff.det());
Shinya Kitaoka 120a6e
    if (jacob == 0.0)
Shinya Kitaoka 120a6e
      throw TRopException("AFFINE transformation has zero determinant");
Shinya Kitaoka 120a6e
    if (jacob < 1E-30)
Shinya Kitaoka 120a6e
      throw TRopException(
Shinya Kitaoka 120a6e
          "AFFINE transformation has (nearly) zero determinant");
Shinya Kitaoka 120a6e
    s11 = sqrt(jacob); /* provvisorio */
Shinya Kitaoka 120a6e
    s22 = s11;
Shinya Kitaoka 120a6e
    s13 = aff.a13;
Shinya Kitaoka 120a6e
    s23 = aff.a23;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // rot = aff_place (0.0, 0.0, 0.0, 0.0, TScale(1/s11,
Shinya Kitaoka 120a6e
    // 1/s22)*aff);//eventualmente invertire ordine
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // scale = aff_place (0.0, 0.0, s13, s23, TScale(s11, s22));
Shinya Kitaoka 120a6e
    scale  = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Shinya Kitaoka 120a6e
    invrot = rot.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                         rad_x, pmin, pmax, dummy);
Shinya Kitaoka 120a6e
    colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                         rad_y, qmin, qmax, nrows);
Shinya Kitaoka 120a6e
    rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                         pmin, pmax, nocdiamx);
Shinya Kitaoka 120a6e
    coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                         qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Shinya Kitaoka 120a6e
    malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Shinya Kitaoka 120a6e
    CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TAffine aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
    TAffine inv_0 = aff_0.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    minmax(-0.5, -0.5, 0.5, 0.5, aff_0, negradx_, negrady_, posradx_, posrady_);
Shinya Kitaoka 120a6e
    double flatradx_ = posradx_;
Shinya Kitaoka 120a6e
    double flatrady_ = posrady_;
Shinya Kitaoka 120a6e
    minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x,
Shinya Kitaoka 120a6e
           posrady_ + rad_y, inv_0, negradu_, negradv_, posradu_, posradv_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int flatradu = tceil(posradu_) - 1;
Shinya Kitaoka 120a6e
    int flatradv = tceil(posradv_) - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    rop_resample_gr8(rin, rout, aff, invrot, rowf, pmin, pmax, colf, qmin, qmax,
Shinya Kitaoka 120a6e
                     nrows, flatradu, flatradv, flatradx_, flatrady_, rown,
Shinya Kitaoka 120a6e
                     nocdiamx, coln, nocdiamy);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // free_nocalc (coln);
Shinya Kitaoka 120a6e
    if (coln) delete (coln);
Shinya Kitaoka 120a6e
    // free_nocalc (rown);
Shinya Kitaoka 120a6e
    if (rown) delete (rown);
Shinya Kitaoka 120a6e
    free_filter(colf, rout->getLy());
Shinya Kitaoka 120a6e
    free_filter(rowf, rout->getLx());
Shinya Kitaoka 120a6e
    //----NON GESTIAMO ANCORA EXTRA BUFFER
Shinya Kitaoka 120a6e
    // rop_resample_extra (rin, rout, aff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void do_resample(TRasterGR8P rout, const TRaster32P &rin, const TAffine &aff,
Shinya Kitaoka 120a6e
                 TRop::ResampleFilterType flt_type, double blur) {
Shinya Kitaoka 120a6e
  double jacob;
Shinya Kitaoka 120a6e
  double s11, s22, s13, s23;
Shinya Kitaoka 120a6e
  FILTER *rowf, *colf;
Shinya Kitaoka 120a6e
  NOCALC *rown, *coln;
Shinya Kitaoka 120a6e
  int pmin, pmax, qmin, qmax;
Shinya Kitaoka 120a6e
  int nrows, dummy;
Shinya Kitaoka 120a6e
  double negradu_, negradv_, posradu_, posradv_;
Shinya Kitaoka 120a6e
  double negradx_, negrady_, posradx_, posrady_;
Shinya Kitaoka 120a6e
  int nocdiamx, nocdiamy;
Shinya Kitaoka 120a6e
  double rad_x, rad_y;
Shinya Kitaoka 120a6e
  TAffine rot, scale, invrot;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    rout->fill(TPixelGR8::Black);  // Black_rgbm
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  jacob = fabs(aff.det());
Shinya Kitaoka 120a6e
  if (jacob == 0.0)
Shinya Kitaoka 120a6e
    throw TRopException("AFFINE transformation has zero determinant");
Shinya Kitaoka 120a6e
  if (jacob < 1E-30)
Shinya Kitaoka 120a6e
    throw TRopException("AFFINE transformation has (nearly) zero determinant");
Shinya Kitaoka 120a6e
  s11 = sqrt(jacob); /* provvisorio */
Shinya Kitaoka 120a6e
  s22 = s11;
Shinya Kitaoka 120a6e
  s13 = aff.a13;
Shinya Kitaoka 120a6e
  s23 = aff.a23;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // rot = aff_place (0.0, 0.0, 0.0, 0.0, TScale(1/s11,
Shinya Kitaoka 120a6e
  // 1/s22)*aff);//eventualmente invertire ordine
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // scale = aff_place (0.0, 0.0, s13, s23, TScale(s11, s22));
Shinya Kitaoka 120a6e
  scale  = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Shinya Kitaoka 120a6e
  invrot = rot.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                       rad_x, pmin, pmax, dummy);
Shinya Kitaoka 120a6e
  colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                       rad_y, qmin, qmax, nrows);
Shinya Kitaoka 120a6e
  rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                       pmin, pmax, nocdiamx);
Shinya Kitaoka 120a6e
  coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                       qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Shinya Kitaoka 120a6e
  malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Shinya Kitaoka 120a6e
  CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TAffine aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
  TAffine inv_0 = aff_0.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  minmax(-0.5, -0.5, 0.5, 0.5, aff_0, negradx_, negrady_, posradx_, posrady_);
Shinya Kitaoka 120a6e
  double flatradx_ = posradx_;
Shinya Kitaoka 120a6e
  double flatrady_ = posrady_;
Shinya Kitaoka 120a6e
  minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y,
Shinya Kitaoka 120a6e
         inv_0, negradu_, negradv_, posradu_, posradv_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int flatradu = tceil(posradu_) - 1;
Shinya Kitaoka 120a6e
  int flatradv = tceil(posradv_) - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rop_resample_rgbm32_gr8(rin, rout, aff, invrot, rowf, pmin, pmax, colf, qmin,
Shinya Kitaoka 120a6e
                          qmax, nrows, flatradu, flatradv, flatradx_, flatrady_,
Shinya Kitaoka 120a6e
                          rown, nocdiamx, coln, nocdiamy);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // free_nocalc (coln);
Shinya Kitaoka 120a6e
  if (coln) delete (coln);
Shinya Kitaoka 120a6e
  // free_nocalc (rown);
Shinya Kitaoka 120a6e
  if (rown) delete (rown);
Shinya Kitaoka 120a6e
  free_filter(colf, rout->getLy());
Shinya Kitaoka 120a6e
  free_filter(rowf, rout->getLx());
Shinya Kitaoka 120a6e
  //----NON GESTIAMO ANCORA EXTRA BUFFER
Shinya Kitaoka 120a6e
  // rop_resample_extra (rin, rout, aff);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // 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>
Shinya Kitaoka 120a6e
void do_resample(TRasterPT<t> rout, const TRasterPT<t> &rin, const TAffine &aff,</t></t>
Shinya Kitaoka 120a6e
                 TRop::ResampleFilterType flt_type, double blur)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
#ifdef ALTRI_TIPI_DI_RASTER
Shinya Kitaoka 120a6e
  double jacob;
Shinya Kitaoka 120a6e
  double s11, s22, s13, s23;
Shinya Kitaoka 120a6e
  FILTER *rowf, *colf;
Shinya Kitaoka 120a6e
  NOCALC *rown, *coln;
Shinya Kitaoka 120a6e
  int pmin, pmax, qmin, qmax;
Shinya Kitaoka 120a6e
  int nrows, dummy;
Shinya Kitaoka 120a6e
  double negradu_, negradv_, posradu_, posradv_;
Shinya Kitaoka 120a6e
  double negradx_, negrady_, posradx_, posrady_;
Shinya Kitaoka 120a6e
  int nocdiamx, nocdiamy;
Shinya Kitaoka 120a6e
  double rad_x, rad_y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    rout->fill(T::Black);  // Black_rgbm
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRasterPT<t> rout_ = rout, rin_ = rin;</t>
Shinya Kitaoka 120a6e
  if (rout_ && rin_) {
Shinya Kitaoka 120a6e
    rop_resample_rgbm<t>(rout, rin, aff, flt_type, blur);</t>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    throw TRopException("unsupported pixel type");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef ALTRI_TIPI_DI_RASTER
Shinya Kitaoka 120a6e
  jacob = fabs(aff.det());
Shinya Kitaoka 120a6e
  if (jacob == 0.0)
Shinya Kitaoka 120a6e
    throw TRopException("AFFINE transformation has zero determinant");
Shinya Kitaoka 120a6e
  if (jacob < 1E-30)
Shinya Kitaoka 120a6e
    throw TRopException("AFFINE transformation has (nearly) zero determinant");
Shinya Kitaoka 120a6e
  s11 = sqrt(jacob); /* provvisorio */
Shinya Kitaoka 120a6e
  s22 = s11;
Shinya Kitaoka 120a6e
  s13 = aff.a13;
Shinya Kitaoka 120a6e
  s23 = aff.a23;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rot = (TScale(1 / s11, 1 / s22) * aff).place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scale  = TScale(s11, s22).place(0.0, 0.0, s13, s23);
Shinya Kitaoka 120a6e
  invrot = rot.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rowf = create_filter(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                       rad_x, pmin, pmax, dummy);
Shinya Kitaoka 120a6e
  colf = create_filter(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                       rad_y, qmin, qmax, nrows);
Shinya Kitaoka 120a6e
  rown = create_nocalc(flt_type, blur, scale.a11, scale.a13, rout->getLx(),
Shinya Kitaoka 120a6e
                       pmin, pmax, nocdiamx);
Shinya Kitaoka 120a6e
  coln = create_nocalc(flt_type, blur, scale.a22, scale.a23, rout->getLy(),
Shinya Kitaoka 120a6e
                       qmin, qmax, nocdiamy);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef DBMALLOC
Shinya Kitaoka 120a6e
  malloc_chain_check(TRUE);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
#ifdef MEMLEAK
Shinya Kitaoka 120a6e
  CheckMemory();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  aff_0 = aff.place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
  inv_0 = aff_0.inv();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  minmax(-0.5, -0.5, 0.5, 0.5, aff_0, negradx_, negrady_, posradx_, posrady_);
Shinya Kitaoka 120a6e
  minmax(negradx_ - rad_x, negrady_ - rad_y, posradx_ + rad_x, posrady_ + rad_y,
Shinya Kitaoka 120a6e
         inv_0, negradu_, negradv_, posradu_, posradv_);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (coln) delete (coln);
Shinya Kitaoka 120a6e
  if (rown) delete (rown);
Shinya Kitaoka 120a6e
  free_filter(colf, rout->getLy());
Shinya Kitaoka 120a6e
  free_filter(rowf, rout->getLx());
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
typedef struct {
Shinya Kitaoka 120a6e
  TUINT32 val;
Shinya Kitaoka 120a6e
  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
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
void do_resample(TRasterCM32P rout, const TRasterCM32P &rin,
Shinya Kitaoka 120a6e
                 const TAffine &aff) {
Shinya Kitaoka 120a6e
  TAffine inv;
Shinya Kitaoka 120a6e
  int lx, ly, mx, my;
Shinya Kitaoka 120a6e
  int lu, lv, mu, mv;
Shinya Kitaoka 120a6e
  int x, y, u, v;
Shinya Kitaoka 120a6e
  double u_0, v_0, u_, v_;
Shinya Kitaoka 120a6e
  double fu, fv, gu, gv;
Shinya Kitaoka 120a6e
  int i, j;
Shinya Kitaoka 120a6e
  int wrapin, wrapout;
Shinya Kitaoka 120a6e
  TUINT32 *bufin_tcm, *bufout_tcm;
Shinya Kitaoka 120a6e
  TUINT32 *in_tcm, *out_tcm;
Shinya Kitaoka 120a6e
  TUINT32 tcm[4];
Shinya Kitaoka 120a6e
  double w[4];
Shinya Kitaoka 120a6e
  TUINT32 transp;
Shinya Kitaoka 120a6e
  BLOB24 color_blob[4], new_color_blob;
Shinya Kitaoka 120a6e
  BLOB24 pencil_blob[4], new_pencil_blob;
Shinya Kitaoka 120a6e
  int color_blobs;
Shinya Kitaoka 120a6e
  int pencil_blobs;
Shinya Kitaoka 120a6e
  bool some_pencil;
Shinya Kitaoka 120a6e
  double tone_tot;
Shinya Kitaoka 120a6e
  TUINT32 color_mask, pencil_mask;
Shinya Kitaoka 120a6e
  TUINT32 tone_mask;
Shinya Kitaoka 120a6e
  int tone;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) /* immagine out vuota */
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) /* immagine in vuota */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    for (y = 0; y < rout->getLy(); y++)
Shinya Kitaoka 120a6e
      for (x = 0; x < rout->getLx(); x++)
Shinya Kitaoka 120a6e
        ((TUINT32 *)rout->getRawData())[x + y * rout->getWrap()] = 0xff;
Shinya Kitaoka 120a6e
    rout->unlock();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bufin_tcm  = (TUINT32 *)rin->getRawData();
Shinya Kitaoka 120a6e
  bufout_tcm = (TUINT32 *)rout->getRawData();
Shinya Kitaoka 120a6e
  wrapin     = rin->getWrap();
Shinya Kitaoka 120a6e
  wrapout    = rout->getWrap();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  mx         = lx - 1;
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  my         = ly - 1;
Shinya Kitaoka 120a6e
  inv        = aff.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  pencil_mask = TPixelCM32::getInkMask();
Shinya Kitaoka 120a6e
  color_mask  = TPixelCM32::getPaintMask();
Shinya Kitaoka 120a6e
  tone_mask   = TPixelCM32::getToneMask();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  transp = tone_mask;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(tone_mask &
Shinya Kitaoka 120a6e
         0x1);  // Ensure that tone lies in the less significative bits
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // deal with every output line independently
Shinya Kitaoka 120a6e
  for (y = 0; y < ly; y++) {
Shinya Kitaoka 120a6e
    // Take inv*(0,y)
Shinya Kitaoka 120a6e
    u_0 = inv.a12 * y + inv.a13;
Shinya Kitaoka 120a6e
    v_0 = inv.a22 * y + inv.a23;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    out_tcm = bufout_tcm + wrapout * y;
Shinya Kitaoka 120a6e
    x       = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Place transparent pixels until we reach a useful source pos.
Shinya Kitaoka 120a6e
    for (; x < lx; x++) {
Shinya Kitaoka 120a6e
      // Add inv*(x,0) and floor it
Shinya Kitaoka 120a6e
      u_ = u_0 + x * inv.a11;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + x * inv.a21;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if (MINOREQ(u + 1, lu) &&
Shinya Kitaoka 120a6e
          MINOREQ(v + 1, lv))  // u>=-1 && u<lu &&="" v="">=-1 && v</lu>
Shinya Kitaoka 120a6e
        break;                 // Goto next for
Shinya Kitaoka 120a6e
      *out_tcm++ = transp;     // Otherwise, place a transparent pixel
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Deal with leftwise border pre-images
Shinya Kitaoka 120a6e
    for (; x < lx; x++) {
Shinya Kitaoka 120a6e
      u_ = u_0 + x * inv.a11;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + x * inv.a21;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if (MINOR(u, lu) && MINOR(v, lv))  // u>=0 && u<lu &&="" v="">=0 && v</lu>
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      in_tcm  = bufin_tcm + u + v * wrapin;
Shinya Kitaoka 120a6e
      bool u0 = MINOREQ(u, mu);
Shinya Kitaoka 120a6e
      bool v0 = MINOREQ(v, mv);
Shinya Kitaoka 120a6e
      bool u1 = MINOREQ(u + 1, mv);
Shinya Kitaoka 120a6e
      bool v1 = MINOREQ(v + 1, mv);
Shinya Kitaoka 120a6e
      tcm[0]  = (u0 && v0) ? in_tcm[0] : transp;
Shinya Kitaoka 120a6e
      tcm[1]  = (u1 && v0) ? in_tcm[1] : transp;
Shinya Kitaoka 120a6e
      tcm[2]  = (u0 && v1) ? in_tcm[wrapin] : transp;
Shinya Kitaoka 120a6e
      tcm[3]  = (u1 && v1) ? in_tcm[wrapin + 1] : transp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Shinya Kitaoka 120a6e
        *out_tcm++ = tcm[0];
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        fu          = u_ - u;
Shinya Kitaoka 120a6e
        gu          = 1. - fu;
Shinya Kitaoka 120a6e
        fv          = v_ - v;
Shinya Kitaoka 120a6e
        gv          = 1. - fv;
Shinya Kitaoka 120a6e
        w[0]        = gu * gv;
Shinya Kitaoka 120a6e
        w[2]        = gu * fv;
Shinya Kitaoka 120a6e
        w[1]        = fu * gv;
Shinya Kitaoka 120a6e
        w[3]        = fu * fv;
Shinya Kitaoka 120a6e
        color_blobs = pencil_blobs = 0;
Shinya Kitaoka 120a6e
        tone_tot                   = 0.0;
Shinya Kitaoka 120a6e
        some_pencil                = false;
Shinya Kitaoka 120a6e
        for (i = 0; i < 4; i++) {
Shinya Kitaoka 120a6e
          tone                                        = tcm[i] & tone_mask;
Shinya Kitaoka 120a6e
          if ((TUINT32)tone != tone_mask) some_pencil = true;
Shinya Kitaoka 120a6e
          tone_tot += tone * w[i];
Shinya Kitaoka 120a6e
          new_color_blob.val = tcm[i] & color_mask;
Shinya Kitaoka 120a6e
          new_color_blob.tot = tone * w[i];
Shinya Kitaoka 120a6e
          for (j = 0; j < color_blobs; j++)
Shinya Kitaoka 120a6e
            if (color_blob[j].val == new_color_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < color_blobs)
Shinya Kitaoka 120a6e
            color_blob[j].tot += new_color_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            color_blob[color_blobs++] = new_color_blob;
Shinya Kitaoka 120a6e
          for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(color_blob[j], color_blob[j - 1]);
Shinya Kitaoka 120a6e
          new_pencil_blob.val = tcm[i] & pencil_mask;
Shinya Kitaoka 120a6e
          new_pencil_blob.tot = (tone_mask - tone) * w[i];
Shinya Kitaoka 120a6e
          for (j = 0; j < pencil_blobs; j++)
Shinya Kitaoka 120a6e
            if (pencil_blob[j].val == new_pencil_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < pencil_blobs)
Shinya Kitaoka 120a6e
            pencil_blob[j].tot += new_pencil_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            pencil_blob[pencil_blobs++] = new_pencil_blob;
Shinya Kitaoka 120a6e
          for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(pencil_blob[j], pencil_blob[j - 1]);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        tone = troundp(tone_tot);
Shinya Kitaoka 120a6e
        // if (some_pencil && (TUINT32)tone == tone_mask)
Shinya Kitaoka 120a6e
        //  tone--;
Shinya Kitaoka 120a6e
        // if (color_blob[0].val==0 && pencil_blob[0].val==0)
Shinya Kitaoka 120a6e
        //  tone = 255;
Shinya Kitaoka 120a6e
        *out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Deal with useful source positions on the output line's pre-image
Shinya Kitaoka 120a6e
    for (; x < lx; x++) {
Shinya Kitaoka 120a6e
      u_ = u_0 + x * inv.a11;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + x * inv.a21;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if (!(MINOR(u, lu) && MINOR(v, lv)))  // u<0 || u>=lu || v<0 || v>=lv
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      in_tcm = bufin_tcm + u +
Shinya Kitaoka 120a6e
               v * wrapin;  // Take the associated input pixel pointer
Shinya Kitaoka 120a6e
      tcm[0] = in_tcm[0];
Shinya Kitaoka 120a6e
      if (u < lu - 1 && v < lv - 1) {
Shinya Kitaoka 120a6e
        // Also take their 4 next neighours (we shall perform a kinf of bilinear
Shinya Kitaoka 120a6e
        // interpolation)
Shinya Kitaoka 120a6e
        tcm[1] = in_tcm[1];
Shinya Kitaoka 120a6e
        tcm[2] = in_tcm[wrapin];
Shinya Kitaoka 120a6e
        tcm[3] = in_tcm[wrapin + 1];
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        // Eventually, simulate the off-boundary ones
Shinya Kitaoka 120a6e
        tcm[1] = (u == lu - 1) ? in_tcm[0] : in_tcm[1];
Shinya Kitaoka 120a6e
        tcm[2] = (v == lv - 1) ? in_tcm[0] : in_tcm[wrapin];
Shinya Kitaoka 120a6e
        tcm[3] = (u == lu - 1 || v == lv - 1) ? in_tcm[0] : in_tcm[wrapin + 1];
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Shinya Kitaoka 120a6e
        *out_tcm++ = tcm[0];  // If they are all equal, it's a copy-op
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        // Otherwise, take the bilinear coordinates
Shinya Kitaoka 120a6e
        fu   = u_ - u;
Shinya Kitaoka 120a6e
        gu   = 1. - fu;
Shinya Kitaoka 120a6e
        fv   = v_ - v;
Shinya Kitaoka 120a6e
        gv   = 1. - fv;
Shinya Kitaoka 120a6e
        w[0] = gu * gv;
Shinya Kitaoka 120a6e
        w[2] = gu * fv;  // And the associated weights
Shinya Kitaoka 120a6e
        w[1]        = fu * gv;
Shinya Kitaoka 120a6e
        w[3]        = fu * fv;
Shinya Kitaoka 120a6e
        color_blobs = pencil_blobs = 0;
Shinya Kitaoka 120a6e
        tone_tot                   = 0.0;
Shinya Kitaoka 120a6e
        some_pencil                = false;
Shinya Kitaoka 120a6e
        // Examine all neighbouring pixels
Shinya Kitaoka 120a6e
        for (i = 0; i < 4; i++) {
Shinya Kitaoka 120a6e
          tone = tcm[i] & tone_mask;  // Take the tone
Shinya Kitaoka 120a6e
          if ((TUINT32)tone != tone_mask) some_pencil = true;
Shinya Kitaoka 120a6e
          tone_tot += tone * w[i];  // Build the weighted tone sum
Shinya Kitaoka 120a6e
          new_color_blob.val = tcm[i] & color_mask;
Shinya Kitaoka 120a6e
          new_color_blob.tot =
Shinya Kitaoka 120a6e
              tone * w[i];  // And the weighted paint tone for this pixel
Shinya Kitaoka 120a6e
          // Fill in the different colors found in an array. Equal colors are
Shinya Kitaoka 120a6e
          // stored as one
Shinya Kitaoka 120a6e
          // with summed weighted total tone.
Shinya Kitaoka 120a6e
          for (j = 0; j < color_blobs; j++)
Shinya Kitaoka 120a6e
            if (color_blob[j].val == new_color_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < color_blobs)
Shinya Kitaoka 120a6e
            color_blob[j].tot += new_color_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            color_blob[color_blobs++] = new_color_blob;
Shinya Kitaoka 120a6e
          // Sort the stored colors for decreasing weighted total tone
Shinya Kitaoka 120a6e
          for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(color_blob[j], color_blob[j - 1]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // Deal the same way with ink colors.
Shinya Kitaoka 120a6e
          new_pencil_blob.val = tcm[i] & pencil_mask;
Shinya Kitaoka 120a6e
          new_pencil_blob.tot = (tone_mask - tone) * w[i];
Shinya Kitaoka 120a6e
          for (j = 0; j < pencil_blobs; j++)
Shinya Kitaoka 120a6e
            if (pencil_blob[j].val == new_pencil_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < pencil_blobs)
Shinya Kitaoka 120a6e
            pencil_blob[j].tot += new_pencil_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            pencil_blob[pencil_blobs++] = new_pencil_blob;
Shinya Kitaoka 120a6e
          for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(pencil_blob[j], pencil_blob[j - 1]);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        tone = tround(tone_tot);
Shinya Kitaoka 120a6e
        // if (some_pencil && (TUINT32)tone == tone_mask)
Shinya Kitaoka 120a6e
        //  tone--;
Shinya Kitaoka 120a6e
        // if (color_blob[0].val==0 && pencil_blob[0].val==0)
Shinya Kitaoka 120a6e
        //  tone = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        // The output colors shall be the ones with maximum weighted total tone,
Shinya Kitaoka 120a6e
        // with the overall total tone as output tone.
Shinya Kitaoka 120a6e
        *out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Again, deal with border pixels at the end of line's pre-image
Shinya Kitaoka 120a6e
    for (; x < lx; x++) {
Shinya Kitaoka 120a6e
      u_ = u_0 + x * inv.a11;
Shinya Kitaoka 120a6e
      u  = tfloor(u_);
Shinya Kitaoka 120a6e
      v_ = v_0 + x * inv.a21;
Shinya Kitaoka 120a6e
      v  = tfloor(v_);
Shinya Kitaoka 120a6e
      if (!(MINOREQ(u + 1, lu) &&
Shinya Kitaoka 120a6e
            MINOREQ(v + 1, lv)))  // u<-1 || u>=lu || v<-1 || v>=lv
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      in_tcm  = bufin_tcm + u + v * wrapin;
Shinya Kitaoka 120a6e
      bool u0 = MINOREQ(u, mu);
Shinya Kitaoka 120a6e
      bool v0 = MINOREQ(v, mv);
Shinya Kitaoka 120a6e
      bool u1 = MINOREQ(u + 1, mv);
Shinya Kitaoka 120a6e
      bool v1 = MINOREQ(v + 1, mv);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      tcm[0] = (u0 && v0) ? in_tcm[0] : transp;
Shinya Kitaoka 120a6e
      tcm[1] = (u1 && v0) ? in_tcm[1] : transp;
Shinya Kitaoka 120a6e
      tcm[2] = (u0 && v1) ? in_tcm[wrapin] : transp;
Shinya Kitaoka 120a6e
      tcm[3] = (u1 && v1) ? in_tcm[wrapin + 1] : transp;
Shinya Kitaoka 120a6e
      if (tcm[0] == tcm[1] && tcm[1] == tcm[2] && tcm[2] == tcm[3])
Shinya Kitaoka 120a6e
        *out_tcm++ = tcm[0];
Shinya Kitaoka 120a6e
      else {
Shinya Kitaoka 120a6e
        fu          = u_ - u;
Shinya Kitaoka 120a6e
        gu          = 1. - fu;
Shinya Kitaoka 120a6e
        fv          = v_ - v;
Shinya Kitaoka 120a6e
        gv          = 1. - fv;
Shinya Kitaoka 120a6e
        w[0]        = gu * gv;
Shinya Kitaoka 120a6e
        w[2]        = gu * fv;
Shinya Kitaoka 120a6e
        w[1]        = fu * gv;
Shinya Kitaoka 120a6e
        w[3]        = fu * fv;
Shinya Kitaoka 120a6e
        color_blobs = pencil_blobs = 0;
Shinya Kitaoka 120a6e
        tone_tot                   = 0.0;
Shinya Kitaoka 120a6e
        some_pencil                = false;
Shinya Kitaoka 120a6e
        for (i = 0; i < 4; i++) {
Shinya Kitaoka 120a6e
          tone                                        = tcm[i] & tone_mask;
Shinya Kitaoka 120a6e
          if ((TUINT32)tone != tone_mask) some_pencil = true;
Shinya Kitaoka 120a6e
          tone_tot += tone * w[i];
Shinya Kitaoka 120a6e
          new_color_blob.val = tcm[i] & color_mask;
Shinya Kitaoka 120a6e
          new_color_blob.tot = tone * w[i];
Shinya Kitaoka 120a6e
          for (j = 0; j < color_blobs; j++)
Shinya Kitaoka 120a6e
            if (color_blob[j].val == new_color_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < color_blobs)
Shinya Kitaoka 120a6e
            color_blob[j].tot += new_color_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            color_blob[color_blobs++] = new_color_blob;
Shinya Kitaoka 120a6e
          for (; j > 0 && color_blob[j].tot > color_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(color_blob[j], color_blob[j - 1]);
Shinya Kitaoka 120a6e
          new_pencil_blob.val = tcm[i] & pencil_mask;
Shinya Kitaoka 120a6e
          new_pencil_blob.tot = (tone_mask - tone) * w[i];
Shinya Kitaoka 120a6e
          for (j = 0; j < pencil_blobs; j++)
Shinya Kitaoka 120a6e
            if (pencil_blob[j].val == new_pencil_blob.val) break;
Shinya Kitaoka 120a6e
          if (j < pencil_blobs)
Shinya Kitaoka 120a6e
            pencil_blob[j].tot += new_pencil_blob.tot;
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            pencil_blob[pencil_blobs++] = new_pencil_blob;
Shinya Kitaoka 120a6e
          for (; j > 0 && pencil_blob[j].tot > pencil_blob[j - 1].tot; j--)
Shinya Kitaoka 120a6e
            tswap(pencil_blob[j], pencil_blob[j - 1]);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        tone = troundp(tone_tot);
Shinya Kitaoka 120a6e
        // if (some_pencil && (TUINT32)tone == tone_mask)
Shinya Kitaoka 120a6e
        //  tone--;
Shinya Kitaoka 120a6e
        // if (color_blob[0].val==0 && pencil_blob[0].val==0)
Shinya Kitaoka 120a6e
        //  tone = 255;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        *out_tcm++ = color_blob[0].val | pencil_blob[0].val | tone;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Finally, deal with out-of-source pixels at the end of line's pre-image
Shinya Kitaoka 120a6e
    for (; x < lx; x++) *out_tcm++ = transp;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  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>
Shinya Kitaoka 120a6e
                                  const TAffine &aff_xy2uv,
Shinya Kitaoka 120a6e
                                  const TAffine &aff0_uv2fg, int min_pix_ref_u,
Shinya Kitaoka 120a6e
                                  int min_pix_ref_v, int max_pix_ref_u,
Shinya Kitaoka 120a6e
                                  int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
                                  int *pix_ref_v, int *pix_ref_f,
Shinya Kitaoka 120a6e
                                  int *pix_ref_g, short *filter,
Shinya Kitaoka 120a6e
                                  TPalette *palette) {
Shinya Kitaoka 120a6e
  __m128i zeros = _mm_setzero_si128();
Shinya Kitaoka 120a6e
  const TPixelCM32 *buffer_in;
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int inside_offset_u, inside_offset_v;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  double outside_min_u_, outside_min_v_;
Shinya Kitaoka 120a6e
  double outside_max_u_, outside_max_v_;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  T pix_value;
Shinya Kitaoka 120a6e
  T default_value(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  float weight;
Shinya Kitaoka 120a6e
  float sum_weights;
Shinya Kitaoka 120a6e
  float inv_sum_weights;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  T *pix_out;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128 sum_contribs_packed;
Shinya Kitaoka 120a6e
  __m128 pix_value_packed;
Shinya Kitaoka 120a6e
  __m128 weight_packed;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  __m128 zeros2 = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float maxChannelValue        = (float)T::maxChannelValue;
Shinya Kitaoka 120a6e
  __m128 maxChanneValue_packed = _mm_load1_ps(&maxChannelValue);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    resample_clear_rgbm(rout, default_value);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inside_offset_u = -min_pix_ref_u;
Shinya Kitaoka 120a6e
  inside_offset_v = -min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - max_pix_ref_u - inside_offset_u;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - max_pix_ref_v - inside_offset_v;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u_  = -0.5;
Shinya Kitaoka 120a6e
  outside_min_v_  = -0.5;
Shinya Kitaoka 120a6e
  outside_max_u_  = lu - 0.5;
Shinya Kitaoka 120a6e
  outside_max_v_  = lv - 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int count = palette->getStyleCount();
Shinya Kitaoka 120a6e
  int count2 =
Shinya Kitaoka 120a6e
      std::max({count, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPixelFloat *paints =
Shinya Kitaoka 120a6e
      (TPixelFloat *)_aligned_malloc(count2 * sizeof(TPixelFloat), 16);
Shinya Kitaoka 120a6e
  TPixelFloat *inks =
Shinya Kitaoka 120a6e
      (TPixelFloat *)_aligned_malloc(count2 * sizeof(TPixelFloat), 16);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints2(count2);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks2(count2);</tpixel32>
Shinya Kitaoka 120a6e
  for (i = 0; i < palette->getStyleCount(); i++) {
Shinya Kitaoka 120a6e
    TPixel32 color = ::premultiply(palette->getStyle(i)->getAverageColor());
Shinya Kitaoka 120a6e
    paints[i] = inks[i] = TPixelFloat(color);
Shinya Kitaoka 120a6e
    paints2[i] = inks2[i] = color;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  float maxTone     = (float)TPixelCM32::getMaxTone();
Shinya Kitaoka 120a6e
  __m128 den_packed = _mm_load1_ps(&maxTone);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      pix_out = buffer_out + out_y * wrap_out + out_x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      ref_u  = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v  = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Shinya Kitaoka 120a6e
          ref_out_u_  = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_  = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_  = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_  = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f   = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g   = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          sum_contribs_packed = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos           = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Shinya Kitaoka 120a6e
            int tone                 = pix_in->getTone();
Shinya Kitaoka 120a6e
            int paint                = pix_in->getPaint();
Shinya Kitaoka 120a6e
            int ink                  = pix_in->getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value_packed = _mm_load_ps((float *)&(paints[paint]));
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value_packed = _mm_load_ps((float *)&(inks[ink]));
Shinya Kitaoka 120a6e
            else {
Shinya Kitaoka 120a6e
              float tt = (float)tone;
Shinya Kitaoka 120a6e
              blendBySSE2(pix_value_packed,  // il valore calcolato
Shinya Kitaoka 120a6e
                          (float *)&(inks[ink]), (float *)&(paints[paint]), &tt,
Shinya Kitaoka 120a6e
                          den_packed, zeros);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            weight_packed = _mm_load1_ps(&weight);
Shinya Kitaoka 120a6e
            sum_contribs_packed =
Shinya Kitaoka 120a6e
                _mm_add_ps(sum_contribs_packed,
Shinya Kitaoka 120a6e
                           _mm_mul_ps(pix_value_packed, weight_packed));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights               = 1.0f / sum_weights;
Shinya Kitaoka 120a6e
          __m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128 out_fval_packed =
Shinya Kitaoka 120a6e
              _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packs_epi32(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packus_epi16(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          *(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int pix_in_pos           = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Shinya Kitaoka 120a6e
          int tone                 = pix_in->getTone();
Shinya Kitaoka 120a6e
          int paint                = pix_in->getPaint();
Shinya Kitaoka 120a6e
          int ink                  = pix_in->getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            *pix_out = paints2[paint];
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            *pix_out = inks2[ink];
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            *pix_out = blend(inks2[ink], paints2[paint], tone,
Shinya Kitaoka 120a6e
                             TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Shinya Kitaoka 120a6e
                 outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_          = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_          = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_          = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_          = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f           = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g           = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights         = 0;
Shinya Kitaoka 120a6e
          sum_contribs_packed = _mm_setzero_ps();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos           = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Shinya Kitaoka 120a6e
            int tone                 = pix_in->getTone();
Shinya Kitaoka 120a6e
            int paint                = pix_in->getPaint();
Shinya Kitaoka 120a6e
            int ink                  = pix_in->getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value_packed = _mm_load_ps((float *)&(paints[paint]));
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value_packed = _mm_load_ps((float *)&(inks[ink]));
Shinya Kitaoka 120a6e
            else {
Shinya Kitaoka 120a6e
              float tt = (float)tone;
Shinya Kitaoka 120a6e
              blendBySSE2(pix_value_packed,  // il valore calcolato
Shinya Kitaoka 120a6e
                          (float *)&(inks[ink]), (float *)&(paints[paint]), &tt,
Shinya Kitaoka 120a6e
                          den_packed, zeros);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            weight_packed = _mm_load1_ps(&weight);
Shinya Kitaoka 120a6e
            sum_contribs_packed =
Shinya Kitaoka 120a6e
                _mm_add_ps(sum_contribs_packed,
Shinya Kitaoka 120a6e
                           _mm_mul_ps(pix_value_packed, weight_packed));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0f / sum_weights;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128 inv_sum_weights_packed = _mm_load1_ps(&inv_sum_weights);
Shinya Kitaoka 120a6e
          __m128 out_fval_packed =
Shinya Kitaoka 120a6e
              _mm_mul_ps(sum_contribs_packed, inv_sum_weights_packed);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_max_ps(out_fval_packed, zeros2);
Shinya Kitaoka 120a6e
          out_fval_packed = _mm_min_ps(out_fval_packed, maxChanneValue_packed);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          __m128i out_value_packed_i = _mm_cvtps_epi32(out_fval_packed);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packs_epi32(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          out_value_packed_i  = _mm_packus_epi16(out_value_packed_i, zeros);
Shinya Kitaoka 120a6e
          *(DWORD *)(pix_out) = _mm_cvtsi128_si32(out_value_packed_i);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int pix_in_pos           = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          const TPixelCM32 *pix_in = buffer_in + pix_in_pos;
Shinya Kitaoka 120a6e
          int tone                 = pix_in->getTone();
Shinya Kitaoka 120a6e
          int paint                = pix_in->getPaint();
Shinya Kitaoka 120a6e
          int ink                  = pix_in->getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            *pix_out = paints2[paint];
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            *pix_out = inks2[ink];
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            *pix_out = blend(inks2[ink], paints2[paint], tone,
Shinya Kitaoka 120a6e
                             TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        *pix_out = default_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (calc) delete[] calc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*---------------------------------------------------------------------------*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Shinya Kitaoka 120a6e
void resample_main_cm32_rgbm_bigradius(
Shinya Kitaoka 120a6e
    TRasterPT<t> rout, const TRasterCM32P &rin, const TAffine &aff_xy2uv,</t>
Shinya Kitaoka 120a6e
    const TAffine &aff0_uv2fg, int min_pix_ref_u, int min_pix_ref_v,
Shinya Kitaoka 120a6e
    int max_pix_ref_u, int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
    int *pix_ref_v, int *pix_ref_f, int *pix_ref_g, short *filter,
Shinya Kitaoka 120a6e
    TPalette *palette) {
Shinya Kitaoka 120a6e
  // bigradius: cambia solo che i sum_contribs sono double invece che int
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const TPixelCM32 *buffer_in;
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int inside_offset_u, inside_offset_v;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  double outside_min_u_, outside_min_v_;
Shinya Kitaoka 120a6e
  double outside_max_u_, outside_max_v_;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  T pix_value;
Shinya Kitaoka 120a6e
  T default_value;
Shinya Kitaoka 120a6e
  float weight;
Shinya Kitaoka 120a6e
  float sum_weights;
Shinya Kitaoka 120a6e
  double inv_sum_weights;
Shinya Kitaoka 120a6e
  double sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Shinya Kitaoka 120a6e
  double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Shinya Kitaoka 120a6e
  int out_value_r, out_value_g, out_value_b, out_value_m;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  T *pix_out;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  default_value.r = 0;
Shinya Kitaoka 120a6e
  default_value.g = 0;
Shinya Kitaoka 120a6e
  default_value.b = 0;
Shinya Kitaoka 120a6e
  default_value.m = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    rout->clear();
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inside_offset_u = -min_pix_ref_u;
Shinya Kitaoka 120a6e
  inside_offset_v = -min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - max_pix_ref_u - inside_offset_u;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - max_pix_ref_v - inside_offset_v;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u_  = -0.5;
Shinya Kitaoka 120a6e
  outside_min_v_  = -0.5;
Shinya Kitaoka 120a6e
  outside_max_u_  = lu - 0.5;
Shinya Kitaoka 120a6e
  outside_max_v_  = lv - 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorCount = palette->getStyleCount();
Shinya Kitaoka 120a6e
  colorCount     = std::max(
Shinya Kitaoka 120a6e
      {colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  for (i      = 0; i < palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    paints[i] = inks[i] =
Shinya Kitaoka 120a6e
        ::premultiply(palette->getStyle(i)->getAverageColor());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      pix_out = buffer_out + out_y * wrap_out + out_x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      ref_u  = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v  = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                  inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          pix_out->r = out_value_r;
Shinya Kitaoka 120a6e
          pix_out->g = out_value_g;
Shinya Kitaoka 120a6e
          pix_out->b = out_value_b;
Shinya Kitaoka 120a6e
          pix_out->m = out_value_m;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          // *pix_out = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Shinya Kitaoka 120a6e
                 outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (float)((filter[pix_out_f] * filter[pix_out_g]) >> 16);
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                  inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          pix_out->r = out_value_r;
Shinya Kitaoka 120a6e
          pix_out->g = out_value_g;
Shinya Kitaoka 120a6e
          pix_out->b = out_value_b;
Shinya Kitaoka 120a6e
          pix_out->m = out_value_m;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            *pix_out = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        *pix_out = default_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (calc) 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>
Shinya Kitaoka 120a6e
                             const TAffine &aff_xy2uv,
Shinya Kitaoka 120a6e
                             const TAffine &aff0_uv2fg, int min_pix_ref_u,
Shinya Kitaoka 120a6e
                             int min_pix_ref_v, int max_pix_ref_u,
Shinya Kitaoka 120a6e
                             int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
                             int *pix_ref_v, int *pix_ref_f, int *pix_ref_g,
Shinya Kitaoka 120a6e
                             short *filter, TPalette *palette) {
Shinya Kitaoka 120a6e
  const TPixelCM32 *buffer_in;
Shinya Kitaoka 120a6e
  T *buffer_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int inside_offset_u, inside_offset_v;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  double outside_min_u_, outside_min_v_;
Shinya Kitaoka 120a6e
  double outside_max_u_, outside_max_v_;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  T pix_value;
Shinya Kitaoka 120a6e
  T default_value(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  int weight;
Shinya Kitaoka 120a6e
  int sum_weights;
Shinya Kitaoka 120a6e
  double inv_sum_weights;
Shinya Kitaoka 120a6e
  int sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Shinya Kitaoka 120a6e
  double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Shinya Kitaoka 120a6e
  int out_value_r, out_value_g, out_value_b, out_value_m;
Shinya Kitaoka 120a6e
  T out_value;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (n_pix >= 512 || T::maxChannelValue > 255) {
Shinya Kitaoka 120a6e
    resample_main_cm32_rgbm_bigradius<t>(</t>
Shinya Kitaoka 120a6e
        rout, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
        max_pix_ref_u, max_pix_ref_v, n_pix, pix_ref_u, pix_ref_v, pix_ref_f,
Shinya Kitaoka 120a6e
        pix_ref_g, filter, palette);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    resample_clear_rgbm<t>(rout, default_value);</t>
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inside_offset_u = -min_pix_ref_u;
Shinya Kitaoka 120a6e
  inside_offset_v = -min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - max_pix_ref_u - inside_offset_u;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - max_pix_ref_v - inside_offset_v;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u_  = -0.5;
Shinya Kitaoka 120a6e
  outside_min_v_  = -0.5;
Shinya Kitaoka 120a6e
  outside_max_u_  = lu - 0.5;
Shinya Kitaoka 120a6e
  outside_max_v_  = lv - 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorCount = palette->getStyleCount();
Shinya Kitaoka 120a6e
  colorCount     = std::max(
Shinya Kitaoka 120a6e
      {colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  for (i      = 0; i < palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    paints[i] = inks[i] =
Shinya Kitaoka 120a6e
        ::premultiply(palette->getStyle(i)->getAverageColor());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      ref_u  = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v  = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                  inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          out_value.r = out_value_r;
Shinya Kitaoka 120a6e
          out_value.g = out_value_g;
Shinya Kitaoka 120a6e
          out_value.b = out_value_b;
Shinya Kitaoka 120a6e
          out_value.m = out_value_m;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          // out_value = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Shinya Kitaoka 120a6e
                 outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
            else if (tone == 0)
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                  inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(T::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          out_value.r = out_value_r;
Shinya Kitaoka 120a6e
          out_value.g = out_value_g;
Shinya Kitaoka 120a6e
          out_value.b = out_value_b;
Shinya Kitaoka 120a6e
          out_value.m = out_value_m;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          // out_value = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int tone       = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int paint      = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int ink        = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (tone == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(paints[paint]);</t>
Shinya Kitaoka 120a6e
          else if (tone == 0)
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(inks[ink]);</t>
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            out_value = Converter<t>::convert(blend(</t>
Shinya Kitaoka 120a6e
                inks[ink], paints[paint], tone, TPixelCM32::getMaxTone()));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        out_value = default_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      buffer_out[out_x + out_y * wrap_out] = out_value;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (calc) 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,
Shinya Kitaoka 120a6e
                        const TAffine &aff_xy2uv, const TAffine &aff0_uv2fg,
Shinya Kitaoka 120a6e
                        int min_pix_ref_u, int min_pix_ref_v, int max_pix_ref_u,
Shinya Kitaoka 120a6e
                        int max_pix_ref_v, int n_pix, int *pix_ref_u,
Shinya Kitaoka 120a6e
                        int *pix_ref_v, int *pix_ref_f, int *pix_ref_g,
Shinya Kitaoka 120a6e
                        short *filter, TPalette *palette) {
Shinya Kitaoka 120a6e
  const TPixelCM32 *buffer_in;
Shinya Kitaoka 120a6e
  /*T*/ TPixel32 *buffer_out;
Shinya Kitaoka 120a6e
  int lu, lv, wrap_in, mu, mv;
Shinya Kitaoka 120a6e
  int lx, ly, wrap_out;
Shinya Kitaoka 120a6e
  int out_x, out_y;
Shinya Kitaoka 120a6e
  double out_x_, out_y_;
Shinya Kitaoka 120a6e
  double out_u_, out_v_;
Shinya Kitaoka 120a6e
  int ref_u, ref_v;
Shinya Kitaoka 120a6e
  int pix_u, pix_v;
Shinya Kitaoka 120a6e
  double ref_out_u_, ref_out_v_;
Shinya Kitaoka 120a6e
  double ref_out_f_, ref_out_g_;
Shinya Kitaoka 120a6e
  int ref_out_f, ref_out_g;
Shinya Kitaoka 120a6e
  int pix_out_f, pix_out_g;
Shinya Kitaoka 120a6e
  int inside_offset_u, inside_offset_v;
Shinya Kitaoka 120a6e
  UINT inside_limit_u, inside_limit_v;
Shinya Kitaoka 120a6e
  int inside_nonempty;
Shinya Kitaoka 120a6e
  double outside_min_u_, outside_min_v_;
Shinya Kitaoka 120a6e
  double outside_max_u_, outside_max_v_;
Shinya Kitaoka 120a6e
  UCHAR *calc;
Shinya Kitaoka 120a6e
  int calc_allocsize;
Shinya Kitaoka 120a6e
  int calc_bytewrap;
Shinya Kitaoka 120a6e
  UCHAR calc_value;
Shinya Kitaoka 120a6e
  bool must_calc;
Shinya Kitaoka 120a6e
  /*T*/ TPixel32 pix_value;
Shinya Kitaoka 120a6e
  /*T*/ TPixel32 default_value(0, 0, 0, 0);
Shinya Kitaoka 120a6e
  int weight;
Shinya Kitaoka 120a6e
  int sum_weights;
Shinya Kitaoka 120a6e
  double inv_sum_weights;
Shinya Kitaoka 120a6e
  int sum_contribs_r, sum_contribs_g, sum_contribs_b, sum_contribs_m;
Shinya Kitaoka 120a6e
  double out_fval_r, out_fval_g, out_fval_b, out_fval_m;
Shinya Kitaoka 120a6e
  int out_value_r, out_value_g, out_value_b, out_value_m;
Shinya Kitaoka 120a6e
  /*T*/ TPixel32 out_value;
Shinya Kitaoka 120a6e
  int i;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (n_pix >= 512 || /*T*/ TPixel32::maxChannelValue > 255) {
Shinya Kitaoka 120a6e
    assert(false);
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
resample_main_rgbm_bigradius<t>( rout, rin,</t>
Shinya Kitaoka 120a6e
                                              aff_xy2uv,
Shinya Kitaoka 120a6e
                                            aff0_uv2fg,
Shinya Kitaoka 120a6e
                                              min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
                                              max_pix_ref_u, max_pix_ref_v,
Shinya Kitaoka 120a6e
                                              n_pix,
Shinya Kitaoka 120a6e
                                              pix_ref_u, pix_ref_v,
Shinya Kitaoka 120a6e
                                              pix_ref_f, pix_ref_g,
Shinya Kitaoka 120a6e
                                            filter );
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rout->getLx() > 0 && rout->getLy() > 0)) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!(rin->getLx() > 0 && rin->getLy() > 0)) {
Shinya Kitaoka 120a6e
    resample_clear_rgbm(rout, default_value);
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int colorCount = palette->getStyleCount();
Shinya Kitaoka 120a6e
  colorCount     = std::max(
Shinya Kitaoka 120a6e
      {colorCount, TPixelCM32::getMaxInk(), TPixelCM32::getMaxPaint()});
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<tpixel32> paints(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  std::vector<tpixel32> inks(colorCount);</tpixel32>
Shinya Kitaoka 120a6e
  for (i      = 0; i < palette->getStyleCount(); i++)
Shinya Kitaoka 120a6e
    paints[i] = inks[i] =
Shinya Kitaoka 120a6e
        ::premultiply(palette->getStyle(i)->getAverageColor());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  calc           = 0;
Shinya Kitaoka 120a6e
  calc_allocsize = 0;
Shinya Kitaoka 120a6e
  create_calc(rin, min_pix_ref_u, max_pix_ref_u, min_pix_ref_v, max_pix_ref_v,
Shinya Kitaoka 120a6e
              calc, calc_allocsize, calc_bytewrap);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  buffer_in  = rin->pixels();
Shinya Kitaoka 120a6e
  buffer_out = rout->pixels();
Shinya Kitaoka 120a6e
  lu         = rin->getLx();
Shinya Kitaoka 120a6e
  lx         = rout->getLx();
Shinya Kitaoka 120a6e
  lv         = rin->getLy();
Shinya Kitaoka 120a6e
  ly         = rout->getLy();
Shinya Kitaoka 120a6e
  wrap_in    = rin->getWrap();
Shinya Kitaoka 120a6e
  wrap_out   = rout->getWrap();
Shinya Kitaoka 120a6e
  mu         = lu - 1;
Shinya Kitaoka 120a6e
  mv         = lv - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inside_offset_u = -min_pix_ref_u;
Shinya Kitaoka 120a6e
  inside_offset_v = -min_pix_ref_v;
Shinya Kitaoka 120a6e
  inside_limit_u  = lu - max_pix_ref_u - inside_offset_u;
Shinya Kitaoka 120a6e
  inside_limit_v  = lv - max_pix_ref_v - inside_offset_v;
Shinya Kitaoka 120a6e
  inside_nonempty = (int)inside_limit_u > 0 && (int)inside_limit_v > 0;
Shinya Kitaoka 120a6e
  outside_min_u_  = -0.5;
Shinya Kitaoka 120a6e
  outside_min_v_  = -0.5;
Shinya Kitaoka 120a6e
  outside_max_u_  = lu - 0.5;
Shinya Kitaoka 120a6e
  outside_max_v_  = lv - 0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (out_y = 0, out_y_ = 0.0; out_y < ly; out_y++, out_y_ += 1.0) {
Shinya Kitaoka 120a6e
    for (out_x = 0, out_x_ = 0.0; out_x < lx; out_x++, out_x_ += 1.0) {
Shinya Kitaoka 120a6e
      out_u_ = affMV1(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      out_v_ = affMV2(aff_xy2uv, out_x_, out_y_);
Shinya Kitaoka 120a6e
      ref_u  = intLE(out_u_);
Shinya Kitaoka 120a6e
      ref_v  = intLE(out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (inside_nonempty && (UINT)(ref_u - inside_offset_u) < inside_limit_u &&
Shinya Kitaoka 120a6e
          (UINT)(ref_v - inside_offset_v) < inside_limit_v) {
Shinya Kitaoka 120a6e
        calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
        if (calc_value && ((calc_value >> (ref_u & 7)) & 1)) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int t          = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int p          = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int i          = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (t == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = paints[p];
Shinya Kitaoka 120a6e
            else if (t == 0)
Shinya Kitaoka 120a6e
              pix_value = inks[i];
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value =
Shinya Kitaoka 120a6e
                  blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          out_value.r = out_value_r;
Shinya Kitaoka 120a6e
          out_value.g = out_value_g;
Shinya Kitaoka 120a6e
          out_value.b = out_value_b;
Shinya Kitaoka 120a6e
          out_value.m = out_value_m;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int t          = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int p          = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int i          = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (t == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            out_value = paints[p];
Shinya Kitaoka 120a6e
          else if (t == 0)
Shinya Kitaoka 120a6e
            out_value = inks[i];
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            out_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // out_value = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else if (outside_min_u_ <= out_u_ && out_u_ <= outside_max_u_ &&
Shinya Kitaoka 120a6e
                 outside_min_v_ <= out_v_ && out_v_ <= outside_max_v_) {
Shinya Kitaoka 120a6e
        if ((UINT)ref_u >= (UINT)lu || (UINT)ref_v >= (UINT)lv)
Shinya Kitaoka 120a6e
          must_calc = true;
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          calc_value = calc[(ref_u >> 3) + ref_v * calc_bytewrap];
Shinya Kitaoka 120a6e
          must_calc  = calc_value && ((calc_value >> (ref_u & 7)) & 1);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (must_calc) {
Shinya Kitaoka 120a6e
          ref_out_u_     = ref_u - out_u_;
Shinya Kitaoka 120a6e
          ref_out_v_     = ref_v - out_v_;
Shinya Kitaoka 120a6e
          ref_out_f_     = aff0MV1(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_g_     = aff0MV2(aff0_uv2fg, ref_out_u_, ref_out_v_);
Shinya Kitaoka 120a6e
          ref_out_f      = tround(ref_out_f_);
Shinya Kitaoka 120a6e
          ref_out_g      = tround(ref_out_g_);
Shinya Kitaoka 120a6e
          sum_weights    = 0;
Shinya Kitaoka 120a6e
          sum_contribs_r = 0;
Shinya Kitaoka 120a6e
          sum_contribs_g = 0;
Shinya Kitaoka 120a6e
          sum_contribs_b = 0;
Shinya Kitaoka 120a6e
          sum_contribs_m = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (i = n_pix - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
            pix_out_f = pix_ref_f[i] + ref_out_f;
Shinya Kitaoka 120a6e
            pix_out_g = pix_ref_g[i] + ref_out_g;
Shinya Kitaoka 120a6e
            weight    = (filter[pix_out_f] * filter[pix_out_g]) >> 16;
Shinya Kitaoka 120a6e
            pix_u     = pix_ref_u[i] + ref_u;
Shinya Kitaoka 120a6e
            pix_v     = pix_ref_v[i] + ref_v;
Shinya Kitaoka 120a6e
            notLessThan(0, pix_u);
Shinya Kitaoka 120a6e
            notLessThan(0, pix_v);
Shinya Kitaoka 120a6e
            notMoreThan(mu, pix_u);
Shinya Kitaoka 120a6e
            notMoreThan(mv, pix_v);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            // pix_value = buffer_in[pix_u + pix_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            int pix_in_pos = pix_u + pix_v * wrap_in;
Shinya Kitaoka 120a6e
            int t          = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
            int p          = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
            int i          = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            if (t == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
              pix_value = paints[p];
Shinya Kitaoka 120a6e
            else if (t == 0)
Shinya Kitaoka 120a6e
              pix_value = inks[i];
Shinya Kitaoka 120a6e
            else
Shinya Kitaoka 120a6e
              pix_value =
Shinya Kitaoka 120a6e
                  blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
            sum_contribs_r += (int)pix_value.r * weight;
Shinya Kitaoka 120a6e
            sum_contribs_g += (int)pix_value.g * weight;
Shinya Kitaoka 120a6e
            sum_contribs_b += (int)pix_value.b * weight;
Shinya Kitaoka 120a6e
            sum_contribs_m += (int)pix_value.m * weight;
Shinya Kitaoka 120a6e
            sum_weights += weight;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          inv_sum_weights = 1.0 / sum_weights;
Shinya Kitaoka 120a6e
          out_fval_r      = sum_contribs_r * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_g      = sum_contribs_g * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_b      = sum_contribs_b * inv_sum_weights;
Shinya Kitaoka 120a6e
          out_fval_m      = sum_contribs_m * inv_sum_weights;
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_r);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_g);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_b);
Shinya Kitaoka 120a6e
          notLessThan(0.0, out_fval_m);
Shinya Kitaoka 120a6e
          out_value_r = troundp(out_fval_r);
Shinya Kitaoka 120a6e
          out_value_g = troundp(out_fval_g);
Shinya Kitaoka 120a6e
          out_value_b = troundp(out_fval_b);
Shinya Kitaoka 120a6e
          out_value_m = troundp(out_fval_m);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_r);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_g);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_b);
Shinya Kitaoka 120a6e
          notMoreThan(/*T*/ TPixel32::maxChannelValue, out_value_m);
Shinya Kitaoka 120a6e
          out_value.r = out_value_r;
Shinya Kitaoka 120a6e
          out_value.g = out_value_g;
Shinya Kitaoka 120a6e
          out_value.b = out_value_b;
Shinya Kitaoka 120a6e
          out_value.m = out_value_m;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          // out_value = buffer_in[ref_u + ref_v * wrap_in];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          int pix_in_pos = ref_u + ref_v * wrap_in;
Shinya Kitaoka 120a6e
          int t          = buffer_in[pix_in_pos].getTone();
Shinya Kitaoka 120a6e
          int p          = buffer_in[pix_in_pos].getPaint();
Shinya Kitaoka 120a6e
          int i          = buffer_in[pix_in_pos].getInk();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (t == TPixelCM32::getMaxTone())
Shinya Kitaoka 120a6e
            out_value = paints[p];
Shinya Kitaoka 120a6e
          else if (t == 0)
Shinya Kitaoka 120a6e
            out_value = inks[i];
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            out_value = blend(inks[i], paints[p], t, TPixelCM32::getMaxTone());
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        out_value = default_value;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      buffer_out[out_x + out_y * wrap_out] = out_value;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (calc) 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>
Shinya Kitaoka 120a6e
                         const TAffine &aff, TRop::ResampleFilterType flt_type,
Shinya Kitaoka 120a6e
                         double blur, TPalette *palette) {
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
Shinya Kitaoka 120a6e
  static TRop::ResampleFilterType current_flt_type = TRop::None;
Shinya Kitaoka 120a6e
  static std::unique_ptr<short[]> filter_array;</short[]>
Shinya Kitaoka 120a6e
  static short *filter = 0;
Shinya Kitaoka 120a6e
  static int min_filter_fg, max_filter_fg;
Shinya Kitaoka 120a6e
  static int filter_array_size = 0;
Shinya Kitaoka 120a6e
  static int n_pix             = 0;
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 120a6e
  static std::unique_ptr<int[]> pix_ref_g;</int[]>
Shinya Kitaoka 120a6e
  static int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
  std::unique_ptr<short[]> filter_array;</short[]>
Shinya Kitaoka 120a6e
  short *filter = 0;
Shinya Kitaoka 120a6e
  int min_filter_fg, max_filter_fg;
Shinya Kitaoka 120a6e
  int filter_array_size = 0;
Shinya Kitaoka 120a6e
  int n_pix             = 0;
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_u;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_v;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_f;</int[]>
Shinya Kitaoka 120a6e
  std::unique_ptr<int[]> pix_ref_g;</int[]>
Shinya Kitaoka 120a6e
  int current_max_n_pix = 0;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int filter_st_radius;
Shinya Kitaoka 120a6e
  int filter_fg_radius;
Shinya Kitaoka 120a6e
  int filter_size;
Shinya Kitaoka 120a6e
  int f;
Shinya Kitaoka 120a6e
  double s_;
Shinya Kitaoka 120a6e
  double weight_;
Shinya Kitaoka 120a6e
  int weight;
Shinya Kitaoka 120a6e
  TAffine aff_uv2xy;
Shinya Kitaoka 120a6e
  TAffine aff_xy2uv;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2xy;
Shinya Kitaoka 120a6e
  TAffine aff0_xy2st;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2st;
Shinya Kitaoka 120a6e
  TAffine aff0_st2fg;
Shinya Kitaoka 120a6e
  TAffine aff0_uv2fg;
Shinya Kitaoka 120a6e
  TAffine aff0_fg2uv;
Shinya Kitaoka 120a6e
  double scale_x, scale_y;
Shinya Kitaoka 120a6e
  double inv_blur;
Shinya Kitaoka 120a6e
  int max_n_pix;
Shinya Kitaoka 120a6e
  double min_pix_out_u_, min_pix_out_v_;
Shinya Kitaoka 120a6e
  double max_pix_out_u_, max_pix_out_v_;
Shinya Kitaoka 120a6e
  int min_pix_ref_u, min_pix_ref_v;
Shinya Kitaoka 120a6e
  int max_pix_ref_u, max_pix_ref_v;
Shinya Kitaoka 120a6e
  int cur_pix_ref_u, cur_pix_ref_v;
Shinya Kitaoka 120a6e
  double cur_pix_ref_f_, cur_pix_ref_g_;
Shinya Kitaoka 120a6e
  int cur_pix_ref_f, cur_pix_ref_g;
Shinya Kitaoka 120a6e
  double min_ref_out_f_, min_ref_out_g_;
Shinya Kitaoka 120a6e
  double max_ref_out_f_, max_ref_out_g_;
Shinya Kitaoka 120a6e
  int min_ref_out_f, min_ref_out_g;
Shinya Kitaoka 120a6e
  int max_ref_out_f, max_ref_out_g;
Shinya Kitaoka 120a6e
  int min_pix_ref_f, min_pix_ref_g;
Shinya Kitaoka 120a6e
  int max_pix_ref_f, max_pix_ref_g;
Shinya Kitaoka 120a6e
  int min_pix_out_f, min_pix_out_g;
Shinya Kitaoka 120a6e
  int max_pix_out_f, max_pix_out_g;
Shinya Kitaoka 120a6e
  int min_pix_out_fg;
Shinya Kitaoka 120a6e
  int max_pix_out_fg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_DOUBLE_TO_INT
Shinya Kitaoka 120a6e
  double d2iaux;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(flt_type != TRop::None);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  filter_st_radius = get_filter_radius(flt_type);
Shinya Kitaoka 120a6e
  filter_fg_radius = filter_st_radius * FILTER_RESOLUTION;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  aff_uv2xy  = aff;
Shinya Kitaoka 120a6e
  aff0_uv2xy = aff_uv2xy.place(0.0, 0.0, 0.0, 0.0);
Shinya Kitaoka 120a6e
  aff_xy2uv  = aff_uv2xy.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  scale_x    = sqrt(sq(aff_uv2xy.a11) + sq(aff_uv2xy.a12));
Shinya Kitaoka 120a6e
  scale_y    = sqrt(sq(aff_uv2xy.a21) + sq(aff_uv2xy.a22));
Shinya Kitaoka 120a6e
  aff0_xy2st = TScale((scale_x > 1.0) ? 1.0 / scale_x : 1.0,
Shinya Kitaoka 120a6e
                      (scale_y > 1.0) ? 1.0 / scale_y : 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (blur > 1.0)  // per ora il blur e' 1.0
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    inv_blur   = 1.0 / blur;
Shinya Kitaoka 120a6e
    aff0_xy2st = TScale(inv_blur, inv_blur) * aff0_xy2st;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  aff0_uv2st = aff0_xy2st * aff0_uv2xy;
Shinya Kitaoka 120a6e
  aff0_st2fg = TScale(FILTER_RESOLUTION, FILTER_RESOLUTION);
Shinya Kitaoka 120a6e
  aff0_uv2fg = aff0_st2fg * aff0_uv2st;
Shinya Kitaoka 120a6e
  aff0_fg2uv = aff0_uv2fg.inv();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  minmax(-filter_fg_radius, -filter_fg_radius, filter_fg_radius,
Shinya Kitaoka 120a6e
         filter_fg_radius, aff0_fg2uv, min_pix_out_u_, min_pix_out_v_,
Shinya Kitaoka 120a6e
         max_pix_out_u_, max_pix_out_v_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_pix_ref_u = intGT(min_pix_out_u_);
Shinya Kitaoka 120a6e
  min_pix_ref_v = intGT(min_pix_out_v_);
Shinya Kitaoka 120a6e
  max_pix_ref_u = intLT(max_pix_out_u_) + 1;
Shinya Kitaoka 120a6e
  max_pix_ref_v = intLT(max_pix_out_v_) + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (blur <= 1.0) {
Shinya Kitaoka 120a6e
    if (aff_uv2xy.a12 == 0.0 && aff_uv2xy.a21 == 0.0) {
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a11 == 1.0 && isInt(aff_uv2xy.a13)) {
Shinya Kitaoka 120a6e
        min_pix_ref_u = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_u = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a22 == 1.0 && isInt(aff_uv2xy.a23)) {
Shinya Kitaoka 120a6e
        min_pix_ref_v = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_v = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (aff_uv2xy.a11 == 0.0 && aff_uv2xy.a22 == 0.0) {
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a12 == 1.0 && isInt(aff_uv2xy.a13)) {
Shinya Kitaoka 120a6e
        min_pix_ref_v = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_v = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      if (aff_uv2xy.a21 == 1.0 && isInt(aff_uv2xy.a23)) {
Shinya Kitaoka 120a6e
        min_pix_ref_u = 0;
Shinya Kitaoka 120a6e
        max_pix_ref_u = 0;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  max_n_pix =
Shinya Kitaoka 120a6e
      (max_pix_ref_u - min_pix_ref_u + 1) * (max_pix_ref_v - min_pix_ref_v + 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (max_n_pix > current_max_n_pix) {
Shinya Kitaoka 120a6e
    current_max_n_pix = max_n_pix;
Shinya Kitaoka 120a6e
    pix_ref_u.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_v.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_f.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    pix_ref_g.reset(new int[current_max_n_pix]);
Shinya Kitaoka 120a6e
    assert(pix_ref_u && pix_ref_v && pix_ref_f && pix_ref_g);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  minmax(-1, -1, 0, 0, aff0_uv2fg, min_ref_out_f_, min_ref_out_g_,
Shinya Kitaoka 120a6e
         max_ref_out_f_, max_ref_out_g_);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_ref_out_f = tround(min_ref_out_f_);
Shinya Kitaoka 120a6e
  min_ref_out_g = tround(min_ref_out_g_);
Shinya Kitaoka 120a6e
  max_ref_out_f = tround(max_ref_out_f_);
Shinya Kitaoka 120a6e
  max_ref_out_g = tround(max_ref_out_g_);
Shinya Kitaoka 120a6e
  min_pix_ref_f = -filter_fg_radius - max_ref_out_f;
Shinya Kitaoka 120a6e
  min_pix_ref_g = -filter_fg_radius - max_ref_out_g;
Shinya Kitaoka 120a6e
  max_pix_ref_f = filter_fg_radius - min_ref_out_f;
Shinya Kitaoka 120a6e
  max_pix_ref_g = filter_fg_radius - min_ref_out_g;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  min_pix_out_f = c_maxint;
Shinya Kitaoka 120a6e
  min_pix_out_g = c_maxint;
Shinya Kitaoka 120a6e
  max_pix_out_f = c_minint;
Shinya Kitaoka 120a6e
  max_pix_out_g = c_minint;
Shinya Kitaoka 120a6e
  n_pix         = 0;
Shinya Kitaoka 120a6e
  for (cur_pix_ref_v = min_pix_ref_v; cur_pix_ref_v <= max_pix_ref_v;
Shinya Kitaoka 120a6e
       cur_pix_ref_v++)
Shinya Kitaoka 120a6e
    for (cur_pix_ref_u = min_pix_ref_u; cur_pix_ref_u <= max_pix_ref_u;
Shinya Kitaoka 120a6e
         cur_pix_ref_u++) {
Shinya Kitaoka 120a6e
      cur_pix_ref_f_ = affMV1(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Shinya Kitaoka 120a6e
      cur_pix_ref_g_ = affMV2(aff0_uv2fg, cur_pix_ref_u, cur_pix_ref_v);
Shinya Kitaoka 120a6e
      cur_pix_ref_f  = tround(cur_pix_ref_f_);
Shinya Kitaoka 120a6e
      cur_pix_ref_g  = tround(cur_pix_ref_g_);
Shinya Kitaoka 120a6e
      if (min_pix_ref_f <= cur_pix_ref_f && cur_pix_ref_f <= max_pix_ref_f &&
Shinya Kitaoka 120a6e
          min_pix_ref_g <= cur_pix_ref_g && cur_pix_ref_g <= max_pix_ref_g) {
Shinya Kitaoka 120a6e
        pix_ref_u[n_pix] = cur_pix_ref_u;
Shinya Kitaoka 120a6e
        pix_ref_v[n_pix] = cur_pix_ref_v;
Shinya Kitaoka 120a6e
        pix_ref_f[n_pix] = cur_pix_ref_f;
Shinya Kitaoka 120a6e
        pix_ref_g[n_pix] = cur_pix_ref_g;
Shinya Kitaoka 120a6e
        notMoreThan(cur_pix_ref_f + min_ref_out_f, min_pix_out_f);
Shinya Kitaoka 120a6e
        notMoreThan(cur_pix_ref_g + min_ref_out_g, min_pix_out_g);
Shinya Kitaoka 120a6e
        notLessThan(cur_pix_ref_f + max_ref_out_f, max_pix_out_f);
Shinya Kitaoka 120a6e
        notLessThan(cur_pix_ref_g + max_ref_out_g, max_pix_out_g);
Shinya Kitaoka 120a6e
        n_pix++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  assert(n_pix > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Shinya Kitaoka 120a6e
  if (flt_type != current_flt_type) {
Shinya Kitaoka 120a6e
    current_flt_type = flt_type;
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    min_filter_fg = -filter_fg_radius - FILTER_RESOLUTION * 3 / 2;
Shinya Kitaoka 120a6e
    max_filter_fg = filter_fg_radius + FILTER_RESOLUTION * 3 / 2;
Shinya Kitaoka 120a6e
    filter_size   = max_filter_fg - min_filter_fg + 1;
Shinya Kitaoka 120a6e
    if (filter_size > filter_array_size) {
Shinya Kitaoka 120a6e
      filter_array.reset(new short[filter_size]);
Shinya Kitaoka 120a6e
      assert(filter_array);
Shinya Kitaoka 120a6e
      filter_array_size = filter_size;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    filter    = filter_array.get() - min_filter_fg;
Shinya Kitaoka 120a6e
    filter[0] = MAX_FILTER_VAL;
Shinya Kitaoka 120a6e
    for (f = 1, s_ = 1.0 / FILTER_RESOLUTION; f < filter_fg_radius;
Shinya Kitaoka 120a6e
         f++, s_ += 1.0 / FILTER_RESOLUTION) {
Shinya Kitaoka 120a6e
      weight_    = get_filter_value(flt_type, s_) * (double)MAX_FILTER_VAL;
Shinya Kitaoka 120a6e
      weight     = tround(weight_);
Shinya Kitaoka 120a6e
      filter[f]  = weight;
Shinya Kitaoka 120a6e
      filter[-f] = weight;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    for (f = filter_fg_radius; f <= max_filter_fg; f++) filter[f] = 0;
Shinya Kitaoka 120a6e
    for (f = -filter_fg_radius; f >= min_filter_fg; f--) filter[f] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef USE_STATIC_VARS
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  min_pix_out_fg = std::min(min_pix_out_f, min_pix_out_g);
Shinya Kitaoka 120a6e
  max_pix_out_fg = std::max(max_pix_out_f, max_pix_out_g);
Shinya Kitaoka 120a6e
  if (min_pix_out_fg < min_filter_fg || max_pix_out_fg > max_filter_fg) {
Shinya Kitaoka 120a6e
    filter_size = max_pix_out_fg - min_pix_out_fg + 1;
Shinya Kitaoka 120a6e
    if (filter_size > filter_array_size) {
Shinya Kitaoka 120a6e
      // controllare!!
Shinya Kitaoka 120a6e
      // TREALLOC (filter_array, filter_size)
Shinya Kitaoka 120a6e
      filter_array.reset(new short[filter_size]);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      assert(filter_array);
Shinya Kitaoka 120a6e
      filter_array_size = filter_size;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    filter = filter_array.get() - min_filter_fg;
Shinya Kitaoka 120a6e
    if (min_pix_out_fg < min_filter_fg) {
Shinya Kitaoka 120a6e
      int delta = min_filter_fg - min_pix_out_fg;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (f              = max_filter_fg; f >= min_filter_fg; f--)
Shinya Kitaoka 120a6e
        filter[f + delta] = filter[f];
Shinya Kitaoka 120a6e
      filter += delta;
Shinya Kitaoka 120a6e
      for (f = min_filter_fg - 1; f >= min_pix_out_fg; f--) filter[f] = 0;
Shinya Kitaoka 120a6e
      min_filter_fg = min_pix_out_fg;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (max_pix_out_fg > max_filter_fg) {
Shinya Kitaoka 120a6e
      for (f = max_filter_fg + 1; f <= max_pix_out_fg; f++) filter[f] = 0;
Shinya Kitaoka 120a6e
      max_filter_fg = max_pix_out_fg;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Shinya Kitaoka 120a6e
  TRaster32P rout32 = rout;
Shinya Kitaoka 120a6e
  if ((TSystem::getCPUExtensions() & TSystem::CpuSupportsSse2) && rout32)
Shinya Kitaoka 120a6e
    resample_main_cm32_rgbm_SSE2<tpixel32>(</tpixel32>
Shinya Kitaoka 120a6e
        rout32, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
        max_pix_ref_u, max_pix_ref_v, n_pix, pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 120a6e
        pix_ref_f.get(), pix_ref_g.get(), filter, palette);
Shinya Kitaoka 120a6e
  else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    resample_main_cm32_rgbm<t>(</t>
Shinya Kitaoka 120a6e
        rout, rin, aff_xy2uv, aff0_uv2fg, min_pix_ref_u, min_pix_ref_v,
Shinya Kitaoka 120a6e
        max_pix_ref_u, max_pix_ref_v, n_pix, pix_ref_u.get(), pix_ref_v.get(),
Shinya Kitaoka 120a6e
        pix_ref_f.get(), pix_ref_g.get(), filter, palette);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TRop::resample(const TRasterP &out, const TRasterCM32P &in,
Shinya Kitaoka 120a6e
                    const TPaletteP palette, const TAffine &aff,
Shinya Kitaoka 120a6e
                    TRop::ResampleFilterType filterType, double blur) {
Shinya Kitaoka 120a6e
  TRasterP rin      = in;
Shinya Kitaoka 120a6e
  TRaster32P rout32 = out;
Shinya Kitaoka 120a6e
  in->lock();
Shinya Kitaoka 120a6e
  out->lock();
Shinya Kitaoka 120a6e
  if (rout32)
Shinya Kitaoka 120a6e
    rop_resample_rgbm_2<tpixel32>(rout32, rin, aff, filterType, blur,</tpixel32>
Shinya Kitaoka 120a6e
                                  palette.getPointer());
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    TRaster64P rout64 = out;
Shinya Kitaoka 120a6e
    if (rout64)
Shinya Kitaoka 120a6e
      rop_resample_rgbm_2<tpixel64>(rout64, rin, aff, filterType, blur,</tpixel64>
Shinya Kitaoka 120a6e
                                    palette.getPointer());
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      in->unlock();
Shinya Kitaoka 120a6e
      out->unlock();
Shinya Kitaoka 120a6e
      throw TRopException("unsupported pixel type");
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  in->unlock();
Shinya Kitaoka 120a6e
  out->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TNZCORE_LIGHT
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TRop::resample(const TRasterP &rout, const TRasterP &rin,
Shinya Kitaoka 120a6e
                    const TAffine &aff, ResampleFilterType filterType,
Shinya Kitaoka 120a6e
                    double blur) {
Shinya Kitaoka 120a6e
  rin->lock();
Shinya Kitaoka 120a6e
  rout->lock();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (filterType == ClosestPixel || filterType == Bilinear) {
Shinya Kitaoka 120a6e
    if ((TRaster64P)rout || (TRaster64P)rin)
Shinya Kitaoka 120a6e
      filterType = Triangle;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      quickResample(rout, rin, aff, filterType);
Shinya Kitaoka 120a6e
      rin->unlock();
Shinya Kitaoka 120a6e
      rout->unlock();
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRaster32P rout32 = rout, rin32 = rin;
Shinya Kitaoka 120a6e
  if (rout32) {
Shinya Kitaoka 120a6e
    if (!rin32) {
Shinya Kitaoka 120a6e
      rin32 = TRaster32P(rin->getLx(), rin->getLy());
Shinya Kitaoka 120a6e
      TRop::convert(rin32, rin);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    do_resample<tpixel32>(rout32, rin32, aff, filterType, blur);</tpixel32>
Shinya Kitaoka 120a6e
  } else {
Toshihiro Shimizu 890ddd
#ifndef TNZCORE_LIGHT
Shinya Kitaoka 120a6e
    TRasterCM32P routCM32 = rout, rinCM32 = rin;
Shinya Kitaoka 120a6e
    if (routCM32 && rinCM32)
Shinya Kitaoka 120a6e
      do_resample(routCM32, rinCM32, aff);
Shinya Kitaoka 120a6e
    else
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      TRaster64P rout64 = rout, rin64 = rin;
Shinya Kitaoka 120a6e
      if (rout64) {
Shinya Kitaoka 120a6e
        if (!rin64) {
Shinya Kitaoka 120a6e
          rin64 = TRaster64P(rin->getLx(), rin->getLy());
Shinya Kitaoka 120a6e
          TRop::convert(rin64, rin);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
        do_resample<tpixel64>(rout64, rin64, aff, filterType, blur);</tpixel64>
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        TRasterGR8P routGR8 = rout, rinGR8 = rin;
Shinya Kitaoka 120a6e
        TRaster32P rin32 = rin;
Shinya Kitaoka 120a6e
        if (routGR8 && rinGR8)
Shinya Kitaoka 120a6e
          do_resample(routGR8, rinGR8, aff, filterType, blur);
Shinya Kitaoka 120a6e
        else if (routGR8 && rin32)
Shinya Kitaoka 120a6e
          do_resample(routGR8, rin32, aff, filterType, blur);
Shinya Kitaoka 120a6e
        else {
Shinya Kitaoka 120a6e
          rin->unlock();
Shinya Kitaoka 120a6e
          rout->unlock();
Shinya Kitaoka 120a6e
          throw TRopException("unsupported pixel type");
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  rin->unlock();
Shinya Kitaoka 120a6e
  rout->unlock();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------