/* Define built-in VIPS types. * * J. Cupitt, 8/4/93. * * Modified: * 21/5/07 * - any length vector (Tom) */ /* 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 #endif /*HAVE_CONFIG_H*/ #include #include #include #include #include #include #ifdef WITH_DMALLOC #include #endif /*WITH_DMALLOC*/ /* Max str we parse. */ #define IM_MAX_STR (4096) /* String containing each of the characters which can be used within a * single command line argument to separate the elements of a vector. */ #define VEC_SEPS " " /* Init function for input displays. */ static int input_display_init( im_object *obj, char *str ) { struct im_col_display *scr = im_col_display_name( str ); if( !scr ) { int i; im_error( "input_display", _( "unknown display type \"%s\"" ), str ); im_error( "input_display", "%s", _( "display should be one of:\n" ) ); for( i = 0; (scr = im_col_displays( i )); i++ ) im_error( "input_display", " '%s'\n", scr->d_name ); return( -1 ); } *obj = scr; return( 0 ); } /* Input display type. */ im_type_desc im__input_display = { IM_TYPE_DISPLAY, /* Its a display */ 0, /* No storage needed */ IM_TYPE_ARG, /* It requires a command-line arg */ input_display_init, /* Init function */ NULL /* Destroy function */ }; /* Output display type. */ im_type_desc im__output_display = { IM_TYPE_DISPLAY, /* Its a display */ sizeof( struct im_col_display ),/* Memory to allocate */ IM_TYPE_OUTPUT, /* Output object */ NULL, /* Init function */ NULL /* Destroy function */ }; /* Init function for input images. */ static int input_image_init( im_object *obj, char *str ) { IMAGE **im = (IMAGE **) obj; return( !(*im = im_open( str, "r" )) ); } /* Input image type. */ im_type_desc im__input_image = { IM_TYPE_IMAGE, /* Its an image */ 0, /* No storage needed */ IM_TYPE_ARG, /* It requires a command-line arg */ (im_init_obj_fn) input_image_init,/* Init function */ (im_dest_obj_fn) im_close/* Destroy function */ }; /* Init function for output images. */ static int output_image_init( im_object *obj, char *str ) { IMAGE **im = (IMAGE **) obj; return( !(*im = im_open( str, "w" )) ); } /* Output image type. */ im_type_desc im__output_image = { IM_TYPE_IMAGE, /* Its an image */ 0, /* No storage to be allocated */ IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags! */ (im_init_obj_fn) output_image_init, /* Init function */ (im_dest_obj_fn) im_close /* Destroy function */ }; /* Init function for RW images. */ static int rw_image_init( im_object *obj, char *str ) { IMAGE **im = (IMAGE **) obj; return( !(*im = im_open( str, "rw" )) ); } /* RW image type. */ im_type_desc im__rw_image = { IM_TYPE_IMAGE, /* Its an image */ 0, /* No storage to be allocated */ IM_TYPE_ARG, /* Flags! Pretend its an input type */ (im_init_obj_fn) rw_image_init, /* Init function */ (im_dest_obj_fn) im_close /* Destroy function */ }; /* im_imagevec_object destroy function. */ static int imagevec_dest( im_object obj ) { im_imagevec_object *iv = obj; if( iv->vec ) { int i; for( i = 0; i < iv->n; i++ ) if( iv->vec[i] ) { im_close( iv->vec[i] ); iv->vec[i] = NULL; } im_free( iv->vec ); iv->vec = NULL; iv->n = 0; } return( 0 ); } /* Init function for imagevec input. */ static int input_imagevec_init( im_object *obj, char *str ) { im_imagevec_object *iv = *obj; char **strv; int nargs; int i; strv = g_strsplit( str, VEC_SEPS, -1 ); nargs = g_strv_length( strv ); if( !(iv->vec = IM_ARRAY( NULL, nargs, IMAGE * )) ) { g_strfreev( strv ); return( -1 ); } iv->n = nargs; /* Must NULL them out in case we fail halfway though opening them all. */ for( i = 0; i < nargs; i++ ) iv->vec[i] = NULL; for( i = 0; i < nargs; i++ ) if( !(iv->vec[i] = im_open( strv[i], "r" )) ) { g_strfreev( strv ); return( -1 ); } g_strfreev( strv ); return( 0 ); } /* Input image vector type. */ im_type_desc im__input_imagevec = { IM_TYPE_IMAGEVEC, /* Its an array of IMAGE */ sizeof( im_imagevec_object ), /* Memory to allocate in vec build */ IM_TYPE_ARG, /* It requires a command-line arg */ input_imagevec_init, /* Init function */ imagevec_dest /* Destroy function */ }; /* Init function for masks. "str" can be NULL for output masks. */ static int mask_init( im_object *obj, char *str ) { im_mask_object *mo = *obj; /* Install string, clear mask. */ if( str && !(mo->name = im_strdup( NULL, str )) ) return( -1 ); mo->mask = NULL; return( 0 ); } /* Init function for input dmasks. As above, but read in the mask. */ static int dmask_init( im_object *obj, char *str ) { im_mask_object *mo = *obj; if( mask_init( obj, str ) ) return( -1 ); if( !(mo->mask = im_read_dmask( str )) ) return( -1 ); return( 0 ); } /* Init function for input imasks. */ static int imask_init( im_object *obj, char *str ) { im_mask_object *mo = *obj; if( mask_init( obj, str ) ) return( -1 ); if( !(mo->mask = im_read_imask( str )) ) return( -1 ); return( 0 ); } /* DOUBLEMASK destroy function. */ static int dmask_dest( im_object obj ) { im_mask_object *mo = obj; if( mo->name ) { im_free( mo->name ); mo->name = NULL; } if( mo->mask ) { im_free_dmask( (DOUBLEMASK *) mo->mask ); mo->mask = NULL; } return( 0 ); } /* INTMASK destroy function. */ static int imask_dest( im_object obj ) { im_mask_object *mo = obj; if( mo->name ) { im_free( mo->name ); mo->name = NULL; } if( mo->mask ) { im_free_imask( (INTMASK *) mo->mask ); mo->mask = NULL; } return( 0 ); } /* As above, but save the mask first. */ static int save_dmask_dest( im_object obj ) { im_mask_object *mo = obj; if( mo->mask && im_write_dmask( mo->mask ) ) return( -1 ); return( dmask_dest( obj ) ); } /* As above, but save the mask first. */ static int save_imask_dest( im_object obj ) { im_mask_object *mo = obj; if( mo->mask && im_write_imask( mo->mask ) ) return( -1 ); return( imask_dest( obj ) ); } /* Output dmask type. */ im_type_desc im__output_dmask = { IM_TYPE_DMASK, /* Its a mask */ sizeof( im_mask_object ),/* Storage for mask object */ IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags */ mask_init, /* Init function */ save_dmask_dest /* Save and destroy function */ }; /* Input dmask type. */ im_type_desc im__input_dmask = { IM_TYPE_DMASK, /* Its a mask */ sizeof( im_mask_object ),/* Storage for mask object */ IM_TYPE_ARG, /* It requires a command-line arg */ dmask_init, /* Init function */ dmask_dest /* Destroy function */ }; /* Output imask type. */ im_type_desc im__output_imask = { IM_TYPE_IMASK, /* Its a mask */ sizeof( im_mask_object ),/* Storage for mask object */ IM_TYPE_OUTPUT | IM_TYPE_ARG, /* Flags */ mask_init, /* Init function */ save_imask_dest /* Save and destroy function */ }; /* Input imask type. */ im_type_desc im__input_imask = { IM_TYPE_IMASK, /* Its a mask */ sizeof( im_mask_object ),/* Storage for mask object */ IM_TYPE_ARG, /* It requires a command-line arg */ imask_init, /* Init function */ imask_dest /* Destroy function */ }; /* Output dmask to screen type. Set a `print' function to get actual output. * Used for things like "stats". */ im_type_desc im__output_dmask_screen = { IM_TYPE_DMASK, /* Its a mask */ sizeof( im_mask_object ),/* Storage for mask object */ IM_TYPE_OUTPUT, /* Its an output argument */ mask_init, /* Init function */ dmask_dest /* Destroy function */ }; /* Init function for double input. */ static int input_double_init( im_object *obj, char *str ) { double *d = (double *) *obj; *d = g_ascii_strtod( str, NULL ); return( 0 ); } /* Input double type. */ im_type_desc im__input_double = { IM_TYPE_DOUBLE, /* Its a double */ sizeof( double ), /* Memory to allocate */ IM_TYPE_ARG, /* It requires a command-line arg */ input_double_init, /* Init function */ NULL /* Destroy function */ }; /* im_doublevec_object destroy function. */ static int doublevec_dest( im_object obj ) { im_doublevec_object *dv = obj; if( dv->vec ) { im_free( dv->vec ); dv->vec = NULL; dv->n = 0; } return( 0 ); } /* Init function for doublevec input. */ static int input_doublevec_init( im_object *obj, char *str ) { im_doublevec_object *dv = *obj; char **strv; int nargs; int i; strv = g_strsplit( str, VEC_SEPS, -1 ); nargs = g_strv_length( strv ); if( !(dv->vec = IM_ARRAY( NULL, nargs, double )) ) { g_strfreev( strv ); return( -1 ); } dv->n = nargs; for( i = 0; i < nargs; i++ ) { dv->vec[i] = g_ascii_strtod( strv[i], NULL ); if( errno ) { im_error_system( errno, "input_doublevec_init", _( "bad double \"%s\"" ), strv[i] ); g_strfreev( strv ); return( -1 ); } } g_strfreev( strv ); return( 0 ); } /* Input double vector type. */ im_type_desc im__input_doublevec = { IM_TYPE_DOUBLEVEC, /* Its an array of double */ sizeof( im_doublevec_object ), /* Memory to allocate in vec build */ IM_TYPE_ARG, /* It requires a command-line arg */ input_doublevec_init, /* Init function */ doublevec_dest /* Destroy function */ }; /* Print function for doublevec output. */ int im__dvprint( im_object obj ) { im_doublevec_object *dv = obj; int i; for( i = 0; i < dv->n; i++ ) printf( "%G ", dv->vec[i] ); printf( "\n" ); return( 0 ); } /* Output double vector type. */ im_type_desc im__output_doublevec = { IM_TYPE_DOUBLEVEC, /* Its an array of double */ sizeof( im_doublevec_object ), /* Memory to allocate in vec build */ IM_TYPE_OUTPUT, /* Output type */ NULL, /* Init function */ doublevec_dest /* Destroy function */ }; /* im_intvec_object destroy function. */ static int intvec_dest( im_object obj ) { im_intvec_object *iv = obj; if( iv->vec ) { im_free( iv->vec ); iv->vec = NULL; iv->n = 0; } return( 0 ); } /* Init function for intvec input. */ static int input_intvec_init( im_object *obj, char *str ) { im_intvec_object *iv = *obj; char **strv; int nargs; int i; strv = g_strsplit( str, VEC_SEPS, -1 ); nargs = g_strv_length( strv ); if( !(iv->vec = IM_ARRAY( NULL, nargs, int )) ) { g_strfreev( strv ); return( -1 ); } iv->n = nargs; for( i = 0; i < nargs; i++ ) { long int val= strtol( strv[i], NULL, 10 ); if( errno ) { im_error_system( errno, "input_intvec_init", _( "bad integer \"%s\"" ), strv[i] ); g_strfreev( strv ); return( -1 ); } if( INT_MAX < val || INT_MIN > val ) { im_error( "input_intvec_init", "%ld overflows integer type", val ); } iv->vec[i] = (int) val; } g_strfreev( strv ); return( 0 ); } /* Input int vector type. */ im_type_desc im__input_intvec = { IM_TYPE_INTVEC, /* It's an array of int */ sizeof( im_intvec_object ), /* Memory to allocate in vec build */ IM_TYPE_ARG, /* It requires a command-line arg */ input_intvec_init, /* Init function */ intvec_dest /* Destroy function */ }; /* Print function for intvec output. */ int im__ivprint( im_object obj ) { im_intvec_object *iv = obj; int i; for( i = 0; i < iv->n; i++ ) printf( "%d ", iv->vec[i] ); printf( "\n" ); return( 0 ); } /* Output int vector type. */ im_type_desc im__output_intvec = { IM_TYPE_INTVEC, /* It's an array of int */ sizeof( im_intvec_object ), /* Memory to allocate in vec build */ IM_TYPE_OUTPUT, /* Output arg */ (im_init_obj_fn)NULL, /* Init function */ (im_dest_obj_fn)intvec_dest /* Destroy function */ }; /* Init function for int input. */ static int input_int_init( im_object *obj, char *str ) { int *i = (int *) *obj; if( sscanf( str, "%d", i ) != 1 ) { im_error( "input_int", "%s", _( "bad format" ) ); return( -1 ); } return( 0 ); } /* Input int type. */ im_type_desc im__input_int = { IM_TYPE_INT, /* Its an int */ sizeof( int ), /* Memory to allocate */ IM_TYPE_ARG, /* It requires a command-line arg */ input_int_init, /* Init function */ NULL /* Destroy function */ }; /* Init function for string input. */ static int input_string_init( im_object *obj, char *str ) { if( !(*obj = (im_object) im_strdup( NULL, str )) ) return( -1 ); return( 0 ); } /* Input string type. */ im_type_desc im__input_string = { IM_TYPE_STRING, /* Its a string */ 0, /* Memory to allocate */ IM_TYPE_ARG, /* It requires a command-line arg */ input_string_init, /* Init function */ im_free /* Destroy function */ }; /* Output string type. */ im_type_desc im__output_string = { IM_TYPE_STRING, /* Its a string */ 0, /* Memory to allocate */ IM_TYPE_OUTPUT, /* Its an output argument */ NULL, /* Init function */ im_free /* Destroy function */ }; /* Output double type. */ im_type_desc im__output_double = { IM_TYPE_DOUBLE, /* Its a double */ sizeof( double ), /* Memory to allocate */ IM_TYPE_OUTPUT, /* Its an output argument */ NULL, /* Init function */ NULL /* Destroy function */ }; /* Output complex type. */ im_type_desc im__output_complex = { IM_TYPE_COMPLEX, /* Its a complex */ 2 * sizeof( double ), /* Memory to allocate */ IM_TYPE_OUTPUT, /* Its an output argument */ NULL, /* Init function */ NULL /* Destroy function */ }; /* Output int type. */ im_type_desc im__output_int = { IM_TYPE_INT, /* Its an int */ sizeof( int ), /* Memory to allocate */ IM_TYPE_OUTPUT, /* Its an output argument */ NULL, /* Init function */ NULL /* Destroy function */ }; /* Print function for int output. */ int im__iprint( im_object obj ) { int *i = (int *) obj; printf( "%d\n", *i ); return( 0 ); } /* Print function for string output. */ int im__sprint( im_object obj ) { char *s = (char *) obj; printf( "%s\n", s ); return( 0 ); } /* Print function for double output. */ int im__dprint( im_object obj ) { double *d = (double *) obj; printf( "%G\n", *d ); return( 0 ); } /* Print function for complex output. */ int im__cprint( im_object obj ) { double *d = (double *) obj; printf( "%G %G\n", d[0], d[1] ); return( 0 ); } /* Statistics to stdout. */ int im__dmsprint( im_object obj ) { DOUBLEMASK *mask = ((im_mask_object *) obj)->mask; double *row; int i, j; /* Print statistics band stats eg: 2 bands:b 0,1 */ printf( "\ band minimum maximum sum sum^2 mean deviation\ \n" ); for( j = 0; j < mask->ysize; j++ ) { row = mask->coeff + j * 6; if( j == 0 ) printf( "all" ); else printf( "%2d ", j ); for( i = 0; i < 6; i++ ) printf( "%12g", row[i] ); printf( "\n" ); } return( 0 ); } static char *decode_dtype( enum im_col_disp_type type ) { switch( type ) { case DISP_BARCO: return( "DISP_BARCO" ); case DISP_DUMB: return( "DISP_DUMB" ); default: return( "" ); } } /* Print display stuff. */ int im__displayprint( im_object obj ) { struct im_col_display *scr = (struct im_col_display *) obj; printf( "im_col_display:\n" ); printf( "\td_name: %s\n", scr->d_name ); printf( "\td_type: %s\n", decode_dtype( scr->d_type ) ); printf( "\td_mat:\n" ); printf( "\t\t %g %g %g\n", scr->d_mat[0][0], scr->d_mat[0][1], scr->d_mat[0][2] ); printf( "\t\t %g %g %g\n", scr->d_mat[1][0], scr->d_mat[1][1], scr->d_mat[1][2] ); printf( "\t\t %g %g %g\n", scr->d_mat[2][0], scr->d_mat[2][1], scr->d_mat[2][2] ); printf( "\td_YCW: %g\n", scr->d_YCW ); printf( "\td_xCW: %g\n", scr->d_xCW ); printf( "\td_yCW: %g\n", scr->d_yCW ); printf( "\td_YCR: %g\n", scr->d_YCR ); printf( "\td_YCG: %g\n", scr->d_YCG ); printf( "\td_YCB: %g\n", scr->d_YCB ); printf( "\td_Vrwr: %d\n", scr->d_Vrwr ); printf( "\td_Vrwg: %d\n", scr->d_Vrwg ); printf( "\td_Vrwb: %d\n", scr->d_Vrwb ); printf( "\td_Y0R: %g\n", scr->d_Y0R ); printf( "\td_Y0G: %g\n", scr->d_Y0G ); printf( "\td_Y0B: %g\n", scr->d_Y0B ); printf( "\td_gammaR: %g\n", scr->d_gammaR ); printf( "\td_gammaG: %g\n", scr->d_gammaG ); printf( "\td_gammaB: %g\n", scr->d_gammaB ); printf( "\td_B: %g\n", scr->d_B ); printf( "\td_P: %g\n", scr->d_P ); return( 0 ); } /* GValue */ /* Init function for input gvalue. Just make a string ... will get cast to * whatever later. */ static int input_gvalue_init( im_object *obj, char *str ) { GValue *value = *obj; g_value_init( value, G_TYPE_STRING ); g_value_set_string( value, str ); return( 0 ); } static int gvalue_free( im_object obj ) { GValue *value = obj; g_value_unset( value ); return( 0 ); } /* Input GValue type. */ im_type_desc im__input_gvalue = { IM_TYPE_GVALUE, sizeof( GValue ), /* Need some storage */ IM_TYPE_ARG, /* It requires a command-line arg */ (im_init_obj_fn) input_gvalue_init, /* Init function */ (im_dest_obj_fn) gvalue_free /* Destroy function */ }; int im__gprint( im_object obj ) { GValue *value = obj; char *str_value; str_value = g_strdup_value_contents( value ); printf( "%s\n", str_value ); g_free( str_value ); return( 0 ); } /* Init function for output gvalue. Just init to zero. */ static int output_gvalue_init( im_object *obj ) { GValue *value = *obj; memset( value, 0, sizeof( GValue ) ); return( 0 ); } im_type_desc im__output_gvalue = { IM_TYPE_GVALUE, sizeof( GValue ), /* Need some storage */ IM_TYPE_OUTPUT, /* No arg needed (just print) */ (im_init_obj_fn) output_gvalue_init, /* Init function */ (im_dest_obj_fn) gvalue_free /* Destroy function */ }; /* Init function for input interpolate. */ static int input_interpolate_init( im_object *obj, char *str ) { VipsObject *object; if( !(object = vips_object_new_from_string( "VipsInterpolate", str )) ) return( -1 ); *obj = object; return( 0 ); } im_type_desc im__input_interpolate = { IM_TYPE_INTERPOLATE, 0, /* No storage required */ IM_TYPE_ARG, /* It requires a command-line arg */ (im_init_obj_fn) input_interpolate_init,/* Init function */ (im_dest_obj_fn) g_object_unref /* Destroy function */ };