deprecate im_contrast_surface()

slower than calling conv a few times
This commit is contained in:
John Cupitt 2013-11-03 12:24:46 +00:00
parent e1f2c06772
commit ad94488734
7 changed files with 40 additions and 267 deletions

View File

@ -10,6 +10,8 @@
- vipsthumbnail allows non-square bounding boxes, thanks seth
- add vips_matrixprint()
- add @point subsample mode to vips_subsample()
- im_contrast_surface() deprecated: it was slower than calling conv a few
times
18/10/13 started 7.36.3
- fix compiler warnings in ubuntu 13.10

1
TODO
View File

@ -1,4 +1,3 @@
- do conv and morph quickly as simple wrappers over the vips7 operations
- add vips_gaussian_blur() with approx / int / float precision, maybe

View File

@ -12,7 +12,6 @@ libconvolution_la_SOURCES = \
im_aconvsep.c \
im_conv.c \
im_conv_f.c \
im_contrast_surface.c \
im_fastcor.c \
im_gradcor.c \
im_sharpen.c \

View File

@ -1,263 +0,0 @@
/* im_contrast_surface
*
* Copyright: 2006, The Nottingham Trent University
*
* Author: Tom Vajzovic
* (based on algorithm by Nicos Dessipris & John Cupitt)
*
* Written on: 2006-03-13
* 3/2/10
* - gtkdoc
* - small cleanups
*/
/*
This file is part of VIPS.
VIPS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
/*
These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
*/
/** HEADERS **/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /*HAVE_CONFIG_H */
#ifdef NOT_IN_VIPS
#define _(s) (s)
#else
#include <vips/intl.h>
#endif
#include <stdlib.h>
#include <vips/vips.h>
#include <vips/region.h>
/** MACROS **/
/* from simple_macros.h */
#define LESSER(a,b) ((a)<(b)?(a):(b))
#define DOUBLE(a) ( (a)<<1 )
#define DOUBLE_ADD_ONE(a) ( 1 | ( (a)<<1 ) )
/** LOCAL TYPES **/
typedef struct cont_surf_params_s
{
int half_win_size;
int spacing;
} cont_surf_params_t;
/** LOCAL FUNCTIONS DECLARATIONS **/
int
im_contrast_surface (IMAGE * in, IMAGE * out, int half_win_size, int spacing);
int
im_contrast_surface_raw (IMAGE * in, IMAGE * out, int half_win_size,
int spacing);
static int cont_surf_gen (REGION * to_make, void *seq,
void *a, void * b);
static unsigned int calc_cont (REGION * reg, int win_size_less_one,
int x_left, int y_top);
/** EXPORTED FUNCTIONS **/
/**
* im_contrast_surface:
* @in: input image
* @out: output image
* @half_win_size: window radius
* @spacing: subsample output by this
*
* Generate an image where the value of each pixel represents the
* contrast within a window of half_win_size from the corresponsing
* point in the input image. Sub-sample by a factor of spacing.
*
* See also: im_spcor(), im_gradcor().
*
* Returns: 0 on success, -1 on error.
*/
int
im_contrast_surface (IMAGE * in, IMAGE * out, int half_win_size, int spacing)
{
IMAGE *t1 = im_open_local (out, "im_contrast_surface intermediate", "p");
if (!t1
|| im_embed (in, t1, 1, half_win_size, half_win_size,
in->Xsize + DOUBLE (half_win_size),
in->Ysize + DOUBLE (half_win_size))
|| im_contrast_surface_raw (t1, out, half_win_size, spacing))
return -1;
out->Xoffset = 0;
out->Yoffset = 0;
return 0;
}
int
im_contrast_surface_raw (IMAGE * in, IMAGE * out, int half_win_size,
int spacing)
{
#define FUNCTION_NAME "im_contrast_surface_raw"
cont_surf_params_t *params;
if (im_piocheck (in, out) ||
im_check_uncoded (FUNCTION_NAME, in) ||
im_check_mono (FUNCTION_NAME, in) ||
im_check_format (FUNCTION_NAME, in, IM_BANDFMT_UCHAR))
return -1;
if (half_win_size < 1 || spacing < 1)
{
im_error (FUNCTION_NAME, "%s", _("bad parameters"));
return -1;
}
if (DOUBLE (half_win_size) >= LESSER (in->Xsize, in->Ysize))
{
im_error (FUNCTION_NAME,
"%s", _("parameters would result in zero size output image"));
return -1;
}
params = IM_NEW (out, cont_surf_params_t);
if (!params)
return -1;
params->half_win_size = half_win_size;
params->spacing = spacing;
if (im_cp_desc (out, in))
return -1;
out->BandFmt = IM_BANDFMT_UINT;
out->Xsize = 1 + ((in->Xsize - DOUBLE_ADD_ONE (half_win_size)) / spacing);
out->Ysize = 1 + ((in->Ysize - DOUBLE_ADD_ONE (half_win_size)) / spacing);
out->Xoffset = -half_win_size;
out->Yoffset = -half_win_size;
if (im_demand_hint (out, IM_FATSTRIP, in, NULL))
return -1;
return im_generate (out, im_start_one, cont_surf_gen, im_stop_one, in,
params);
#undef FUNCTION_NAME
}
/** LOCAL FUNCTIONS DEFINITIONS **/
static int
cont_surf_gen (REGION * to_make, void * seq, void *unrequired, void * b)
{
/* I don't need *in, but I will recieve it anyway since im_start_one() needs it */
REGION * make_from = (REGION *) seq;
cont_surf_params_t * params = (cont_surf_params_t *) b;
unsigned int *row =
(unsigned int *) IM_REGION_ADDR (to_make, to_make->valid.left,
to_make->valid.top);
int xoff;
int y;
int bottom = to_make->valid.top + to_make->valid.height;
size_t lskip = IM_REGION_LSKIP (to_make) / sizeof (unsigned int);
Rect area = {
params->spacing * to_make->valid.left,
params->spacing * to_make->valid.top,
DOUBLE_ADD_ONE (params->half_win_size) +
(params->spacing * (to_make->valid.width - 1)),
DOUBLE_ADD_ONE (params->half_win_size) +
(params->spacing * (to_make->valid.height - 1))
};
if (im_prepare (make_from, &area)
|| !im_rect_equalsrect (&make_from->valid, &area))
return -1;
for (y = to_make->valid.top; y < bottom; ++y, row += lskip)
for (xoff = 0; xoff < to_make->valid.width; ++xoff)
row[xoff] =
calc_cont (make_from, DOUBLE (params->half_win_size),
(xoff + to_make->valid.left) * params->spacing,
y * params->spacing);
return 0;
}
static unsigned int
calc_cont (REGION * reg, int win_size_less_one, int x_left, int y_top)
{
unsigned char val;
unsigned char all_black = 1;
unsigned char *row;
unsigned int contrast = 0;
int xoff;
int yoff;
size_t lskip = IM_REGION_LSKIP (reg) / sizeof (unsigned char);
row = (unsigned char *) IM_REGION_ADDR (reg, x_left, y_top);
val = *row;
for (yoff = 0; yoff <= win_size_less_one && all_black; ++yoff, row += lskip)
for (xoff = 0; xoff <= win_size_less_one; ++xoff)
if (row[xoff] != val)
{
all_black = 0;
break;
}
if (all_black)
return contrast;
row = (unsigned char *) IM_REGION_ADDR (reg, x_left, y_top);
for (yoff = 0; yoff < win_size_less_one; ++yoff, row += lskip)
{
for (xoff = 0; xoff < win_size_less_one; ++xoff)
contrast +=
abs (row[xoff + 1] - row[xoff]) + abs (row[xoff + lskip] -
row[xoff]);
contrast += abs (row[xoff + lskip] - row[xoff]);
}
for (xoff = 0; xoff < win_size_less_one; ++xoff)
contrast += abs (row[xoff + 1] - row[xoff]);
return contrast;
}

View File

@ -2236,6 +2236,41 @@ im_addgnoise( IMAGE *in, IMAGE *out, double sigma )
return( 0 );
}
/* This replaces some custom code in 7.36 and earlier. The hand-made one was
* slower for spacing == 1, though faster for large values of spacing.
*
* Not worth maintaining a special operator for.
*/
int
im_contrast_surface (IMAGE * in, IMAGE * out, int half_win_size, int spacing)
{
VipsImage **t = (VipsImage **)
vips_object_local_array( VIPS_OBJECT( out ), 10 );
int size = half_win_size * 2;
int x, y;
t[0] = vips_image_new_matrixv( 1, 2, -1.0, 1.0 );
t[1] = vips_image_new_matrixv( 2, 1, -1.0, 1.0 );
t[8] = vips_image_new_matrix( size, size );
for( y = 0; y < size; y++ )
for( x = 0; x < size; x++ )
*VIPS_MATRIX( t[8], x, y ) = 1.0;
if( vips_conv( in, &t[2], t[0], NULL ) ||
vips_conv( in, &t[3], t[1], NULL ) ||
vips_abs( t[2], &t[4], NULL ) ||
vips_abs( t[3], &t[5], NULL ) ||
vips_add( t[4], t[5], &t[6], NULL ) ||
vips_conv( t[6], &t[7], t[8], NULL ) ||
vips_subsample( t[7], &t[9], spacing, spacing, NULL ) ||
vips_image_write( t[9], out ) )
return( -1 );
return( 0 );
}
static int
vips__round( VipsImage *in, VipsImage *out, VipsOperationRound round )
{

View File

@ -94,8 +94,6 @@ int im_grad_y( VipsImage *in, VipsImage *out );
int im_fastcor( VipsImage *in, VipsImage *ref, VipsImage *out );
int im_spcor( VipsImage *in, VipsImage *ref, VipsImage *out );
int im_gradcor( VipsImage *in, VipsImage *ref, VipsImage *out );
int im_contrast_surface( VipsImage *in, VipsImage *out,
int half_win_size, int spacing );
#ifdef __cplusplus
}

View File

@ -918,6 +918,9 @@ int im_lindetect( VipsImage *in, VipsImage *out, INTMASK *mask );
int im_addgnoise( VipsImage *in, VipsImage *out, double sigma );
int im_contrast_surface( VipsImage *in, VipsImage *out,
int half_win_size, int spacing );
#ifdef __cplusplus
}
#endif /*__cplusplus*/