diff --git a/doc/reference/libvips-docs.sgml.in b/doc/reference/libvips-docs.sgml.in
index a0ff1f2f..b771a7e2 100644
--- a/doc/reference/libvips-docs.sgml.in
+++ b/doc/reference/libvips-docs.sgml.in
@@ -37,11 +37,11 @@
+
VIPS operation API by section (no gtkdoc comments yet)
-
diff --git a/libvips/conversion/im_gaussnoise.c b/libvips/conversion/im_gaussnoise.c
index 49754624..a94a2b36 100644
--- a/libvips/conversion/im_gaussnoise.c
+++ b/libvips/conversion/im_gaussnoise.c
@@ -105,7 +105,7 @@ gnoise_gen( REGION *or, void *seq, void *a, void *b )
/**
* im_gaussnoise:
- * @out: output #IMAGE
+ * @out: output image
* @x: output width
* @y: output height
* @mean: average value in output
@@ -115,7 +115,7 @@ gnoise_gen( REGION *or, void *seq, void *a, void *b )
* distribution. The noise distribution is created by averaging 12 random
* numbers with the appropriate weights.
*
- * See also: im_make_xy(), im_text(), im_black().
+ * See also: im_addgnoise(), im_make_xy(), im_text(), im_black().
*
* Returns: 0 on success, -1 on error
*/
diff --git a/libvips/conversion/im_system_image.c b/libvips/conversion/im_system_image.c
index 8121faa1..958897e8 100644
--- a/libvips/conversion/im_system_image.c
+++ b/libvips/conversion/im_system_image.c
@@ -113,6 +113,15 @@ system_image( IMAGE *im,
*
* In all cases, @log must be freed with im_free().
*
+ * For example, this call will run the ImageMagick convert program on an
+ * image, using JPEG files to pass images into and out of the convert command.
+ *
+ * |[
+ * im_system_image( in, out,
+ * "%s.jpg", "%s.jpg", "convert %s -swirl 45 %s",
+ * &log )
+ * ]|
+ *
* See also: im_system().
*
* Returns: an image on success, NULL on error
diff --git a/libvips/convolution/im_addgnoise.c b/libvips/convolution/im_addgnoise.c
index 87de342a..7ab0beed 100644
--- a/libvips/convolution/im_addgnoise.c
+++ b/libvips/convolution/im_addgnoise.c
@@ -1,15 +1,4 @@
-/* @(#) Add gaussian noise with mean 0 and variance sigma to image
- * @(#) The noise is generated by averaging 12 random numbers
- * @(#) page 78 PIETGEN 1989 n = 12
- * @(#) Input image is any, output is float
- * @(#) If running on SYSTEM V CONSTANT should be replaced by 2**15 - 1
- * @(#) Usage
- * @(#)
- * @(#) int im_addgnoise(imin, imout, sigma)
- * @(#) IMAGE *imin, *imout;
- * @(#) double sigma;
- * @(#) Returns 0 on success and -1 on error
- * @(#)
+/* im_addgnoise
*
* Copyright 1990, N. Dessipris.
*
@@ -26,6 +15,9 @@
* 2008-01-28 tcv:
* - now works (was broken)
* - no limit on bands
+ * 4/2/10
+ * - no need to bandup here now, im_add() does that
+ * - gtkdoc
*/
/*
@@ -66,25 +58,29 @@
#include
#endif /*WITH_DMALLOC*/
+/**
+ * im_addgnoise:
+ * @in: input image
+ * @out: output image
+ * @sigma: standard deviation of noise
+ *
+ * Add gaussian noise with mean 0 and variance sigma to @in.
+ * The noise is generated by averaging 12 random numbers,
+ * see page 78, PIETGEN, 1989.
+ *
+ * See also: im_gaussnoise().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int
-im_addgnoise( IMAGE *in, IMAGE *out, double sigma ){
-#define FUNCTION_NAME "im_addgnoise"
+im_addgnoise( IMAGE *in, IMAGE *out, double sigma )
+{
+ IMAGE *t;
- if( im_piocheck( in, out ))
- return -1;
- {
- int i;
- IMAGE **temps= IM_ARRAY( out, in-> Bands, IMAGE* );
- IMAGE *joined_temps= im_open_local( out, FUNCTION_NAME ": joined_temps", "p" );
+ if( !(t = im_open_local( out, "im_addgnoise", "p" )) ||
+ im_gaussnoise( t, in->Xsize, in->Ysize, 0, sigma ) ||
+ im_add( in, t, out ) )
+ return( -1 );
- if( ! temps || ! joined_temps || im_open_local_array( out, temps, in-> Bands, FUNCTION_NAME ": temps", "p" ))
- return -1;
-
- for( i= 0; i < in-> Bands; ++i )
- if( im_gaussnoise( temps[i], in-> Xsize, in-> Ysize, 0.0, sigma ))
- return -1;
-
- return im_gbandjoin( temps, joined_temps, in-> Bands ) || im_add( in, joined_temps, out );
- }
-#undef FUNCTION_NAME
+ return( 0 );
}
diff --git a/libvips/convolution/im_compass.c b/libvips/convolution/im_compass.c
index 7b357da7..8f24f811 100644
--- a/libvips/convolution/im_compass.c
+++ b/libvips/convolution/im_compass.c
@@ -1,28 +1,12 @@
-/* @(#) im_complass: Optimised convolution for line detection
- * @(#) Uses the entered mask and 7 rotated versions of it (each by 45 degrees)
- * @(#)
- * @(#) Usage
- * @(#) int im_compass( in, out, m )
- * @(#) IMAGE *in, *out;
- * @(#) INTMASK *m;
- * @(#)
- * @(#) Returns 0 on sucess and -1 on error
- * @(#)
- * @(#) Returns an int pointer to valid offsets for rotating a square mask
- * @(#) of odd size by 45 degrees.
- * @(#)
- * @(#) Usage
- * @(#) int *im_offsets45( size )
- * @(#) int size;
- * @(#)
- * @(#) Returns an int pointer to valid offsets on sucess and -1 on error
- * @(#)
+/* im_compass
*
* Author: N. Dessipris (Copyright, N. Dessipris 1991)
* Written on: 08/05/1991
* Modified on:
* 11/3/01 JC
* - rewritten, calling im_conv() and im_maxvalue()
+ * 3/2/10
+ * - gtkdoc
*/
/*
@@ -67,6 +51,20 @@
#include
#endif /*WITH_DMALLOC*/
+/**
+ * im_compass:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * @in is convolved 8 times with @mask, each time @mask is rotated by 45
+ * degrees. Each output pixel is the largest absolute value of the 8
+ * convolutions.
+ *
+ * See also: im_lindetect(), im_gradient(), im_conv().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int
im_compass( IMAGE *in, IMAGE *out, INTMASK *mask )
{
@@ -94,6 +92,20 @@ im_compass( IMAGE *in, IMAGE *out, INTMASK *mask )
return( im_maxvalue( absed, out, 8 ) );
}
+/**
+ * im_lindetect:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * @in is convolved four times with @mask, each time @mask is rotated by 45
+ * degrees. Each output pixel is the largest absolute value of the four
+ * convolutions.
+ *
+ * See also: im_compass(), im_gradient(), im_conv().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int
im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
{
@@ -121,15 +133,26 @@ im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
return( im_maxvalue( absed, out, 4 ) );
}
-#define GTEMPS (4)
-
+/**
+ * im_gradient:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * @in is convolved with @mask and with @mask after a 90 degree rotation. The
+ * result is the sum of the absolute value of the two convolutions.
+ *
+ * See also: im_lindetect(), im_gradient(), im_conv().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int
im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
{
- IMAGE *t[GTEMPS];
+ IMAGE *t[4];
INTMASK *rmask;
- if( im_open_local_array( out, t, GTEMPS, "im_gradient", "p" ) )
+ if( im_open_local_array( out, t, 4, "im_gradient", "p" ) )
return( -1 );
if( !(rmask = (INTMASK *) im_local( out,
diff --git a/libvips/convolution/im_contrast_surface.c b/libvips/convolution/im_contrast_surface.c
index 17515d6d..9731ed0f 100644
--- a/libvips/convolution/im_contrast_surface.c
+++ b/libvips/convolution/im_contrast_surface.c
@@ -1,27 +1,4 @@
-/* @(#) 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.
- * @(#)
- * @(#) Pixels beyond the edges of the image are considered to be have the
- * @(#) value zero (black).
- * @(#)
- * @(#) Input must be single-band uncoded uchar, WIO or PIO.
- * @(#)
- * @(#) Output is single-band uncoded uint, WIO or PIO.
- * @(#)
- * @(#) int
- * @(#) im_contrast_surface(
- * @(#) IMAGE *in,
- * @(#) IMAGE *out,
- * @(#) int half_win_size,
- * @(#) int spacing
- * @(#) );
- * @(#)
- * @(#) Returns either 0 (success) or -1 (fail)
- * @(#)
- * @(#) Also: im_contrast_surface_raw(). As above, but pixels within
- * @(#) half_win_size of the edge are not calculated, and output is smaller
- * @(#) accordingly.
+/* im_contrast_surface
*
* Copyright: 2006, The Nottingham Trent University
*
@@ -29,6 +6,9 @@
* (based on algorithm by Nicos Dessipris & John Cupitt)
*
* Written on: 2006-03-13
+ * 3/2/10
+ * - gtkdoc
+ * - small cleanups
*/
/*
@@ -111,6 +91,21 @@ static unsigned int calc_cont (REGION * reg, int win_size_less_one,
/** 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)
{
@@ -138,16 +133,12 @@ im_contrast_surface_raw (IMAGE * in, IMAGE * out, int half_win_size,
cont_surf_params_t *params;
- if (im_piocheck (in, out))
+ 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 (IM_CODING_NONE != in->Coding || IM_BANDFMT_UCHAR != in->BandFmt
- || 1 != in->Bands)
- {
- im_error (FUNCTION_NAME, "%s", _("one band uncoded uchar only"));
- return -1;
- }
-
if (half_win_size < 1 || spacing < 1)
{
im_error (FUNCTION_NAME, "%s", _("bad parameters"));
diff --git a/libvips/convolution/im_conv.c b/libvips/convolution/im_conv.c
index dc0c9ada..069854ca 100644
--- a/libvips/convolution/im_conv.c
+++ b/libvips/convolution/im_conv.c
@@ -1,27 +1,4 @@
-/* @(#) Convolve an image with an INTMASK. Image can have any number of bands,
- * @(#) any non-complex type. Size and type of output image matches type of
- * @(#) input image.
- * @(#)
- * @(#) int
- * @(#) im_conv( in, out, mask )
- * @(#) IMAGE *in, *out;
- * @(#) INTMASK *mask;
- * @(#)
- * @(#) Also: im_conv_raw(). As above, but does not add a black border.
- * @(#)
- * @(#) Returns either 0 (success) or -1 (fail)
- * @(#)
- * @(#) Old code, kept for use of other old code in this package:
- * @(#)
- * @(#) Creates int luts for all non zero elm of the original mask;
- * @(#) which is kept in buffer of length buffersize
- * @(#) cnt is needed for freeing luts. Called by the above.
- * @(#)
- * @(#) int im__create_int_luts( buffer, buffersize, orig_luts, luts, cnt )
- * @(#) int *buffer, buffersize;
- * @(#) int **orig_luts, **luts, *cnt;
- * @(#)
- * @(#) Returns either 0 (sucess) or -1 (fail)
+/* im_conv
*
* Copyright: 1990, N. Dessipris.
*
@@ -71,6 +48,9 @@
* - only check for non-zero elements once
* - add mask-all-zero check
* - cleanups
+ * 3/2/10
+ * - gtkdoc
+ * - more cleanups
*/
/*
@@ -285,7 +265,7 @@ conv_start( IMAGE *out, void *a, void *b )
i += 1; \
}
-/* INT and FLOAT inner loops.
+/* INT inner loops.
*/
#define CONV_INT( TYPE, IM_CLIP ) { \
TYPE ** restrict p = (TYPE **) seq->pts; \
@@ -307,6 +287,8 @@ conv_start( IMAGE *out, void *a, void *b )
} \
}
+/* FLOAT inner loops.
+ */
#define CONV_FLOAT( TYPE ) { \
TYPE ** restrict p = (TYPE **) seq->pts; \
TYPE * restrict q = (TYPE *) IM_REGION_ADDR( or, le, y ); \
@@ -434,14 +416,9 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
*/
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_conv", in ) ||
- im_check_noncomplex( "im_conv", in ) )
+ im_check_noncomplex( "im_conv", in ) ||
+ im_check_imask( "im_conv", mask ) )
return( -1 );
- if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
- mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
- mask->scale == 0 ) {
- im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
- return( -1 );
- }
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@@ -460,10 +437,8 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
- if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
- return( -1 );
-
- if( im_generate( out, conv_start, conv_gen, conv_stop, in, conv ) )
+ if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ||
+ im_generate( out, conv_start, conv_gen, conv_stop, in, conv ) )
return( -1 );
out->Xoffset = -mask->xsize / 2;
@@ -472,7 +447,24 @@ im_conv_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
return( 0 );
}
-/* The above, with a border to make out the same size as in.
+/**
+ * im_conv:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * Convolve @in with @mask using integer arithmetic. The output image
+ * always has the same #VipsBandFmt as the input image. Non-complex images
+ * only.
+ *
+ * Each output pixel is
+ * calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
+ * and offset are part of @mask. For integer @in, the division by scale
+ * includes round-to-nearest.
+ *
+ * See also: im_conv_f(), im_convsep(), im_create_imaskv().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_conv( IMAGE *in, IMAGE *out, INTMASK *mask )
diff --git a/libvips/convolution/im_conv_f.c b/libvips/convolution/im_conv_f.c
index b312550e..edb58a5a 100644
--- a/libvips/convolution/im_conv_f.c
+++ b/libvips/convolution/im_conv_f.c
@@ -1,14 +1,4 @@
-/* @(#) Convolve an image with a DOUBLEMASK. Image can have any number of bands,
- * @(#) any non-complex type. Output is IM_BANDFMT_FLOAT for all non-complex inputs
- * @(#) except IM_BANDFMT_DOUBLE, which gives IM_BANDFMT_DOUBLE.
- * @(#)
- * @(#) int
- * @(#) im_conv_f( in, out, mask )
- * @(#) IMAGE *in, *out;
- * @(#) DOUBLEMASK *mask;
- * @(#)
- * @(#) Returns either 0 (success) or -1 (fail)
- * @(#)
+/* im_conv_f
*
* Copyright: 1990, N. Dessipris.
*
@@ -43,6 +33,9 @@
* 13/11/09
* - rename as im_conv_f() to make it easier to vips.c to make the
* overloaded version
+ * 3/2/10
+ * - gtkdoc
+ * - more cleanups
*/
/*
@@ -320,14 +313,9 @@ im_conv_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
*/
if( im_piocheck( in, out ) ||
im_check_uncoded( "im_conv", in ) ||
- im_check_noncomplex( "im_conv", in ) )
+ im_check_noncomplex( "im_conv", in ) ||
+ im_check_dmask( "im_conv", mask ) )
return( -1 );
- if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
- mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
- mask->scale == 0 ) {
- im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
- return( -1 );
- }
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@@ -360,7 +348,24 @@ im_conv_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
return( 0 );
}
-/* The above, with a border to make out the same size as in.
+/**
+ * im_conv_f:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * Convolve @in with @mask using floating-point arithmetic. The output image
+ * is always %IM_BANDFMT_FLOAT unless @in is %IM_BANDFMT_DOUBLE, in which case
+ * @out is also %IM_BANDFMT_DOUBLE. Non-complex images
+ * only.
+ *
+ * Each output pixel is
+ * calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
+ * and offset are part of @mask.
+ *
+ * See also: im_conv(), im_convsep_f(), im_create_dmaskv().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_conv_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
diff --git a/libvips/convolution/im_convsep.c b/libvips/convolution/im_convsep.c
index 19380219..8adc52b2 100644
--- a/libvips/convolution/im_convsep.c
+++ b/libvips/convolution/im_convsep.c
@@ -1,15 +1,4 @@
-/* @(#) Convolve an image with a seperable (1xN, or Nx1) INTMASK. Image can
- * @(#) have any number of bands, any non-complex type. Size and type of
- * @(#) output image matches type of input image.
- * @(#)
- * @(#) int
- * @(#) im_convsep( in, out, mask )
- * @(#) IMAGE *in, *out;
- * @(#) INTMASK *mask;
- * @(#)
- * @(#) Also: im_convsep_raw(). As above, but does not add a black border.
- * @(#)
- * @(#) Returns either 0 (success) or -1 (fail)
+/* im_convsep
*
* Copyright: 1990, N. Dessipris.
*
@@ -29,6 +18,9 @@
* overflow on intermediates
* 12/5/08
* - int rounding was +1 too much, argh
+ * 3/2/10
+ * - gtkdoc
+ * - more cleanups
*/
/*
@@ -379,24 +371,16 @@ im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
/* Check parameters.
*/
- if( !in || in->Coding != IM_CODING_NONE ||
- vips_bandfmt_iscomplex( in->BandFmt ) ) {
- im_error( "im_convsep", "%s", _( "non-complex uncoded only" ) );
+ if( im_piocheck( in, out ) ||
+ im_check_uncoded( "im_convsep", in ) ||
+ im_check_noncomplex( "im_convsep", in ) ||
+ im_check_imask( "im_convsep", mask ) )
return( -1 );
- }
- if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
- mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
- mask->scale == 0 ) {
- im_error( "im_convsep", "%s", _( "nonsense mask parameters" ) );
- return( -1 );
- }
if( mask->xsize != 1 && mask->ysize != 1 ) {
im_error( "im_convsep",
"%s", _( "expect 1xN or Nx1 input mask" ) );
return( -1 );
}
- if( im_piocheck( in, out ) )
- return( -1 );
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@@ -424,7 +408,32 @@ im_convsep_raw( IMAGE *in, IMAGE *out, INTMASK *mask )
return( 0 );
}
-/* The above, with a border to make out the same size as in.
+
+/**
+ * im_convsep:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * Perform a separable convolution of @in with @mask using integer arithmetic.
+ *
+ * The mask must be 1xn or nx1 elements.
+ * The output image
+ * always has the same #VipsBandFmt as the input image. Non-complex images
+ * only.
+ *
+ * The image is convolved twice: once with @mask and then again with @mask
+ * rotated by 90 degrees. This is much faster for certain types of mask
+ * (gaussian blur, for example) than doing a full 2D convolution.
+ *
+ * Each output pixel is
+ * calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
+ * and offset are part of @mask. For integer @in, the division by scale
+ * includes round-to-nearest.
+ *
+ * See also: im_convsep_f(), im_conv(), im_create_imaskv().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_convsep( IMAGE *in, IMAGE *out, INTMASK *mask )
diff --git a/libvips/convolution/im_convsep_f.c b/libvips/convolution/im_convsep_f.c
index 65346373..0f752f11 100644
--- a/libvips/convolution/im_convsep_f.c
+++ b/libvips/convolution/im_convsep_f.c
@@ -1,14 +1,4 @@
-/* @(#) Convolve an image with a DOUBLEMASK. Image can have any number of bands,
- * @(#) any non-complex type. Output is IM_BANDFMT_FLOAT for all non-complex inputs
- * @(#) except IM_BANDFMT_DOUBLE, which gives IM_BANDFMT_DOUBLE.
- * @(#) Separable mask of sizes 1xN or Nx1
- * @(#)
- * @(#) int im_convsep_f( in, out, mask )
- * @(#) IMAGE *in, *out;
- * @(#) DOUBLEMASK *mask; details in mask.h
- * @(#)
- * @(#) Returns either 0 (sucess) or -1 (fail)
- * @(#) Picture can have any number of channels (max 64).
+/* im_convsep_f
*
* Copyright: 1990, N. Dessipris.
*
@@ -21,6 +11,9 @@
* - now uses im_embed() with edge stretching on the input, not
* the output
* - sets Xoffset / Yoffset
+ * 3/2/10
+ * - gtkdoc
+ * - more cleanups
*/
/*
@@ -81,10 +74,7 @@ typedef struct {
static int
conv_destroy( Conv *conv )
{
- if( conv->mask ) {
- (void) im_free_dmask( conv->mask );
- conv->mask = NULL;
- }
+ IM_FREEF( im_free_dmask, conv->mask );
return( 0 );
}
@@ -285,26 +275,16 @@ im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
/* Check parameters.
*/
- if( !in ||
- in->Coding != IM_CODING_NONE ||
- vips_bandfmt_iscomplex( in->BandFmt ) ) {
- im_error( "im_convsep_f",
- "%s", _( "non-complex uncoded only" ) );
+ if( im_piocheck( in, out ) ||
+ im_check_uncoded( "im_convsep_f", in ) ||
+ im_check_noncomplex( "im_convsep_f", in ) ||
+ im_check_dmask( "im_convsep_f", mask ) )
return( -1 );
- }
- if( !mask || mask->xsize > 1000 || mask->ysize > 1000 ||
- mask->xsize <= 0 || mask->ysize <= 0 || !mask->coeff ||
- mask->scale == 0 ) {
- im_error( "im_convsep_f", "%s", _( "bad mask parameters" ) );
- return( -1 );
- }
if( mask->xsize != 1 && mask->ysize != 1 ) {
im_error( "im_convsep_f",
"%s", _( "expect 1xN or Nx1 input mask" ) );
return( -1 );
}
- if( im_piocheck( in, out ) )
- return( -1 );
if( !(conv = conv_new( in, out, mask )) )
return( -1 );
@@ -335,7 +315,32 @@ im_convsep_f_raw( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
return( 0 );
}
-/* The above, with a border to make out the same size as in.
+/**
+ * im_convsep_f:
+ * @in: input image
+ * @out: output image
+ * @mask: convolution mask
+ *
+ * Perform a separable convolution of @in with @mask using floating-point
+ * arithmetic.
+ *
+ * The mask must be 1xn or nx1 elements.
+ * The output image
+ * is always %IM_BANDFMT_FLOAT unless @in is %IM_BANDFMT_DOUBLE, in which case
+ * @out is also %IM_BANDFMT_DOUBLE. Non-complex images
+ * only.
+ *
+ * The image is convolved twice: once with @mask and then again with @mask
+ * rotated by 90 degrees. This is much faster for certain types of mask
+ * (gaussian blur, for example) than doing a full 2D convolution.
+ *
+ * Each output pixel is
+ * calculated as sigma[i]{pixel[i] * mask[i]} / scale + offset, where scale
+ * and offset are part of @mask.
+ *
+ * See also: im_convsep(), im_conv(), im_create_dmaskv().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_convsep_f( IMAGE *in, IMAGE *out, DOUBLEMASK *mask )
diff --git a/libvips/convolution/im_fastcor.c b/libvips/convolution/im_fastcor.c
index 0901eedd..ceef5803 100644
--- a/libvips/convolution/im_fastcor.c
+++ b/libvips/convolution/im_fastcor.c
@@ -1,19 +1,4 @@
-/* @(#) Functions which calculates spatial correlation between two images.
- * @(#) by taking absolute differences pixel by pixel without calculating
- * @(#) the correlation coefficient.
- * @(#)
- * @(#) The function works as follows:
- * @(#)
- * @(#) int im_fastcor( im, ref, out )
- * @(#) IMAGE *im, *ref, *out;
- * @(#)
- * @(#) ref must be smaller than in. The correlation is
- * @(#) calculated by overlaping im on the top left corner of ref
- * @(#) and moving it all over ref calculating the correlation coefficient
- * @(#) at each point. The resultant coefficients are written as unsigned int
- * @(#) numbers in out which has the size of im.
- * @(#)
- * @(#) Returns 0 on sucess and -1 on error.
+/* im_fastcor
*
* Copyright: 1990, N. Dessipris.
*
@@ -34,6 +19,9 @@
* - use im_embed() with edge stretching on the input, not the output
* - calculate sum of squares of differences, rather than abs of
* difference
+ * 3/2/10
+ * - gtkdoc
+ * - cleanups
*/
/*
@@ -142,7 +130,8 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
{
/* PIO between in and out; WIO from ref.
*/
- if( im_piocheck( in, out ) || im_incheck( ref ) )
+ if( im_piocheck( in, out ) ||
+ im_incheck( ref ) )
return( -1 );
/* Check sizes.
@@ -154,14 +143,13 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
/* Check types.
*/
- if( in->Coding != IM_CODING_NONE || in->Bands != 1 ||
- in->BandFmt != IM_BANDFMT_UCHAR ||
- ref->Coding != IM_CODING_NONE || ref->Bands != 1 ||
- ref->BandFmt != IM_BANDFMT_UCHAR ) {
- im_error( "im_fastcor_raw", "%s",
- _( "input not uncoded 1 band uchar" ) );
+ if( im_check_uncoded( "im_fastcor", in ) ||
+ im_check_format( "im_fastcor", in, IM_BANDFMT_UCHAR ) ||
+ im_check_mono( "im_fastcor", in ) ||
+ im_check_uncoded( "im_fastcor", ref ) ||
+ im_check_format( "im_fastcor", ref, IM_BANDFMT_UCHAR ) ||
+ im_check_mono( "im_fastcor", ref ) )
return( -1 );
- }
/* Prepare the output image.
*/
@@ -171,16 +159,12 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
out->Xsize = in->Xsize - ref->Xsize + 1;
out->Ysize = in->Ysize - ref->Ysize + 1;
- /* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
+ /* FATSTRIP is good for us, as THINSTRIP will cause
* too many recalculations on overlaps.
*/
- if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
- return( -1 );
-
- /* Write the correlation.
- */
- if( im_generate( out,
- im_start_one, fastcor_gen, im_stop_one, in, ref ) )
+ if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ||
+ im_generate( out,
+ im_start_one, fastcor_gen, im_stop_one, in, ref ) )
return( -1 );
out->Xoffset = -ref->Xsize / 2;
@@ -189,7 +173,22 @@ im_fastcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
return( 0 );
}
-/* The above, with a border to make out the same size as in.
+/**
+ * im_fastcor:
+ * @in: input image
+ * @ref: reference image
+ * @out: output image
+ *
+ * Calculate a fast correlation surface.
+ *
+ * @ref is placed at every position in @in and the sum of squares of
+ * differences calculated. One-band, 8-bit unsigned images only. The output
+ * image is always %IM_BANDFMT_UINT. @ref must be smaller than @in. The output
+ * image is the same size as the input.
+ *
+ * See also: im_spcor().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_fastcor( IMAGE *in, IMAGE *ref, IMAGE *out )
diff --git a/libvips/convolution/im_gradcor.c b/libvips/convolution/im_gradcor.c
index 93abe22a..87731cd3 100644
--- a/libvips/convolution/im_gradcor.c
+++ b/libvips/convolution/im_gradcor.c
@@ -1,23 +1,12 @@
-/* @(#) Like im_spcor(), but with a new metric.
- * @(#)
- * @(#) takes the gradient images of the two images, and takes the dot-product
- * @(#) correlation of the two vector images.
- * @(#)
- * @(#) (vector images are never really used, the two components are
- * @(#) calculated separately)
- * @(#)
- * @(#) The vector expression of this method is my (tcv) own creation. It is
- * @(#) equivalent to the complex-number method of:
- * @(#)
- * @(#) ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using
- * @(#) gradient cross correlation. Electronics Letters, 39 (13).
- * @(#)
- * @(#) It's suitability for sub-pixel alignment is not (yet) tested.
+/* im_gradcor
*
* Copyright: 2007 Nottingham Trent University
*
* Author: Tom Vajzovic
* Written on: 2007-06-07
+ * 3/2/10
+ * - gtkdoc
+ * - cleanups
*/
/*
@@ -112,19 +101,14 @@ int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){
if( im_piocheck( large, out ) || im_pincheck( small ) )
return -1;
- if( ! vips_bandfmt_isint( large->BandFmt ) ||
- ! vips_bandfmt_isint( small->BandFmt ) ){
- im_error( FUNCTION_NAME, "image does not have integer band format" );
- return -1;
- }
- if( large-> Coding || small-> Coding ){
- im_error( FUNCTION_NAME, "image is not uncoded" );
- return -1;
- }
- if( 1 != large-> Bands || 1 != small-> Bands ){
- im_error( FUNCTION_NAME, "image is multi-band" );
- return -1;
- }
+ if( im_check_uncoded( "im_gradcor", large ) ||
+ im_check_mono( "im_gradcor", large ) ||
+ im_check_uncoded( "im_gradcor", small ) ||
+ im_check_mono( "im_gradcor", small ) ||
+ im_check_format_same( "im_gradcor", large, small ) ||
+ im_check_int( "im_gradcor", large ) )
+ return( -1 );
+
if( large-> Xsize < small-> Xsize || large-> Ysize < small-> Ysize ){
im_error( FUNCTION_NAME, "second image must be smaller than first" );
return -1;
@@ -152,6 +136,32 @@ int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){
#undef FUNCTION_NAME
}
+/**
+ * im_gradcor:
+ * @in: input image
+ * @ref: reference image
+ * @out: output image
+ *
+ * Calculate a correlation surface.
+ *
+ * @ref is placed at every position in @in and a correlation coefficient
+ * calculated. One-band, integer images only. @in and @ref must have the
+ * same #VipsBandFmt. The output
+ * image is always %IM_BANDFMT_FLOAT. @ref must be smaller than @in. The output
+ * image is the same size as the input.
+ *
+ * The method takes the gradient images of the two images then takes the
+ * dot-product correlation of the two vector images.
+ * The vector expression of this method is my (tcv) own creation. It is
+ * equivalent to the complex-number method of:
+ *
+ * ARGYRIOU, V. et al. 2003. Estimation of sub-pixel motion using
+ * gradient cross correlation. Electronics Letters, 39 (13).
+ *
+ * See also: im_spcor().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int
im_gradcor( IMAGE *in, IMAGE *ref, IMAGE *out )
{
@@ -173,24 +183,35 @@ im_gradcor( IMAGE *in, IMAGE *ref, IMAGE *out )
#undef FUNCTION_NAME
}
+/**
+ * im_grad_x:
+ * @in: input image
+ * @out: output image
+ *
+ * Find horizontal differences between adjacent pixels.
+ *
+ * Generates an image where the value of each pixel is the difference between
+ * it and the pixel to its right. The output has the same height as the input
+ * and one pixel less width. One-band integer formats only. The result is
+ * always %IM_BANDFMT_INT.
+ *
+ * This operation is much faster than (though equivalent to) im_conv() with the
+ * mask [[-1, 1]].
+ *
+ * See also: im_grad_y(), im_conv().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int im_grad_x( IMAGE *in, IMAGE *out ){
#define FUNCTION_NAME "im_grad_x"
if( im_piocheck( in, out ) )
return -1;
- if( ! vips_bandfmt_isint( in->BandFmt ) ){
- im_error( FUNCTION_NAME, "image does not have integer band format" );
- return -1;
- }
- if( in-> Coding ){
- im_error( FUNCTION_NAME, "image is not uncoded" );
- return -1;
- }
- if( 1 != in-> Bands ){
- im_error( FUNCTION_NAME, "image is multi-band" );
- return -1;
- }
+ if( im_check_uncoded( "im_grad_x", in ) ||
+ im_check_mono( "im_grad_x", in ) ||
+ im_check_int( "im_grad_x", in ) )
+ return( -1 );
if( im_cp_desc( out, in ) )
return -1;
@@ -238,24 +259,37 @@ int im_grad_x( IMAGE *in, IMAGE *out ){
#undef FUNCTION_NAME
}
+
+/**
+ * im_grad_y:
+ * @in: input image
+ * @out: output image
+ *
+ * Find vertical differences between adjacent pixels.
+ *
+ * Generates an image where the value of each pixel is the difference between
+ * it and the pixel below it. The output has the same width as the input
+ * and one pixel less height. One-band integer formats only. The result is
+ * always %IM_BANDFMT_INT.
+ *
+ * This operation is much faster than (though equivalent to) im_conv() with the
+ * mask [[-1], [1]].
+ *
+ * See also: im_grad_x(), im_conv().
+ *
+ * Returns: 0 on success, -1 on error
+ */
int im_grad_y( IMAGE *in, IMAGE *out ){
#define FUNCTION_NAME "im_grad_y"
if( im_piocheck( in, out ) )
return -1;
- if( ! vips_bandfmt_isint( in->BandFmt ) ){
- im_error( FUNCTION_NAME, "image does not have integer band format" );
- return -1;
- }
- if( in-> Coding ){
- im_error( FUNCTION_NAME, "image is not uncoded" );
- return -1;
- }
- if( 1 != in-> Bands ){
- im_error( FUNCTION_NAME, "image is multi-band" );
- return -1;
- }
+ if( im_check_uncoded( "im_grad_y", in ) ||
+ im_check_mono( "im_grad_y", in ) ||
+ im_check_int( "im_grad_y", in ) )
+ return( -1 );
+
if( im_cp_desc( out, in ) )
return -1;
diff --git a/libvips/convolution/im_sharpen.c b/libvips/convolution/im_sharpen.c
index bc7d24eb..7a1f1350 100644
--- a/libvips/convolution/im_sharpen.c
+++ b/libvips/convolution/im_sharpen.c
@@ -36,6 +36,9 @@
* - ~15% speed up in total
* 29/11/06
* - convolve first to help region sharing
+ * 3/2/10
+ * - gtkdoc
+ * - cleanups
*/
/*
@@ -212,6 +215,73 @@ sharpen_mask_new( int radius )
return( line );
}
+/**
+ * im_sharpen:
+ * @in: input image
+ * @out: output image
+ * @mask_size: how large a mask to use
+ * @x1: flat/jaggy threshold
+ * @y2: maximum amount of brightening
+ * @y3: maximum amount of darkening
+ * @m1: slope for flat areas
+ * @m2: slope for jaggy areas
+ *
+ * Selectively sharpen the L channel of a LAB image. Works for %IM_CODING_LABQ
+ * and LABS images.
+ *
+ * The operation performs a gaussian blur of size @mask_size and subtracts
+ * from @in to
+ * generate a high-frequency signal. This signal is passed through a lookup
+ * table formed from the five parameters and added back to @in.
+ *
+ * The lookup table is formed like this:
+ *
+ * |[
+ ^
+ y2 |- - - - - -----------
+ | /
+ | / slope m2
+ | .../
+ -x1 | ... |
+ -------------------...---------------------->
+ | ... | x1
+ |... slope m1
+ / |
+ / m2 |
+ / |
+ / |
+ / |
+ / |
+ ______/ _ _ _ _ _ _ | -y3
+ |
+ * ]|
+ *
+ * For printing, we recommend the following settings:
+ *
+ * |[
+ mask_size == 7
+ x1 == 1.5
+ y2 == 20 (don't brighten by more than 20 L*)
+ y3 == 50 (can darken by up to 50 L*)
+
+ m1 == 1 (some sharpening in flat areas)
+ m2 == 2 (more sharpening in jaggy areas)
+ * ]|
+ *
+ * If you want more or less sharpening, we suggest you just change the m1
+ * and m2 parameters.
+ *
+ * The @mask_size parameter changes the width of the fringe and can be
+ * adjusted according to the output printing resolution. As an approximate
+ * guideline, use 3 for 4 pixels/mm (CRT display resolution), 5 for 8
+ * pixels/mm, 7 for 12 pixels/mm and 9 for 16 pixels/mm (300 dpi == 12
+ * pixels/mm). These figures refer to the image raster, not the half-tone
+ * resolution.
+ *
+ * See also: im_conv().
+ *
+ * Returns: 0 on success, -1 on error.
+ */
int
im_sharpen( IMAGE *in, IMAGE *out,
int mask_size,
@@ -243,20 +313,19 @@ im_sharpen( IMAGE *in, IMAGE *out,
/* Check IMAGE parameters
*/
- if( in->Coding != IM_CODING_NONE ||
- in->Bands != 3 ||
- in->BandFmt != IM_BANDFMT_SHORT ) {
- im_error( "im_sharpen", "%s", _( "input not 3-band short" ) );
- return( -1 );
- }
-
- if( im_piocheck( in, out ) )
+ if( im_piocheck( in, out ) ||
+ im_check_uncoded( "im_sharpen", in ) ||
+ im_check_bands( "im_gradcor", in, 3 ) ||
+ im_check_format( "im_gradcor", in, IM_BANDFMT_SHORT ) )
return( -1 );
/* Check number range.
*/
- if( x1 < 0 || x2 < 0 || x1 > 99 || x2 > 99 || x1 > x2 ||
- x3 < 0 || x3 > 99 || x1 > x3 ) {
+ if( x1 < 0 || x1 > 99 ||
+ x2 < 0 || x2 > 99 ||
+ x1 > x2 ||
+ x3 < 0 || x3 > 99 ||
+ x1 > x3 ) {
im_error( "im_sharpen", "%s", _( "parameters out of range" ) );
return( -1 );
}
diff --git a/libvips/convolution/im_spcor.c b/libvips/convolution/im_spcor.c
index d0b6c946..252bc458 100644
--- a/libvips/convolution/im_spcor.c
+++ b/libvips/convolution/im_spcor.c
@@ -1,21 +1,4 @@
-/* @(#) Functions which calculates the correlation coefficient between two
- * @(#) images.
- * @(#)
- * @(#) int im_spcor( IMAGE *in, IMAGE *ref, IMAGE *out )
- * @(#)
- * @(#) We calculate:
- * @(#)
- * @(#) sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
- * @(#) c(k,l) = ------------------------------------------------
- * @(#) sqrt(sumij (ref(i,j)-mean(ref))^2) *
- * @(#) sqrt(sumij (inkl(i,j)-mean(inkl))^2)
- * @(#)
- * @(#) where inkl is the area of in centred at position (k,l).
- * @(#)
- * @(#) Writes float to out. in and ref must be 1 band uchar, or 1 band
- * @(#) ushort.
- * @(#)
- * @(#) Returns 0 on sucess and -1 on error.
+/* im_spcor
*
* Copyright: 1990, N. Dessipris; 2006, 2007 Nottingham Trent University.
*
@@ -48,6 +31,9 @@
* - make im_spcor a wrapper selecting either im__spcor or im__spcor2
* 2008-09-09 JC
* - roll back the windowed version for now, it has some tile edge effects
+ * 3/2/10
+ * - gtkdoc
+ * - cleanups
*/
/*
@@ -185,14 +171,11 @@ spcor_gen( REGION *or, void *vseq, void *a, void *b )
*/
switch( ref->BandFmt ) {
case IM_BANDFMT_UCHAR: LOOP(unsigned char); break;
+ case IM_BANDFMT_CHAR: LOOP(signed char); break;
case IM_BANDFMT_USHORT: LOOP(unsigned short); break;
case IM_BANDFMT_SHORT: LOOP(signed short); break;
default:
- error_exit( "im_spcor: internal error #7934" );
-
- /* Keep gcc -Wall happy.
- */
- return( -1 );
+ g_assert( 0 );
}
/* Now: calculate correlation coefficient!
@@ -260,20 +243,17 @@ im_spcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
/* Check types.
*/
- if( in->Coding != IM_CODING_NONE ||
- in->Bands != 1 ||
- ref->Coding != IM_CODING_NONE ||
- ref->Bands != 1 ||
- in->BandFmt != ref->BandFmt ) {
- im_error( "im_spcor_raw",
- "%s", _( "input not uncoded 1 band" ) );
+ if( im_check_uncoded( "im_spcor", in ) ||
+ im_check_mono( "im_spcor", in ) ||
+ im_check_uncoded( "im_spcor", ref ) ||
+ im_check_mono( "im_spcor", ref ) ||
+ im_check_format_same( "im_spcor", in, ref ) )
return( -1 );
- }
if( in->BandFmt != IM_BANDFMT_UCHAR &&
in->BandFmt != IM_BANDFMT_CHAR &&
in->BandFmt != IM_BANDFMT_SHORT &&
in->BandFmt != IM_BANDFMT_USHORT ) {
- im_error( "im_spcor_raw",
+ im_error( "im_spcor",
"%s", _( "input not char/uchar/short/ushort" ) );
return( -1 );
}
@@ -309,7 +289,37 @@ im_spcor_raw( IMAGE *in, IMAGE *ref, IMAGE *out )
return( 0 );
}
-/* The above, with the input expanded to make out the same size as in.
+/**
+ * im_spcor:
+ * @in: input image
+ * @ref: reference image
+ * @out: output image
+ *
+ * Calculate a correlation surface.
+ *
+ * @ref is placed at every position in @in and the correlation coefficient
+ * calculated. One-band, 8 or 16-bit images only. @in and @ref must have the
+ * same #VipsBandFmt. The output
+ * image is always %IM_BANDFMT_FLOAT. @ref must be smaller than @in. The output
+ * image is the same size as the input.
+ *
+ * The correlation coefficient is calculated as:
+ *
+ * |[
+ * sumij (ref(i,j)-mean(ref))(inkl(i,j)-mean(inkl))
+ * c(k,l) = ------------------------------------------------
+ * sqrt(sumij (ref(i,j)-mean(ref))^2) *
+ * sqrt(sumij (inkl(i,j)-mean(inkl))^2)
+ * ]|
+ *
+ * where inkl is the area of @in centred at position (k,l).
+ *
+ * from Niblack "An Introduction to Digital Image Processing",
+ * Prentice/Hall, pp 138.
+ *
+ * See also: im_gradcor(), im_fastcor().
+ *
+ * Returns: 0 on success, -1 on error
*/
int
im_spcor( IMAGE *in, IMAGE *ref, IMAGE *out )
diff --git a/libvips/include/vips/check.h b/libvips/include/vips/check.h
index 4a063ec8..7ae869af 100644
--- a/libvips/include/vips/check.h
+++ b/libvips/include/vips/check.h
@@ -59,6 +59,8 @@ int im_check_u8or16( const char *domain, IMAGE *im );
int im_check_format_same( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_size_same( const char *domain, IMAGE *im1, IMAGE *im2 );
int im_check_vector( const char *domain, int n, IMAGE *im );
+int im_check_imask( const char *domain, INTMASK *mask );
+int im_check_dmask( const char *domain, DOUBLEMASK *mask );
gboolean vips_bandfmt_isint( VipsBandFmt fmt );
gboolean vips_bandfmt_isuint( VipsBandFmt fmt );
diff --git a/libvips/iofuncs/check.c b/libvips/iofuncs/check.c
index 9b8eba8f..90313759 100644
--- a/libvips/iofuncs/check.c
+++ b/libvips/iofuncs/check.c
@@ -919,6 +919,60 @@ im_check_vector( const char *domain, int n, IMAGE *im )
return( 0 );
}
+/**
+ * im_check_imask:
+ * @domain: the originating domain for the error message
+ * @mask: mask to check
+ *
+ * Sanity-check a mask parameter.
+ *
+ * See also: im_error().
+ *
+ * Returns: 0 if OK, -1 otherwise.
+ */
+int
+im_check_imask( const char *domain, INTMASK *mask )
+{
+ if( !mask ||
+ mask->xsize > 1000 ||
+ mask->ysize > 1000 ||
+ mask->xsize <= 0 ||
+ mask->ysize <= 0 ||
+ !mask->coeff ) {
+ im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
+/**
+ * im_check_dmask:
+ * @domain: the originating domain for the error message
+ * @mask: mask to check
+ *
+ * Sanity-check a mask parameter.
+ *
+ * See also: im_error().
+ *
+ * Returns: 0 if OK, -1 otherwise.
+ */
+int
+im_check_dmask( const char *domain, DOUBLEMASK *mask )
+{
+ if( !mask ||
+ mask->xsize > 1000 ||
+ mask->ysize > 1000 ||
+ mask->xsize <= 0 ||
+ mask->ysize <= 0 ||
+ !mask->coeff ) {
+ im_error( "im_conv", "%s", _( "nonsense mask parameters" ) );
+ return( -1 );
+ }
+
+ return( 0 );
+}
+
/**
* vips_bandfmt_isint:
* @fmt: format to test