Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Image filtering flow
// Calls "fetch" for each line to synthesize a temp image, then applies a 2D separable filter.
//
// The same general design can be applied to resampling, but now some of the buffers have
// different sizes, and the filter kernels are (in general) different in different rows/columns.
static FLOATIMG * img_filter_process_odd( fetch_row_func * fetch, void * user, int w, int h, ODDFILTER const * hfilt, ODDFILTER const * vfilt )
{
int ry = vfilt->radius;
int ntapsy = 2*ry + 1;
FLOATIMG * out = img_alloc( w, h );
FLOATIMG * temp = img_alloc( w, ntapsy + 1 ); // 1 fetch buffer + ntapsy horiz filtered scan lines
float const * rowptr[ MAXODDTAPS ];
int y;
int lastfetchy = -1;
if( !out || !temp )
{
img_free( out );
img_free( temp );
return 0;
}
// need to loop over a few extra rows to seed row buffers
for( y = -ry ; y < h + ry ; y++ )
{
int i;
// fetch row y (with clamp) to last row of temp.
i = boundary_condition( y );
if( i != lastfetchy )
{
fetch( img_row( temp, ntapsy ), i, user );
lastfetchy = i;
}
// horizontal filter to rolling temp buffer
i = ( y + ry ) % ntapsy;
img_hfilter_odd_row( img_row( temp, i ), img_row( temp, ntapsy ), w, hfilt );
// vertical filter and output stage
// this is delayed by ntapsy rows so that we filter only when all input data is available
//
// this version writes directly to "out"; could also write to another temp scanline
// buffer and have a "store" function (analogous to "fetch") that writes output.
if( y >= ry )
{
int yout = y - ry;
for( i = 0 ; i < ntapsy ; i++ )
rowptr[ i ] = img_row( temp, ( y + ry - ( ntapsy - 1 - i ) ) % ntapsy );
img_vfilter_odd_row( img_row( out, yout ), rowptr, w, vfilt->kernel, ntapsy );
}
}
return out;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment