gtk-doc on mask

This commit is contained in:
John Cupitt 2010-10-21 13:50:36 +00:00
parent bf029b4611
commit 01b1597a75
5 changed files with 231 additions and 67 deletions

1
TODO
View File

@ -1,3 +1,4 @@
- started gtk-doc-ing libvips/mask
- maybe im_draw_smudge() is too slow :-( also, we had a sanity failure with

View File

@ -76,6 +76,7 @@ int im_free_dmask( DOUBLEMASK *m );
INTMASK *im_log_imask( const char *filename, double sigma, double min_ampl );
DOUBLEMASK *im_log_dmask( const char *filename, double sigma, double min_ampl );
INTMASK *im_gauss_imask( const char *filename, double sigma, double min_ampl );
INTMASK *im_gauss_imask_sep( const char *filename,
double sigma, double min_ampl );

View File

@ -1,24 +1,4 @@
/* @(#) Returns a circularly symmetric Gaussian mask
* @(#) min_amplitude should be greater than 0.0 and less than 1.0
* @(#) min_amplitude determines the size of the mask; if for instance
* @(#) the value .1 is entered this means that the produced mask is clipped
* @(#) at values less than 10 percent of the minimum negative amplitude.
* @(#) If the value of min_amplitude is too small, then the filter coefficients
* @(#) are calculated for masksize equal to the min of 8 * sigma or 256.
* @(#) The mask can be directly used with the vasari convolution programs,
* @(#) the default offset set is 0
* @(#)
* @(#) DOUBLEMASK *im_gauss_dmask( filename, sigma, min_amplitude )
* @(#) char *filename;
* @(#) double sigma, min_amplitude;
* @(#)
* @(#) Returns a laplacian of Gaussian square double mask or NULL on error
* @(#)
* @(#) DOUBLEMASK *im_gauss_imask( filename, sigma, min_amplitude )
* @(#) char *filename;
* @(#) double sigma, min_amplitude;
* @(#)
* @(#) Returns a laplacian of Gaussian square int mask or NULL on error
/* generate gaussian masks
*/
/* Written on: 30/11/1989 by Nicos
@ -32,6 +12,8 @@
* - added _sep variant
* 30/3/09
* - set scale in _sep variant, why not
* 21/10/10
* - gtkdoc
*/
/*
@ -76,6 +58,28 @@
#define IM_MAXMASK 5000
/**
* im_gauss_dmask:
* @filename: the returned mask has this set as the filename
* @sigma: standard deviation of mask
* @min_ampl: minimum amplitude
*
* im_gauss_dmask() creates a circularly symmetric Gaussian mask of radius
* @sigma. The size of the mask is determined by the variable @min_ampl;
* if for instance the value .1 is entered this means that the produced mask
* is clipped at values less than 10 percent of the maximum amplitude.
*
* The program uses the following equation:
*
* H(r) = exp( -(r * r) / (2 * sigma * sigma) )
*
* The generated mask has odd size and its maximum value is normalised to
* 1.0.
*
* See also: im_gauss_imask(), im_gauss_imask_sep(), im_log_dmask(), im_conv().
*
* Returns: the calculated mask on success, or NULL on error.
*/
DOUBLEMASK *
im_gauss_dmask( const char *filename, double sigma, double min_ampl )
{
@ -168,13 +172,26 @@ im_gauss_dmask( const char *filename, double sigma, double min_ampl )
return( m );
}
/**
* im_gauss_imask:
* @filename: the returned mask has this set as the filename
* @sigma: standard deviation of mask
* @min_ampl: minimum amplitude
*
* im_gauss_imask() works exactly as im_gauss_dmask(), but the returned mask
* is scaled so that it's maximum value it set to 100.
*
* See also: im_gauss_dmask(), im_gauss_imask_sep(), im_conv(), im_convsep().
*
* Returns: the calculated mask on success, or NULL on error.
*/
INTMASK *
im_gauss_imask( const char *filename, double sigma, double min_amplitude )
im_gauss_imask( const char *filename, double sigma, double min_ampl )
{
DOUBLEMASK *dm;
INTMASK *im;
if( !(dm = im_gauss_dmask( filename, sigma, min_amplitude )) )
if( !(dm = im_gauss_dmask( filename, sigma, min_ampl )) )
return( NULL );
if( !(im = im_scale_dmask( dm, dm->filename )) ) {
@ -186,18 +203,28 @@ im_gauss_imask( const char *filename, double sigma, double min_amplitude )
return( im ) ;
}
/* Just return the central line of the mask. This helps nip, which really
* struggles with large matrix manipulations.
/**
* im_gauss_imask_sep:
* @filename: the returned mask has this set as the filename
* @sigma: standard deviation of mask
* @min_ampl: minimum amplitude
*
* im_gauss_imask_sep() works exactly as im_gauss_imask(), but returns only
* the central line of the mask. This is useful with im_convsep().
*
* See also: im_gauss_dmask(), im_gauss_imask_sep(), im_conv(), im_convsep().
*
* Returns: the calculated mask on success, or NULL on error.
*/
INTMASK *
im_gauss_imask_sep( const char *filename, double sigma, double min_amplitude )
im_gauss_imask_sep( const char *filename, double sigma, double min_ampl )
{
INTMASK *im;
INTMASK *im2;
int i;
int sum;
if( !(im = im_gauss_imask( filename, sigma, min_amplitude )) )
if( !(im = im_gauss_imask( filename, sigma, min_ampl )) )
return( NULL );
if( !(im2 = im_create_imask( filename, im->xsize, 1 )) ) {
im_free_imask( im );

View File

@ -42,19 +42,6 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/**
* SECTION: mask
* @short_description: load, save and process mask (matrix) objects
* @stability: Stable
* @include: vips/vips.h
*
* These operations load, save and process mask objects. Masks are used as
* paramaters to convolution and morphology operators, and to represent
* matrices.
*
* This API is horrible and clunky. Surely it will be replaced soon.
*/
/* One matrix in, one out.
*/
static im_arg_desc one_in_one_out[] = {

View File

@ -105,12 +105,76 @@
#include <dmalloc.h>
#endif /*WITH_DMALLOC*/
/**
* SECTION: mask
* @short_description: load, save and process mask (matrix) objects
* @stability: Stable
* @include: vips/vips.h
*
* These operations load, save and process mask objects. Masks are used as
* paramaters to convolution and morphology operators, and to represent
* matrices.
*
* This API is horrible and clunky. Surely it will be replaced soon.
*/
/**
* INTMASK:
* @xsize: mask width
* @ysize: mask height
* @scale: mask scale factor
* @offset: mask offset
* @coeff: array of mask elements
* @filename: the file this mask was read from, or should be written to
*
* An integer mask.
*
* @scale lets the mask represent fractional values: for
* example, in integer convolution (see im_conv()) the result of the
* convolution is divided by @scale and then added to @offset before being
* written to the output image.
*
* @scale and @offset default to 1 and 0. Various functions, such as
* im_conv(), will fail of @scale is zero.
*
* You can read and write the matrix elements in @coeff.
*/
/**
* DOUBLEMASK:
* @xsize: mask width
* @ysize: mask height
* @scale: mask scale factor
* @offset: mask offset
* @coeff: array of mask elements
* @filename: the file this mask was read from, or should be written to
*
* A floating-point mask.
*
* As with #INTMASK, in convolution (see im_convf()) the result of the
* convolution is divided by @scale and then added to @offset before being
* written to the output image.
*
* @scale and @offset default to 1.0 and 0.0. Various functions, such as
* im_conv(), will fail of @scale is zero.
*
* You can read and write the matrix elements in @coeff.
*/
/* Size of line buffer for reading.
*/
#define IM_MAX_LINE (4096)
/* Free mask structure and any attached arrays. Return zero, so we can use
/**
* im_free_imask:
* @m: mask to free
*
* Free mask structure and any attached arrays. Return zero, so we can use
* these functions as close callbacks.
*
* See also: im_free_dmask().
*
* Returns: zero.
*/
int
im_free_imask( INTMASK *m )
@ -127,6 +191,17 @@ im_free_imask( INTMASK *m )
return( 0 );
}
/**
* im_free_dmask:
* @m: mask to free
*
* Free mask structure and any attached arrays. Return zero, so we can use
* these functions as close callbacks.
*
* See also: im_free_dmask().
*
* Returns: zero.
*/
int
im_free_dmask( DOUBLEMASK *m )
{
@ -142,7 +217,17 @@ im_free_dmask( DOUBLEMASK *m )
return( 0 );
}
/* Create structures.
/**
* im_create_imask:
* @filename: set mask filename to this
* @xs: mask width
* @ys: mask height
*
* Create an empty imask. You need to loop over @coeff to set the values.
*
* See also: im_create_imaskv().
*
* Returns: The newly-allocated mask.
*/
INTMASK *
im_create_imask( const char *filename, int xs, int ys )
@ -182,6 +267,19 @@ im_create_imask( const char *filename, int xs, int ys )
return( m );
}
/**
* im_create_imaskv:
* @filename: set mask filename to this
* @xs: mask width
* @ys: mask height
* @Varargs: values to set for the mask
*
* Create an imask and initialise it from the funtion parameter list.
*
* See also: im_create_imask().
*
* Returns: The newly-allocated mask.
*/
INTMASK *
im_create_imaskv( const char *filename, int xs, int ys, ... )
{
@ -201,6 +299,18 @@ im_create_imaskv( const char *filename, int xs, int ys, ... )
return( m );
}
/**
* im_create_dmask:
* @filename: set mask filename to this
* @xs: mask width
* @ys: mask height
*
* Create an empty dmask. You need to loop over @coeff to set the values.
*
* See also: im_create_dmaskv().
*
* Returns: The newly-allocated mask.
*/
DOUBLEMASK *
im_create_dmask( const char *filename, int xs, int ys )
{
@ -239,6 +349,19 @@ im_create_dmask( const char *filename, int xs, int ys )
return( m );
}
/**
* im_create_dmaskv:
* @filename: set mask filename to this
* @xs: mask width
* @ys: mask height
* @Varargs: values to set for the mask
*
* Create a dmask and initialise it from the funtion parameter list.
*
* See also: im_create_dmask().
*
* Returns: The newly-allocated mask.
*/
DOUBLEMASK *
im_create_dmaskv( const char *filename, int xs, int ys, ... )
{
@ -258,22 +381,6 @@ im_create_dmaskv( const char *filename, int xs, int ys, ... )
return( m );
}
/* Open for read.
*/
static FILE *
open_read( const char *name )
{
FILE *fp;
if( !(fp = fopen( name, "r" )) ) {
im_error( "read_mask", _( "Unable to open \"%s\" for input" ),
name );
return( NULL );
}
return( fp );
}
/* Read a line from a file!
*/
static int
@ -309,7 +416,7 @@ read_header( FILE *fp, int *xs, int *ys, double *scale, double *offset )
*/
p = buf;
for( i = 0, p = buf;
i < 4 && (q = im_break_token( p, " \t\n" ));
i < 4 && (q = im_break_token( p, " \";,\t\n" ));
i++, p = q )
v[i] = g_ascii_strtod( p, NULL );
@ -342,10 +449,39 @@ read_header( FILE *fp, int *xs, int *ys, double *scale, double *offset )
return( 0 );
}
/* Read matrix files.
/**
* im_read_dmask:
* @filename: read matrix from this file
*
* Reads a matrix from a file.
*
* Matrix files have a simple format that's supposed to be easy to create with
* a text editor or a spreadsheet.
*
* The first line has four numbers for width, height, scale and
* offset (scale and offset may be omitted, in which case they default to 1.0
* and 0.0). Scale must be non-zero. Width and height must be positive
* integers. The numbers are separated by any mixture of spaces, commas,
* tabs and quotation marks ("). The scale and offset fields may be
* floating-point, and must use '.'
* as a decimal separator.
*
* Subsequent lines each hold one line of matrix data, with numbers again
* separated by any mixture of spaces, commas,
* tabs and quotation marks ("). The numbers may be floating-point, and must
* use '.'
* as a decimal separator.
*
* Extra characters at the ends of lines or at the end of the file are
* ignored.
*
* See also: im_read_imask(), im_gauss_dmask().
*
* Returns: the loaded mask on success, or NULL on error.
*/
DOUBLEMASK *
im_read_dmask( const char *maskfile )
im_read_dmask( const char *filename )
{
FILE *fp;
double sc, off;
@ -354,7 +490,7 @@ im_read_dmask( const char *maskfile )
int x, y, i, size;
char buf[IM_MAX_LINE];
if( !(fp = open_read( maskfile )) )
if( !(fp = im__file_open_read( filename, NULL )) )
return( NULL );
if( read_header( fp, &xs, &ys, &sc, &off ) ) {
@ -362,7 +498,7 @@ im_read_dmask( const char *maskfile )
return( NULL );
}
if( !(m = im_create_dmask( maskfile, xs, ys )) ) {
if( !(m = im_create_dmask( filename, xs, ys )) ) {
fclose( fp );
return( NULL );
}
@ -388,16 +524,28 @@ im_read_dmask( const char *maskfile )
return( m );
}
/* INTMASK ... read as double, check for intness.
/**
* im_read_imask:
* @filename: read matrix from this file
*
* Reads an integer matrix from a file.
*
* This function works exactly as im_read_dmask(), but the loaded matrix is
* checked for 'int-ness'. All coefficients must be integers, and scale and
* offset must be integers.
*
* See also: im_read_dmask().
*
* Returns: the loaded mask on success, or NULL on error.
*/
INTMASK *
im_read_imask( const char *maskfile )
im_read_imask( const char *filename )
{
DOUBLEMASK *dmask;
INTMASK *imask;
int i;
if( !(dmask = im_read_dmask( maskfile )) )
if( !(dmask = im_read_dmask( filename )) )
return( NULL );
if( ceil( dmask->scale ) != dmask->scale ||
@ -420,7 +568,7 @@ im_read_imask( const char *maskfile )
return( NULL );
}
if( !(imask = im_create_imask( maskfile,
if( !(imask = im_create_imask( filename,
dmask->xsize, dmask->ysize )) ) {
im_free_dmask( dmask );
return( NULL );