/** * im_vips2csv: * @in: image to save * @filename: file to write to * * Save a CSV (comma-separated values) file. The image is written * one line of text per scanline. Complex numbers are written as * "(real,imaginary)" and will need extra parsing I guess. The image must * have a single band. * * Write options can be embedded in the filename. The options can be given * in any order and are: * * <itemizedlist> * <listitem> * <para> * <emphasis>sep:separator-string</emphasis> * The string to use to separate numbers in the output. * The default is "\\t" (tab). * </para> * </listitem> * </itemizedlist> * * For example: * * |[ * im_csv2vips( in, "fred.csv:sep:\t" ); * ]| * * Will write to fred.csv, separating numbers with tab characters. * * See also: #VipsFormat, im_csv2vips(), im_write_dmask(), im_vips2ppm(). * * Returns: 0 on success, -1 on error. */ int im_vips2csv( IMAGE *in, const char *filename ) { char *separator = "\t"; char name[FILENAME_MAX]; char mode[FILENAME_MAX]; FILE *fp; char *p, *q, *r; /* Parse mode string. */ im_filename_split( filename, name, mode ); p = &mode[0]; while( (q = im_getnextoption( &p )) ) { if( im_isprefix( "sep", q ) && (r = im_getsuboption( q )) ) separator = r; } if( im_incheck( in ) || im_check_mono( "im_vips2csv", in ) || im_check_uncoded( "im_vips2csv", in ) ) return( -1 ); if( !(fp = im__file_open_write( name, TRUE )) ) return( -1 ); if( vips2csv( in, fp, separator ) ) { fclose( fp ); return( -1 ); } fclose( fp ); return( 0 ); }
/** * 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( 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; -- out-> Ysize; out-> BandFmt= IM_BANDFMT_INT; /* do not change without updating im_gradcor() */ if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) ) return -1; #define RETURN_GENERATE( TYPE ) return im_generate( out, im_start_one, ygrad_gen_ ## TYPE, im_stop_one, (void*) in, NULL ) switch( in-> BandFmt ){ case IM_BANDFMT_UCHAR: RETURN_GENERATE( guint8 ); case IM_BANDFMT_CHAR: RETURN_GENERATE( gint8 ); case IM_BANDFMT_USHORT: RETURN_GENERATE( guint16 ); case IM_BANDFMT_SHORT: RETURN_GENERATE( gint16 ); case IM_BANDFMT_UINT: RETURN_GENERATE( guint32 ); case IM_BANDFMT_INT: RETURN_GENERATE( gint32 ); #if 0 case IM_BANDFMT_FLOAT: RETURN_GENERATE( float ); case IM_BANDFMT_DOUBLE: RETURN_GENERATE( double ); #endif #undef RETURN_GENERATE default: g_assert( 0 ); } /* Keep gcc happy. */ return 0; #undef FUNCTION_NAME }
int im_stdif_raw( IMAGE *in, IMAGE *out, double a, double m0, double b, double s0, int xwin, int ywin ) { StdifInfo *inf; if( xwin > in->Xsize || ywin > in->Ysize ) { im_error( "im_stdif", "%s", _( "window too large" ) ); return( -1 ); } if( xwin <= 0 || ywin <= 0 ) { im_error( "im_lhisteq", "%s", _( "window too small" ) ); return( -1 ); } if( m0 < 0 || m0 > 255 || a < 0 || a > 1.0 || b < 0 || b > 2 || s0 < 0 || s0 > 255 ) { im_error( "im_stdif", "%s", _( "parameters out of range" ) ); return( -1 ); } if( im_check_format( "im_stdif", in, IM_BANDFMT_UCHAR ) || im_check_uncoded( "im_stdif", in ) || im_check_mono( "im_stdif", in ) || im_piocheck( in, out ) ) return( -1 ); if( im_cp_desc( out, in ) ) return( -1 ); out->Xsize -= xwin; out->Ysize -= ywin; /* Save parameters. */ if( !(inf = IM_NEW( out, StdifInfo )) ) return( -1 ); inf->xwin = xwin; inf->ywin = ywin; inf->a = a; inf->m0 = m0; inf->b = b; inf->s0 = s0; /* 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 ); /* Write the hist. */ if( im_generate( out, im_start_one, stdif_gen, im_stop_one, in, inf ) ) return( -1 ); return( 0 ); }
int im_contrast_surface_raw (IMAGE * in, IMAGE * out, int half_win_size, int spacing) { #define FUNCTION_NAME "im_contrast_surface_raw" cont_surf_params_t *params; 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 (half_win_size < 1 || spacing < 1) { im_error (FUNCTION_NAME, "%s", _("bad parameters")); return -1; } if (DOUBLE (half_win_size) >= LESSER (in->Xsize, in->Ysize)) { im_error (FUNCTION_NAME, "%s", _("parameters would result in zero size output image")); return -1; } params = IM_NEW (out, cont_surf_params_t); if (!params) return -1; params->half_win_size = half_win_size; params->spacing = spacing; if (im_cp_desc (out, in)) return -1; out->BandFmt = IM_BANDFMT_UINT; out->Xsize = 1 + ((in->Xsize - DOUBLE_ADD_ONE (half_win_size)) / spacing); out->Ysize = 1 + ((in->Ysize - DOUBLE_ADD_ONE (half_win_size)) / spacing); out->Xoffset = -half_win_size; out->Yoffset = -half_win_size; if (im_demand_hint (out, IM_FATSTRIP, in, NULL)) return -1; return im_generate (out, im_start_one, cont_surf_gen, im_stop_one, in, params); #undef FUNCTION_NAME }
int im_gradcor_raw( IMAGE *large, IMAGE *small, IMAGE *out ){ #define FUNCTION_NAME "im_gradcor_raw" if( im_piocheck( large, out ) || im_pincheck( small ) ) 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; } if( im_cp_desc( out, large ) ) return -1; out-> Xsize= 1 + large-> Xsize - small-> Xsize; out-> Ysize= 1 + large-> Ysize - small-> Ysize; out-> BandFmt= IM_BANDFMT_FLOAT; if( im_demand_hint( out, IM_FATSTRIP, large, NULL ) ) return -1; { IMAGE *xgrad= im_open_local( out, FUNCTION_NAME ": xgrad", "t" ); IMAGE *ygrad= im_open_local( out, FUNCTION_NAME ": ygrad", "t" ); IMAGE **grads= im_allocate_input_array( out, xgrad, ygrad, NULL ); return ! xgrad || ! ygrad || ! grads || im_grad_x( small, xgrad ) || im_grad_y( small, ygrad ) || im_generate( out, gradcor_start, gradcor_gen, gradcor_stop, (void*) large, (void*) grads ); } #undef FUNCTION_NAME }
int im_lhisteq_raw( IMAGE *in, IMAGE *out, int xwin, int ywin ) { LhistInfo *inf; if( im_check_mono( "im_lhisteq", in ) || im_check_uncoded( "im_lhisteq", in ) || im_check_format( "im_lhisteq", in, IM_BANDFMT_UCHAR ) || im_piocheck( in, out ) ) return( -1 ); if( xwin > in->Xsize || ywin > in->Ysize ) { im_error( "im_lhisteq", "%s", _( "window too large" ) ); return( -1 ); } if( xwin <= 0 || ywin <= 0 ) { im_error( "im_lhisteq", "%s", _( "window too small" ) ); return( -1 ); } if( im_cp_desc( out, in ) ) return( -1 ); out->Xsize -= xwin - 1; out->Ysize -= ywin - 1; /* Save parameters. */ if( !(inf = IM_NEW( out, LhistInfo )) ) return( -1 ); inf->xwin = xwin; inf->ywin = ywin; inf->npels = xwin * ywin; /* 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, im_start_one, lhist_gen, im_stop_one, in, inf ) ) return( -1 ); out->Xoffset = -xwin / 2; out->Yoffset = -xwin / 2; return( 0 ); }
/** * im_hist_indexed: * @index: input image * @value: input image * @out: output image * * Make a histogram of @value, but use image @index to pick the bins. In other * words, element zero in @out contains the sum of all the pixels in @value * whose corresponding pixel in @index is zero. * * @index must have just one band and be u8 or u16. @value must be * non-complex. @out always has the same size and format as @value. * * This operation is useful in conjunction with im_label_regions(). You can * use it to find the centre of gravity of blobs in an image, for example. * * See also: im_histgr(), im_label_regions(). * * Returns: 0 on success, -1 on error */ int im_hist_indexed( IMAGE *index, IMAGE *value, IMAGE *out ) { int size; /* Length of hist */ Histogram *mhist; VipsGenerateFn scanfn; /* Check images. PIO from in, WIO to out. */ if( im_pincheck( index ) || im_pincheck( value ) || im_outcheck( out ) || im_check_uncoded( "im_hist_indexed", index ) || im_check_uncoded( "im_hist_indexed", value ) || im_check_noncomplex( "im_hist_indexed", value ) || im_check_size_same( "im_hist_indexed", index, value ) || im_check_u8or16( "im_hist_indexed", index ) || im_check_mono( "im_hist_indexed", index ) ) return( -1 ); /* Find the range of pixel values we must handle. */ if( index->BandFmt == IM_BANDFMT_UCHAR ) { size = 256; scanfn = hist_scan_uchar; } else { size = 65536; scanfn = hist_scan_ushort; } /* Build main hist we accumulate data in. */ if( !(mhist = hist_build( index, value, out, value->Bands, size )) ) return( -1 ); /* Accumulate data. */ if( vips_sink( index, hist_start, scanfn, hist_stop, mhist, NULL ) || hist_write( out, mhist ) ) { hist_free( mhist ); return( -1 ); } hist_free( mhist ); return( 0 ); }
/** * im_circle: * @im: image to draw on * @cx: centre of circle * @cy: centre of circle * @radius: circle radius * @intensity: value to draw * * Draws a circle on a 1-band 8-bit image. * * This an inplace operation, so @im is changed. It does not thread and will * not work well as part of a pipeline. On 32-bit machines it will be limited * to 2GB images. * * See also: im_fastline(). * * Returns: 0 on success, or -1 on error. */ int im_circle( IMAGE *im, int cx, int cy, int radius, int intensity ) { PEL ink[1]; if( im_rwcheck( im ) || im_check_uncoded( "im_circle", im ) || im_check_mono( "im_circle", im ) || im_check_format( "im_circle", im, IM_BANDFMT_UCHAR ) ) return( -1 ); ink[0] = intensity; return( im_draw_circle( im, cx, cy, radius, FALSE, ink ) ); }
/* Raw fastcor, with no borders. */ int 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 ) ) return( -1 ); /* Check sizes. */ if( in->Xsize < ref->Xsize || in->Ysize < ref->Ysize ) { im_error( "im_fastcor", "%s", _( "ref not smaller than or equal to in" ) ); return( -1 ); } /* Check types. */ if( im_check_uncoded( "im_fastcor", in ) || im_check_mono( "im_fastcor", in ) || im_check_format( "im_fastcor", in, IM_BANDFMT_UCHAR ) || im_check_coding_same( "im_fastcor", in, ref ) || im_check_bands_same( "im_fastcor", in, ref ) || im_check_format_same( "im_fastcor", in, ref ) ) return( -1 ); /* Prepare the output image. */ if( im_cp_descv( out, in, ref, NULL ) ) return( -1 ); out->BandFmt = IM_BANDFMT_UINT; out->Xsize = in->Xsize - ref->Xsize + 1; out->Ysize = in->Ysize - ref->Ysize + 1; /* FATSTRIP is good for us, as THINSTRIP will cause * too many recalculations on overlaps. */ 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; out->Yoffset = -ref->Ysize / 2; return( 0 ); }
static Mask * mask_new( VipsImage *im, int x, int y, PEL *ink, VipsImage *mask_im ) { Mask *mask; Rect area, image; if( im_check_coding_noneorlabq( "im_draw_mask", im ) || im_incheck( mask_im ) || im_check_mono( "im_draw_mask", mask_im ) || im_check_uncoded( "im_draw_mask", mask_im ) || im_check_format( "im_draw_mask", mask_im, IM_BANDFMT_UCHAR ) || !(mask = IM_NEW( NULL, Mask )) ) return( NULL ); if( !im__draw_init( DRAW( mask ), im, ink ) ) { mask_free( mask ); return( NULL ); } mask->x = x; mask->y = y; mask->mask_im = mask_im; /* Find the area we draw on the image. */ area.left = x; area.top = y; area.width = mask_im->Xsize; area.height = mask_im->Ysize; image.left = 0; image.top = 0; image.width = im->Xsize; image.height = im->Ysize; im_rect_intersectrect( &area, &image, &mask->image_clip ); /* And the area of the mask image we use. */ mask->mask_clip = mask->image_clip; mask->mask_clip.left -= x; mask->mask_clip.top -= y; return( mask ); }