static void vips_interpolate_bicubic_class_init( VipsInterpolateBicubicClass *iclass ) { VipsObjectClass *object_class = VIPS_OBJECT_CLASS( iclass ); VipsInterpolateClass *interpolate_class = VIPS_INTERPOLATE_CLASS( iclass ); object_class->nickname = "bicubic"; object_class->description = _( "Bicubic interpolation (Catmull-Rom)" ); interpolate_class->interpolate = vips_interpolate_bicubic_interpolate; interpolate_class->window_size = 4; /* Build the tables of pre-computed coefficients. */ for( int x = 0; x < VIPS_TRANSFORM_SCALE + 1; x++ ) { calculate_coefficients_catmull( (float) x / VIPS_TRANSFORM_SCALE, vips_bicubic_matrixf[x] ); for( int i = 0; i < 4; i++ ) vips_bicubic_matrixi[x][i] = vips_bicubic_matrixf[x][i] * VIPS_INTERPOLATE_SCALE; } }
/* Calculate a mask element. */ void vips_reduce_make_mask( double *c, VipsKernel kernel, double shrink, double x ) { switch( kernel ) { case VIPS_KERNEL_NEAREST: c[0] = 1.0; break; case VIPS_KERNEL_LINEAR: c[0] = 1.0 - x; c[1] = x; break; case VIPS_KERNEL_CUBIC: calculate_coefficients_catmull( c, x ); break; case VIPS_KERNEL_LANCZOS2: calculate_coefficients_lanczos( c, 2, shrink, x ); break; case VIPS_KERNEL_LANCZOS3: calculate_coefficients_lanczos( c, 3, shrink, x ); break; default: g_assert_not_reached(); break; } }
static void inline bicubic_notab( void *pout, const PEL *pin, const int bands, const int lskip, double x, double y ) { T* restrict out = (T *) pout; const T* restrict in = (T *) pin; const int b1 = bands; const int b2 = b1 + b1; const int b3 = b1 + b2; const int l1 = lskip / sizeof( T ); const int l2 = l1 + l1; const int l3 = l1 + l2; const int l1_plus_b1 = l1 + b1; const int l1_plus_b2 = l1 + b2; const int l1_plus_b3 = l1 + b3; const int l2_plus_b1 = l2 + b1; const int l2_plus_b2 = l2 + b2; const int l2_plus_b3 = l2 + b3; const int l3_plus_b1 = l3 + b1; const int l3_plus_b2 = l3 + b2; const int l3_plus_b3 = l3 + b3; double cx[4]; double cy[4]; calculate_coefficients_catmull( x, cx ); calculate_coefficients_catmull( y, cy ); for( int z = 0; z < bands; z++ ) { const T uno_one = in[0]; const T uno_two = in[b1]; const T uno_thr = in[b2]; const T uno_fou = in[b3]; const T dos_one = in[l1]; const T dos_two = in[l1_plus_b1]; const T dos_thr = in[l1_plus_b2]; const T dos_fou = in[l1_plus_b3]; const T tre_one = in[l2]; const T tre_two = in[l2_plus_b1]; const T tre_thr = in[l2_plus_b2]; const T tre_fou = in[l2_plus_b3]; const T qua_one = in[l3]; const T qua_two = in[l3_plus_b1]; const T qua_thr = in[l3_plus_b2]; const T qua_fou = in[l3_plus_b3]; const T bicubic = bicubic_float<T>( uno_one, uno_two, uno_thr, uno_fou, dos_one, dos_two, dos_thr, dos_fou, tre_one, tre_two, tre_thr, tre_fou, qua_one, qua_two, qua_thr, qua_fou, cx, cy ); out[z] = bicubic; in += 1; } }