| /* VIPS function dispatch tables for matricies. |
| * |
| * J. Cupitt, 14/2/95. |
| */ |
| |
| /* |
| |
| 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
| */ |
| |
| /* |
| |
| These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk |
| |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| #include <config.h> |
| #endif /*HAVE_CONFIG_H*/ |
| #include <vips/intl.h> |
| |
| #include <stdio.h> |
| |
| #include <vips/vips.h> |
| |
| #ifdef WITH_DMALLOC |
| #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[] = { |
| IM_INPUT_DMASK( "in" ), |
| IM_OUTPUT_DMASK( "out" ) |
| }; |
| |
| /* Two matricies in, one out. |
| */ |
| static im_arg_desc two_in_one_out[] = { |
| IM_INPUT_DMASK( "in1" ), |
| IM_INPUT_DMASK( "in2" ), |
| IM_OUTPUT_DMASK( "out" ) |
| }; |
| |
| /* Call im_matinv via arg vector. |
| */ |
| static int |
| matinv_vec( im_object *argv ) |
| { |
| im_mask_object *in = argv[0]; |
| im_mask_object *out = argv[1]; |
| |
| if( !(out->mask = |
| im_matinv( in->mask, out->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_matinv. |
| */ |
| static im_function matinv_desc = { |
| "im_matinv", /* Name */ |
| "invert matrix", |
| 0, /* Flags */ |
| matinv_vec, /* Dispatch function */ |
| IM_NUMBER( one_in_one_out ), /* Size of arg list */ |
| one_in_one_out /* Arg list */ |
| }; |
| |
| /* Call im_mattrn via arg vector. |
| */ |
| static int |
| mattrn_vec( im_object *argv ) |
| { |
| im_mask_object *in = argv[0]; |
| im_mask_object *out = argv[1]; |
| |
| if( !(out->mask = |
| im_mattrn( in->mask, out->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_mattrn. |
| */ |
| static im_function mattrn_desc = { |
| "im_mattrn", /* Name */ |
| "transpose matrix", |
| 0, /* Flags */ |
| mattrn_vec, /* Dispatch function */ |
| IM_NUMBER( one_in_one_out ), /* Size of arg list */ |
| one_in_one_out /* Arg list */ |
| }; |
| |
| /* Call im_matcat via arg vector. |
| */ |
| static int |
| matcat_vec( im_object *argv ) |
| { |
| im_mask_object *in1 = argv[0]; |
| im_mask_object *in2 = argv[1]; |
| im_mask_object *out = argv[2]; |
| |
| if( !(out->mask = |
| im_matcat( in1->mask, in2->mask, out->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_matcat. |
| */ |
| static im_function matcat_desc = { |
| "im_matcat", /* Name */ |
| "append matrix in2 to the end of matrix in1", |
| 0, /* Flags */ |
| matcat_vec, /* Dispatch function */ |
| IM_NUMBER( two_in_one_out ), /* Size of arg list */ |
| two_in_one_out /* Arg list */ |
| }; |
| |
| /* Call im_matmul via arg vector. |
| */ |
| static int |
| matmul_vec( im_object *argv ) |
| { |
| im_mask_object *in1 = argv[0]; |
| im_mask_object *in2 = argv[1]; |
| im_mask_object *out = argv[2]; |
| |
| if( !(out->mask = |
| im_matmul( in1->mask, in2->mask, out->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_matmul. |
| */ |
| static im_function matmul_desc = { |
| "im_matmul", /* Name */ |
| "multiply matrix in1 by matrix in2", |
| 0, /* Flags */ |
| matmul_vec, /* Dispatch function */ |
| IM_NUMBER( two_in_one_out ), /* Size of arg list */ |
| two_in_one_out /* Arg list */ |
| }; |
| |
| /* Args for im_read_dmask() |
| */ |
| static im_arg_desc read_dmask_args[] = { |
| IM_INPUT_STRING( "filename" ), |
| IM_OUTPUT_DMASK( "mask" ) |
| }; |
| |
| /* Call im_read_dmask via arg vector. |
| */ |
| static int |
| read_dmask_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[1]; |
| |
| if( !(mo->mask = im_read_dmask( argv[0] )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_read_dmask(). |
| */ |
| static im_function read_dmask_desc = { |
| "im_read_dmask", /* Name */ |
| "read matrix of double from file", |
| 0, /* Flags */ |
| read_dmask_vec, /* Dispatch function */ |
| IM_NUMBER( read_dmask_args ), /* Size of arg list */ |
| read_dmask_args /* Arg list */ |
| }; |
| |
| /* Args for im_gauss_dmask. |
| */ |
| static im_arg_desc gauss_dmask_args[] = { |
| IM_OUTPUT_DMASK( "mask" ), |
| IM_INPUT_DOUBLE( "sigma" ), |
| IM_INPUT_DOUBLE( "min_amp" ) |
| }; |
| |
| /* Call im_gauss_dmask via arg vector. |
| */ |
| static int |
| gauss_dmask_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[0]; |
| double sigma = *((double *) argv[1]); |
| double min_amp = *((double *) argv[2]); |
| |
| if( !(mo->mask = |
| im_gauss_dmask( mo->name, sigma, min_amp )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_gauss_dmask. |
| */ |
| static im_function gauss_dmask_desc = { |
| "im_gauss_dmask", /* Name */ |
| "generate gaussian DOUBLEMASK", |
| 0, /* Flags */ |
| gauss_dmask_vec, /* Dispatch function */ |
| IM_NUMBER( gauss_dmask_args ), /* Size of arg list */ |
| gauss_dmask_args /* Arg list */ |
| }; |
| |
| /* Args for im_gauss_imask. |
| */ |
| static im_arg_desc gauss_imask_args[] = { |
| IM_OUTPUT_IMASK( "mask" ), |
| IM_INPUT_DOUBLE( "sigma" ), |
| IM_INPUT_DOUBLE( "min_amp" ) |
| }; |
| |
| /* Call im_gauss_imask via arg vector. |
| */ |
| static int |
| gauss_imask_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[0]; |
| double sigma = *((double *) argv[1]); |
| double min_amp = *((double *) argv[2]); |
| |
| if( !(mo->mask = |
| im_gauss_imask( mo->name, sigma, min_amp )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_gauss_imask. |
| */ |
| static im_function gauss_imask_desc = { |
| "im_gauss_imask", /* Name */ |
| "generate gaussian INTMASK", |
| 0, /* Flags */ |
| gauss_imask_vec, /* Dispatch function */ |
| IM_NUMBER( gauss_imask_args ), /* Size of arg list */ |
| gauss_imask_args /* Arg list */ |
| }; |
| |
| /* Call im_gauss_imask_sep via arg vector. |
| */ |
| static int |
| gauss_imask_sep_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[0]; |
| double sigma = *((double *) argv[1]); |
| double min_amp = *((double *) argv[2]); |
| |
| if( !(mo->mask = |
| im_gauss_imask_sep( mo->name, sigma, min_amp )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_gauss_imask_sep. |
| */ |
| static im_function gauss_imask_sep_desc = { |
| "im_gauss_imask_sep", /* Name */ |
| "generate separable gaussian INTMASK", |
| 0, /* Flags */ |
| gauss_imask_sep_vec, /* Dispatch function */ |
| IM_NUMBER( gauss_imask_args ), /* Size of arg list */ |
| gauss_imask_args /* Arg list */ |
| }; |
| |
| /* Args for im_log_imask. |
| */ |
| static im_arg_desc log_imask_args[] = { |
| IM_OUTPUT_IMASK( "mask" ), |
| IM_INPUT_DOUBLE( "sigma" ), |
| IM_INPUT_DOUBLE( "min_amp" ) |
| }; |
| |
| /* Call im_log_imask via arg vector. |
| */ |
| static int |
| log_imask_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[0]; |
| double sigma = *((double *) argv[1]); |
| double min_amp = *((double *) argv[2]); |
| |
| if( !(mo->mask = |
| im_log_imask( mo->name, sigma, min_amp )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_log_imask. |
| */ |
| static im_function log_imask_desc = { |
| "im_log_imask", /* Name */ |
| "generate laplacian of gaussian INTMASK", |
| 0, /* Flags */ |
| log_imask_vec, /* Dispatch function */ |
| IM_NUMBER( log_imask_args ), /* Size of arg list */ |
| log_imask_args /* Arg list */ |
| }; |
| |
| /* Args for im_log_dmask. |
| */ |
| static im_arg_desc log_dmask_args[] = { |
| IM_OUTPUT_DMASK( "maskfile" ), |
| IM_INPUT_DOUBLE( "sigma" ), |
| IM_INPUT_DOUBLE( "min_amp" ) |
| }; |
| |
| /* Call im_log_dmask via arg vector. |
| */ |
| static int |
| log_dmask_vec( im_object *argv ) |
| { |
| im_mask_object *mo = argv[0]; |
| double sigma = *((double *) argv[1]); |
| double min_amp = *((double *) argv[2]); |
| |
| if( !(mo->mask = |
| im_log_dmask( mo->name, sigma, min_amp )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_log_dmask. |
| */ |
| static im_function log_dmask_desc = { |
| "im_log_dmask", /* Name */ |
| "generate laplacian of gaussian DOUBLEMASK", |
| 0, /* Flags */ |
| log_dmask_vec, /* Dispatch function */ |
| IM_NUMBER( log_dmask_args ), /* Size of arg list */ |
| log_dmask_args /* Arg list */ |
| }; |
| |
| static im_arg_desc imask_args[] = { |
| IM_INPUT_IMASK( "in" ), |
| IM_OUTPUT_IMASK( "out" ) |
| }; |
| |
| static im_arg_desc dmask_args[] = { |
| IM_INPUT_DMASK( "in" ), |
| IM_OUTPUT_DMASK( "out" ) |
| }; |
| |
| /* Call im_rotate_imask45 via arg vector. |
| */ |
| static int |
| rotate_imask45_vec( im_object *argv ) |
| { |
| im_mask_object *min = argv[0]; |
| im_mask_object *mout = argv[1]; |
| |
| if( !(mout->mask = im_rotate_imask45( min->mask, mout->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_rotate_imask45. |
| */ |
| static im_function rotate_imask45_desc = { |
| "im_rotate_imask45", /* Name */ |
| "rotate INTMASK clockwise by 45 degrees", |
| 0, /* Flags */ |
| rotate_imask45_vec, /* Dispatch function */ |
| IM_NUMBER( imask_args ), /* Size of arg list */ |
| imask_args /* Arg list */ |
| }; |
| |
| /* Call im_rotate_imask90 via arg vector. |
| */ |
| static int |
| rotate_imask90_vec( im_object *argv ) |
| { |
| im_mask_object *min = argv[0]; |
| im_mask_object *mout = argv[1]; |
| |
| if( !(mout->mask = im_rotate_imask90( min->mask, mout->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_rotate_imask90. |
| */ |
| static im_function rotate_imask90_desc = { |
| "im_rotate_imask90", /* Name */ |
| "rotate INTMASK clockwise by 90 degrees", |
| 0, /* Flags */ |
| rotate_imask90_vec, /* Dispatch function */ |
| IM_NUMBER( imask_args ), /* Size of arg list */ |
| imask_args /* Arg list */ |
| }; |
| |
| /* Call im_rotate_dmask45 via arg vector. |
| */ |
| static int |
| rotate_dmask45_vec( im_object *argv ) |
| { |
| im_mask_object *min = argv[0]; |
| im_mask_object *mout = argv[1]; |
| |
| if( !(mout->mask = im_rotate_dmask45( min->mask, mout->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_rotate_dmask45. |
| */ |
| static im_function rotate_dmask45_desc = { |
| "im_rotate_dmask45", /* Name */ |
| "rotate DOUBLEMASK clockwise by 45 degrees", |
| 0, /* Flags */ |
| rotate_dmask45_vec, /* Dispatch function */ |
| IM_NUMBER( dmask_args ), /* Size of arg list */ |
| dmask_args /* Arg list */ |
| }; |
| |
| /* Call im_rotate_dmask90 via arg vector. |
| */ |
| static int |
| rotate_dmask90_vec( im_object *argv ) |
| { |
| im_mask_object *min = argv[0]; |
| im_mask_object *mout = argv[1]; |
| |
| if( !(mout->mask = im_rotate_dmask90( min->mask, mout->name )) ) |
| return( -1 ); |
| |
| return( 0 ); |
| } |
| |
| /* Description of im_rotate_dmask90. |
| */ |
| static im_function rotate_dmask90_desc = { |
| "im_rotate_dmask90", /* Name */ |
| "rotate DOUBLEMASK clockwise by 90 degrees", |
| 0, /* Flags */ |
| rotate_dmask90_vec, /* Dispatch function */ |
| IM_NUMBER( dmask_args ), /* Size of arg list */ |
| dmask_args /* Arg list */ |
| }; |
| |
| static int |
| imask_xsize_vec( im_object *argv ) |
| { |
| *( (int*) argv[1] )= ( (INTMASK*) ( ( (im_mask_object*) argv[0] )-> mask ) )-> xsize; |
| return 0; |
| } |
| |
| static int |
| imask_ysize_vec( im_object *argv ) |
| { |
| *( (int*) argv[1] )= ( (INTMASK*) ( ( (im_mask_object*) argv[0] )-> mask ) )-> ysize; |
| return 0; |
| } |
| |
| static int |
| dmask_xsize_vec( im_object *argv ) |
| { |
| *( (int*) argv[1] )= ( (DOUBLEMASK*) ( ( (im_mask_object*) argv[0] )-> mask ) )-> xsize; |
| return 0; |
| } |
| |
| static int |
| dmask_ysize_vec( im_object *argv ) |
| { |
| *( (int*) argv[1] )= ( (DOUBLEMASK*) ( ( (im_mask_object*) argv[0] )-> mask ) )-> ysize; |
| return 0; |
| } |
| |
| static im_arg_desc imask_size_args[] = { |
| IM_INPUT_IMASK( "mask" ), |
| IM_OUTPUT_INT( "size" ) |
| }; |
| |
| static im_arg_desc dmask_size_args[] = { |
| IM_INPUT_DMASK( "mask" ), |
| IM_OUTPUT_INT( "size" ) |
| }; |
| |
| static im_function imask_xsize_desc = { |
| "im_imask_xsize", /* Name */ |
| "horizontal size of an intmask", /* Description */ |
| 0, /* Flags */ |
| imask_xsize_vec, /* Dispatch function */ |
| IM_NUMBER( imask_size_args ), /* Size of arg list */ |
| imask_size_args /* Arg list */ |
| }; |
| |
| static im_function imask_ysize_desc = { |
| "im_imask_ysize", /* Name */ |
| "vertical size of an intmask", /* Description */ |
| 0, /* Flags */ |
| imask_ysize_vec, /* Dispatch function */ |
| IM_NUMBER( imask_size_args ), /* Size of arg list */ |
| imask_size_args /* Arg list */ |
| }; |
| |
| static im_function dmask_xsize_desc = { |
| "im_dmask_xsize", /* Name */ |
| "horizontal size of a doublemask", /* Description */ |
| 0, /* Flags */ |
| dmask_xsize_vec, /* Dispatch function */ |
| IM_NUMBER( dmask_size_args ), /* Size of arg list */ |
| dmask_size_args /* Arg list */ |
| }; |
| |
| static im_function dmask_ysize_desc = { |
| "im_dmask_ysize", /* Name */ |
| "vertical size of a doublemask", /* Description */ |
| 0, /* Flags */ |
| dmask_ysize_vec, /* Dispatch function */ |
| IM_NUMBER( dmask_size_args ), /* Size of arg list */ |
| dmask_size_args /* Arg list */ |
| }; |
| |
| /* Package up all these functions. |
| */ |
| static im_function *mask_list[] = { |
| &gauss_dmask_desc, |
| &log_dmask_desc, |
| &log_imask_desc, |
| &gauss_imask_desc, |
| &gauss_imask_sep_desc, |
| &dmask_xsize_desc, |
| &dmask_ysize_desc, |
| &imask_xsize_desc, |
| &imask_ysize_desc, |
| &read_dmask_desc, |
| &rotate_dmask45_desc, |
| &rotate_dmask90_desc, |
| &rotate_imask45_desc, |
| &rotate_imask90_desc, |
| &matcat_desc, |
| &matinv_desc, |
| &matmul_desc, |
| &mattrn_desc |
| }; |
| |
| /* Package of functions. |
| */ |
| im_package im__mask = { |
| "mask", |
| IM_NUMBER( mask_list ), |
| mask_list |
| }; |