fix yafrtest
This commit is contained in:
parent
20aa5acb1b
commit
ae1763ae50
16
TODO
16
TODO
@ -1,3 +1,19 @@
|
|||||||
|
- built with O2, experiment with
|
||||||
|
|
||||||
|
- floorf()
|
||||||
|
- try commenting out the thing that calculates cardinal_one etc. to get
|
||||||
|
an idea of the possible speedup with LUTs
|
||||||
|
- time for uchar vs. vips-bilinear and new bilinear and float yafr
|
||||||
|
- can we build and time gegl?
|
||||||
|
|
||||||
|
|
||||||
|
add a vips_interpolate_get_method() which returns the function pointer, use
|
||||||
|
that in the inner loop instead of function dispatch
|
||||||
|
|
||||||
|
done ... try editing im_affinei and time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- vips_object_print, set_name etc. need writing
|
- vips_object_print, set_name etc. need writing
|
||||||
|
|
||||||
- im_buf_t -> VipsBuf
|
- im_buf_t -> VipsBuf
|
||||||
|
@ -56,14 +56,20 @@ typedef struct _VipsInterpolate {
|
|||||||
|
|
||||||
} VipsInterpolate;
|
} VipsInterpolate;
|
||||||
|
|
||||||
|
/* An interpolation function. This is a class method, but we have a lookup
|
||||||
|
* function for it to speed up dispatch.
|
||||||
|
*/
|
||||||
|
typedef void (*VipsInterpolateMethod)( VipsInterpolate *,
|
||||||
|
REGION *out, REGION *in,
|
||||||
|
int out_x, int out_y, double in_x, double in_y );
|
||||||
|
|
||||||
typedef struct _VipsInterpolateClass {
|
typedef struct _VipsInterpolateClass {
|
||||||
VipsObjectClass parent_class;
|
VipsObjectClass parent_class;
|
||||||
|
|
||||||
/* Write to pixel out(x,y), interpolating from in(x,y). The caller has
|
/* Write to pixel out(x,y), interpolating from in(x,y). The caller has
|
||||||
* to set the regions up.
|
* to set the regions up.
|
||||||
*/
|
*/
|
||||||
void (*interpolate)( VipsInterpolate *, REGION *out, REGION *in,
|
VipsInterpolateMethod interpolate;
|
||||||
int out_x, int out_y, double in_x, double in_y );
|
|
||||||
|
|
||||||
/* This interpolator needs a window this many pixels across and down.
|
/* This interpolator needs a window this many pixels across and down.
|
||||||
*/
|
*/
|
||||||
@ -77,6 +83,7 @@ typedef struct _VipsInterpolateClass {
|
|||||||
GType vips_interpolate_get_type( void );
|
GType vips_interpolate_get_type( void );
|
||||||
void vips_interpolate( VipsInterpolate *interpolate, REGION *out, REGION *in,
|
void vips_interpolate( VipsInterpolate *interpolate, REGION *out, REGION *in,
|
||||||
int out_x, int out_y, double in_x, double in_y );
|
int out_x, int out_y, double in_x, double in_y );
|
||||||
|
VipsInterpolateMethod vips_interpolate_get_method( VipsInterpolate * );
|
||||||
int vips_interpolate_get_window_size( VipsInterpolate *interpolate );
|
int vips_interpolate_get_window_size( VipsInterpolate *interpolate );
|
||||||
|
|
||||||
/* Nearest class starts.
|
/* Nearest class starts.
|
||||||
|
@ -213,6 +213,8 @@ affinei_gen( REGION *or, void *seq, void *a, void *b )
|
|||||||
const int window_size =
|
const int window_size =
|
||||||
vips_interpolate_get_window_size( affine->interpolate );
|
vips_interpolate_get_window_size( affine->interpolate );
|
||||||
const int half_window_size = window_size / 2;
|
const int half_window_size = window_size / 2;
|
||||||
|
VipsInterpolateMethod interpolate =
|
||||||
|
vips_interpolate_get_method( affine->interpolate );
|
||||||
|
|
||||||
/* Output area for this call.
|
/* Output area for this call.
|
||||||
*/
|
*/
|
||||||
@ -322,7 +324,8 @@ affinei_gen( REGION *or, void *seq, void *a, void *b )
|
|||||||
q[z] = 0;
|
q[z] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vips_interpolate( affine->interpolate, or, ir,
|
interpolate( affine->interpolate,
|
||||||
|
or, ir,
|
||||||
x, y, ix, iy );
|
x, y, ix, iy );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +142,19 @@ vips_interpolate( VipsInterpolate *interpolate, REGION *out, REGION *in,
|
|||||||
class->interpolate( interpolate, out, in, out_x, out_y, in_x, in_y );
|
class->interpolate( interpolate, out, in, out_x, out_y, in_x, in_y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* As above, but return the function pointer. Use this to cache method
|
||||||
|
* dispatch.
|
||||||
|
*/
|
||||||
|
VipsInterpolateMethod
|
||||||
|
vips_interpolate_get_method( VipsInterpolate *interpolate )
|
||||||
|
{
|
||||||
|
VipsInterpolateClass *class = VIPS_INTERPOLATE_GET_CLASS( interpolate );
|
||||||
|
|
||||||
|
g_assert( class->interpolate );
|
||||||
|
|
||||||
|
return( class->interpolate );
|
||||||
|
}
|
||||||
|
|
||||||
/* Get this interpolator's required window size.
|
/* Get this interpolator's required window size.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* vipsinterpolateyafr_test ... yarf as a vips interpolate class
|
/* vipsinterpolateyafr_test ... yafr as a vips interpolate class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -118,8 +118,8 @@ static VipsInterpolateClass *vips_interpolate_yafr_test_parent_class = NULL;
|
|||||||
* the interior of the bichromatic region.
|
* the interior of the bichromatic region.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Pointers to write to / read from, how much to add to move right a pixel,
|
/* Pointers to write to / read from, channel number, number of channels,
|
||||||
* how much to add to move down a line.
|
* how many bytes to add to move down a line.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* T is the type of pixels we are reading and writing.
|
/* T is the type of pixels we are reading and writing.
|
||||||
@ -128,12 +128,12 @@ static VipsInterpolateClass *vips_interpolate_yafr_test_parent_class = NULL;
|
|||||||
* for others we need float or even double.
|
* for others we need float or even double.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename T, typename D> static inline void
|
template <typename T, typename D> static void inline
|
||||||
catrom_yafr_test(
|
catrom_yafr_test(
|
||||||
PEL *out, PEL *in,
|
PEL *pout, const PEL *pin,
|
||||||
const int channels,
|
const int channels,
|
||||||
const int pixels_per_buffer_row,
|
const int lskip,
|
||||||
const float sharpening,
|
const double sharpening,
|
||||||
|
|
||||||
const float cardinal_one,
|
const float cardinal_one,
|
||||||
const float cardinal_two,
|
const float cardinal_two,
|
||||||
@ -205,26 +205,27 @@ catrom_yafr_test(
|
|||||||
* consideration. The in pointer is assumed
|
* consideration. The in pointer is assumed
|
||||||
* to point to uno_one when catrom_yafr_test is entered.
|
* to point to uno_one when catrom_yafr_test is entered.
|
||||||
*/
|
*/
|
||||||
|
const int pel_skip = lskip / sizeof( T );
|
||||||
|
|
||||||
const T uno_one = in[ 0 ];
|
const T uno_one = in[0 ];
|
||||||
const T uno_two = in[ channels];
|
const T uno_two = in[ channels ];
|
||||||
const T uno_thr = in[ 2 * channels];
|
const T uno_thr = in[2 * channels ];
|
||||||
const T uno_fou = in[ 3 * channels];
|
const T uno_fou = in[3 * channels ];
|
||||||
|
|
||||||
const T dos_one = in[ pixels_per_buffer_row * channels];
|
const T dos_one = in[ pel_skip];
|
||||||
const T dos_two = in[(1 + pixels_per_buffer_row) * channels];
|
const T dos_two = in[ channels + pel_skip];
|
||||||
const T dos_thr = in[(2 + pixels_per_buffer_row) * channels];
|
const T dos_thr = in[2 * channels + pel_skip];
|
||||||
const T dos_fou = in[(3 + pixels_per_buffer_row) * channels];
|
const T dos_fou = in[3 * channels + pel_skip];
|
||||||
|
|
||||||
const T tre_one = in[ 2 * pixels_per_buffer_row * channels];
|
const T tre_one = in[ 2 * pel_skip];
|
||||||
const T tre_two = in[(1 + 2 * pixels_per_buffer_row) * channels];
|
const T tre_two = in[ channels + 2 * pel_skip];
|
||||||
const T tre_thr = in[(2 + 2 * pixels_per_buffer_row) * channels];
|
const T tre_thr = in[2 * channels + 2 * pel_skip];
|
||||||
const T tre_fou = in[(3 + 2 * pixels_per_buffer_row) * channels];
|
const T tre_fou = in[3 * channels + 2 * pel_skip];
|
||||||
|
|
||||||
const T qua_one = in[ 3 * pixels_per_buffer_row * channels];
|
const T qua_one = in[ 3 * pel_skip];
|
||||||
const T qua_two = in[(1 + 3 * pixels_per_buffer_row) * channels];
|
const T qua_two = in[ channels + 3 * pel_skip];
|
||||||
const T qua_thr = in[(2 + 3 * pixels_per_buffer_row) * channels];
|
const T qua_thr = in[2 * channels + 3 * pel_skip];
|
||||||
const T qua_fou = in[(3 + 3 * pixels_per_buffer_row) * channels];
|
const T qua_fou = in[3 * channels + 3 * pel_skip];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Computation of the YAFR_TEST correction:
|
* Computation of the YAFR_TEST correction:
|
||||||
@ -548,8 +549,8 @@ vips_interpolate_yafr_test_interpolate( VipsInterpolate *interpolate,
|
|||||||
/* Pel size and line size.
|
/* Pel size and line size.
|
||||||
*/
|
*/
|
||||||
const int channels = in->im->Bands;
|
const int channels = in->im->Bands;
|
||||||
const int pixels_per_buffer_row =
|
const int lskip = IM_REGION_LSKIP( in );
|
||||||
IM_REGION_LSKIP( in ) / (sizeof( float ) * channels);
|
const int esize = IM_IMAGE_SIZEOF_ELEMENT( in->im );
|
||||||
|
|
||||||
/* Where we write the result.
|
/* Where we write the result.
|
||||||
*/
|
*/
|
||||||
@ -558,8 +559,8 @@ vips_interpolate_yafr_test_interpolate( VipsInterpolate *interpolate,
|
|||||||
/* Put this in a macro to save some typing.
|
/* Put this in a macro to save some typing.
|
||||||
*/
|
*/
|
||||||
#define CALL(T, D) \
|
#define CALL(T, D) \
|
||||||
catrom_yafr_test<T, D>(q + z, p + z, \
|
catrom_yafr_test<T, D>(q + z * esize, p + z * esize, \
|
||||||
channels, pixels_per_buffer_row, \
|
channels, lskip, \
|
||||||
yafr_test->sharpening, \
|
yafr_test->sharpening, \
|
||||||
cardinal_one, \
|
cardinal_one, \
|
||||||
cardinal_two, \
|
cardinal_two, \
|
||||||
@ -612,21 +613,22 @@ vips_interpolate_yafr_test_interpolate( VipsInterpolate *interpolate,
|
|||||||
|
|
||||||
case IM_BANDFMT_DOUBLE:
|
case IM_BANDFMT_DOUBLE:
|
||||||
for( int z = 0; z < channels; z++ )
|
for( int z = 0; z < channels; z++ )
|
||||||
CALL( float, float );
|
CALL( double, double );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
vips_interpolate_yafr_test_class_init( VipsInterpolateYafrTestClass *class )
|
vips_interpolate_yafr_test_class_init( VipsInterpolateYafrTestClass *iclass )
|
||||||
{
|
{
|
||||||
VipsInterpolateClass *interpolate_class =
|
VipsInterpolateClass *interpolate_class =
|
||||||
VIPS_INTERPOLATE_CLASS( class );
|
VIPS_INTERPOLATE_CLASS( iclass );
|
||||||
|
|
||||||
vips_interpolate_yafr_test_parent_class =
|
vips_interpolate_yafr_test_parent_class =
|
||||||
g_type_class_peek_parent( class );
|
VIPS_INTERPOLATE_CLASS( g_type_class_peek_parent( iclass ) );
|
||||||
|
|
||||||
interpolate_class->interpolate = vips_interpolate_yafr_test_interpolate;
|
interpolate_class->interpolate = vips_interpolate_yafr_test_interpolate;
|
||||||
interpolate_class->window_size = 4;
|
interpolate_class->window_size = 4;
|
||||||
@ -644,7 +646,7 @@ vips_interpolate_yafr_test_init( VipsInterpolateYafrTest *yafr_test )
|
|||||||
}
|
}
|
||||||
|
|
||||||
GType
|
GType
|
||||||
vips_interpolate_yafr_test_get_type( void )
|
vips_interpolate_yafr_test_get_type()
|
||||||
{
|
{
|
||||||
static GType type = 0;
|
static GType type = 0;
|
||||||
|
|
||||||
@ -662,7 +664,8 @@ vips_interpolate_yafr_test_get_type( void )
|
|||||||
};
|
};
|
||||||
|
|
||||||
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
|
type = g_type_register_static( VIPS_TYPE_INTERPOLATE,
|
||||||
"VipsInterpolateYafrTest", &info, 0 );
|
"VipsInterpolateYafrTest", &info,
|
||||||
|
(GTypeFlags) 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return( type );
|
return( type );
|
||||||
|
Loading…
Reference in New Issue
Block a user