diff --git a/doc/reference/libvips-docs.sgml.in b/doc/reference/libvips-docs.sgml.in index 7bed71d3..1e17901f 100644 --- a/doc/reference/libvips-docs.sgml.in +++ b/doc/reference/libvips-docs.sgml.in @@ -38,7 +38,7 @@ - + diff --git a/libvips/create/buildlut.c b/libvips/create/buildlut.c index a82c9703..a8a4d56b 100644 --- a/libvips/create/buildlut.c +++ b/libvips/create/buildlut.c @@ -60,8 +60,6 @@ #include "pcreate.h" -/* Our state. - */ typedef struct _VipsBuildlut { VipsCreate parent_instance; @@ -69,7 +67,7 @@ typedef struct _VipsBuildlut { */ VipsImage *in; - /* Cast to a matrix. + /* .. and cast to a matrix. */ VipsImage *mat; @@ -253,7 +251,7 @@ vips_buildlut_class_init( VipsBuildlutClass *class ) vobject_class->description = _( "build a look-up table" ); vobject_class->build = vips_buildlut_build; - VIPS_ARG_IMAGE( class, "in", 4, + VIPS_ARG_IMAGE( class, "in", 0, _( "Input" ), _( "Matrix of XY coordinates" ), VIPS_ARGUMENT_REQUIRED_INPUT, diff --git a/libvips/deprecated/vips7compat.c b/libvips/deprecated/vips7compat.c index 0ed52f9a..abd0ce4f 100644 --- a/libvips/deprecated/vips7compat.c +++ b/libvips/deprecated/vips7compat.c @@ -2488,6 +2488,30 @@ im_fgrey( IMAGE *out, const int xsize, const int ysize ) return( 0 ); } +int +im_buildlut( DOUBLEMASK *input, VipsImage *out ) +{ + VipsImage *mat; + VipsImage *x; + + mat = vips_image_new(); + if( im_mask2vips( input, mat ) ) + return( -1 ); + if( vips_buildlut( mat, &x, + NULL ) ) { + g_object_unref( mat ); + return( -1 ); + } + g_object_unref( mat ); + if( im_copy( x, out ) ) { + g_object_unref( x ); + return( -1 ); + } + g_object_unref( x ); + + return( 0 ); +} + int im_rightshift_size( IMAGE *in, IMAGE *out, int xshift, int yshift, int band_fmt ) diff --git a/libvips/histogram/Makefile.am b/libvips/histogram/Makefile.am index ae680788..a673b010 100644 --- a/libvips/histogram/Makefile.am +++ b/libvips/histogram/Makefile.am @@ -19,7 +19,6 @@ libhistogram_la_SOURCES = \ im_invertlut.c \ im_lhisteq.c \ im_maplut.c \ - im_buildlut.c \ im_project.c \ im_stdif.c \ tone.c diff --git a/libvips/histogram/im_buildlut.c b/libvips/histogram/im_buildlut.c deleted file mode 100644 index 8d8e895b..00000000 --- a/libvips/histogram/im_buildlut.c +++ /dev/null @@ -1,303 +0,0 @@ -/* Build a LUT from a set of x/y points. - * - * Written on: 26/9/06 - * - from im_invertlut() - * 9/10/06 - * - don't output x values - * 18/3/09 - * - saner limit and rounding behaviour - * 30/3/09 - * - argh, fixed again - * 22/6/09 - * - more fixes for tables that don't start at zero (thanks Jack) - * 23/3/10 - * - gtkdoc - */ - -/* - - 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 - - */ - -/* -#define DEBUG - */ - -#ifdef HAVE_CONFIG_H -#include -#endif /*HAVE_CONFIG_H*/ -#include - -#include -#include -#include - -#include - -/* Our state. - */ -typedef struct _State { - DOUBLEMASK *input; /* Input mask */ - int xlow; /* Index 0 in output is this x */ - int lut_size; /* Number of output elements to generate */ - double **data; /* Rows of unpacked matrix */ - double *buf; /* Ouput buffer */ -} State; - -/* Use this to sort our input rows by the first column. - */ -static int -compare( const void *a, const void *b ) -{ - double **r1 = (double **) a; - double **r2 = (double **) b; - - double diff = r1[0][0] - r2[0][0]; - - if( diff > 0 ) - return( 1 ); - else if( diff == 0 ) - return( 0 ); - else - return( -1 ); -} - -/* Free our state. - */ -static void -free_state( State *state ) -{ - if( state->data ) { - int i; - - for( i = 0; i < state->input->ysize; i++ ) - IM_FREE( state->data[i] ); - } - - IM_FREE( state->data ); - IM_FREE( state->buf ); -} - -/* Fill our state. - */ -static int -build_state( State *state, DOUBLEMASK *input ) -{ - int x, y, i; - int xlow, xhigh; - - state->input = input; - state->data = NULL; - - /* Need xlow and xhigh to get the size of the LUT we build. - */ - xlow = xhigh = input->coeff[0]; - for( y = 0; y < input->ysize; y++ ) { - double v = input->coeff[y * input->xsize]; - - if( floor( v ) != v ) { - im_error( "im_buildlut", - "%s", _( "x value not an int" ) ); - return( -1 ); - } - - if( v < xlow ) - xlow = v; - if( v > xhigh ) - xhigh = v; - } - state->xlow = xlow; - state->lut_size = xhigh - xlow + 1; - - if( state->lut_size < 1 ) { - im_error( "im_buildlut", "%s", _( "x range too small" ) ); - return( -1 ); - } - - if( !(state->data = IM_ARRAY( NULL, input->ysize, double * )) ) - return( -1 ); - for( y = 0; y < input->ysize; y++ ) - state->data[y] = NULL; - for( y = 0; y < input->ysize; y++ ) - if( !(state->data[y] = IM_ARRAY( NULL, input->xsize, double )) ) - return( -1 ); - - for( i = 0, y = 0; y < input->ysize; y++ ) - for( x = 0; x < input->xsize; x++, i++ ) - state->data[y][x] = input->coeff[i]; - - if( !(state->buf = IM_ARRAY( NULL, - state->lut_size * (input->xsize - 1), double )) ) - return( -1 ); - - /* Sort by 1st column in input. - */ - qsort( state->data, input->ysize, sizeof( double * ), compare ); - -#ifdef DEBUG - printf( "Input table, sorted by 1st column\n" ); - for( y = 0; y < input->ysize; y++ ) { - printf( "%.4d ", y ); - - for( x = 0; x < input->xsize; x++ ) - printf( "%.9f ", state->data[y][x] ); - - printf( "\n" ); - } -#endif /*DEBUG*/ - - return( 0 ); -} - -static int -buildlut( State *state ) -{ - const int xlow = state->xlow; - const DOUBLEMASK *input = state->input; - const int ysize = input->ysize; - const int xsize = input->xsize; - const int bands = xsize - 1; - const int xlast = state->data[ysize - 1][0]; - - int b, i, x; - - /* Do each output channel separately. - */ - for( b = 0; b < bands; b++ ) { - for( i = 0; i < ysize - 1; i++ ) { - const int x1 = state->data[i][0]; - const int x2 = state->data[i + 1][0]; - const int dx = x2 - x1; - const double y1 = state->data[i][b + 1]; - const double y2 = state->data[i + 1][b + 1]; - const double dy = y2 - y1; - - for( x = 0; x < dx; x++ ) - state->buf[b + (x + x1 - xlow) * bands] = - y1 + x * dy / dx; - } - - /* We are inclusive: pop the final value in by hand. - */ - state->buf[b + (xlast - xlow) * bands] = - state->data[ysize - 1][b + 1]; - } - - return( 0 ); -} - -/** - * im_buildlut: - * @input: input mask - * @output: output image - * - * This operation builds a lookup table from a set of points. Intermediate - * values are generated by piecewise linear interpolation. - * - * For example, consider this 2 x 2 matrix of (x, y) coordinates: - * - * - * - * - * 0 - * 0 - * - * - * 255 - * 100 - * - * - * - * - * We then generate: - * - * - * - * - * Index - * Value - * - * - * - * - * 0 - * 0 - * - * - * 1 - * 0.4 - * - * - * ... - * etc. by linear interpolation - * - * - * 255 - * 100 - * - * - * - * - * This is then written as the output image, with the left column giving the - * index in the image to place the value. - * - * The (x, y) points don't need to be sorted: we do that. You can have - * several Ys, each becomes a band in the output LUT. You don't need to - * start at zero, any integer will do, including negatives. - * - * See also: im_identity(), im_invertlut(). - * - * Returns: 0 on success, -1 on error - */ -int -im_buildlut( DOUBLEMASK *input, IMAGE *output ) -{ - State state; - - if( !input || input->xsize < 2 || input->ysize < 1 ) { - im_error( "im_buildlut", "%s", _( "bad input matrix size" ) ); - return( -1 ); - } - - if( build_state( &state, input ) || - buildlut( &state ) ) { - free_state( &state ); - return( -1 ); - } - - im_initdesc( output, - state.lut_size, 1, input->xsize - 1, - IM_BBITS_DOUBLE, IM_BANDFMT_DOUBLE, - IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); - if( im_setupout( output ) || - im_writeline( 0, output, (VipsPel *) state.buf ) ) { - free_state( &state ); - return( -1 ); - } - - free_state( &state ); - - return( 0 ); -} diff --git a/libvips/include/vips/Makefile.am b/libvips/include/vips/Makefile.am index 837cefff..0896042a 100644 --- a/libvips/include/vips/Makefile.am +++ b/libvips/include/vips/Makefile.am @@ -18,7 +18,7 @@ pkginclude_HEADERS = \ inplace.h \ generate.h \ header.h \ - histograms_lut.h \ + histogram.h \ freq_filt.h \ image.h \ interpolate.h \ diff --git a/libvips/include/vips/histograms_lut.h b/libvips/include/vips/histogram.h similarity index 96% rename from libvips/include/vips/histograms_lut.h rename to libvips/include/vips/histogram.h index 67742016..8aa15a53 100644 --- a/libvips/include/vips/histograms_lut.h +++ b/libvips/include/vips/histogram.h @@ -31,8 +31,8 @@ */ -#ifndef IM_HIST_H -#define IM_HIST_H +#ifndef VIPS_HISTOGRAM_H +#define VIPS_HISTOGRAM_H #ifdef __cplusplus extern "C" { @@ -45,7 +45,6 @@ int im_hist_indexed( VipsImage *index, VipsImage *value, VipsImage *out ); int im_identity( VipsImage *lut, int bands ); int im_identity_ushort( VipsImage *lut, int bands, int sz ); int im_invertlut( DOUBLEMASK *input, VipsImage *output, int lut_size ); -int im_buildlut( DOUBLEMASK *input, VipsImage *output ); int im_project( VipsImage *in, VipsImage *hout, VipsImage *vout ); int im_histnorm( VipsImage *in, VipsImage *out ); @@ -83,4 +82,4 @@ int im_tone_map( VipsImage *in, VipsImage *out, VipsImage *lut ); } #endif /*__cplusplus*/ -#endif /*IM_HIST_H*/ +#endif /*VIPS_HISTOGRAM_H*/ diff --git a/libvips/include/vips/vips.h b/libvips/include/vips/vips.h index d5df3b4f..85078776 100644 --- a/libvips/include/vips/vips.h +++ b/libvips/include/vips/vips.h @@ -129,7 +129,7 @@ extern "C" { #include #include #include -#include +#include #include #include #include diff --git a/libvips/include/vips/vips7compat.h b/libvips/include/vips/vips7compat.h index 407968dd..12a64027 100644 --- a/libvips/include/vips/vips7compat.h +++ b/libvips/include/vips/vips7compat.h @@ -733,6 +733,7 @@ int im_grey( VipsImage *out, const int xsize, const int ysize ); int im_fgrey( VipsImage *out, const int xsize, const int ysize ); int im_sines( VipsImage *out, int xsize, int ysize, double horfreq, double verfreq ); +int im_buildlut( DOUBLEMASK *input, VipsImage *output ); int im_system( VipsImage *im, const char *cmd, char **out ); VipsImage *im_system_image( VipsImage *im,