/** * im_fgrey: * @out: output image * @xsize: image size * @ysize: image size * * Create a one-band float image with the left-most column zero and the * right-most 1. Intermediate pixels are a linear ramp. * * See also: im_grey(), im_make_xy(), im_identity(). * * Returns: 0 on success, -1 on error */ int im_fgrey( IMAGE *out, const int xsize, const int ysize ) { /* Check args. */ if( xsize <=0 || ysize <= 0 ) { im_error( "im_fgrey", "%s", _( "bad size" ) ); return( -1 ); } if( im_poutcheck( out ) ) return( -1 ); /* Set image. */ im_initdesc( out, xsize, ysize, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); /* Set hints - ANY is ok with us. */ if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Generate image. */ if( im_generate( out, NULL, fgrey_gen, NULL, NULL, NULL ) ) return( -1 ); return( 0 ); }
/** * im_gaussnoise: * @out: output image * @x: output width * @y: output height * @mean: average value in output * @sigma: standard deviation in output * * Make a one band float image of gaussian noise with the specified * distribution. The noise distribution is created by averaging 12 random * numbers with the appropriate weights. * * See also: im_addgnoise(), im_make_xy(), im_text(), im_black(). * * Returns: 0 on success, -1 on error */ int im_gaussnoise( IMAGE *out, int x, int y, double mean, double sigma ) { GnoiseInfo *gin; if( x <= 0 || y <= 0 ) { im_error( "im_gaussnoise", "%s", _( "bad parameter" ) ); return( -1 ); } if( im_poutcheck( out ) ) return( -1 ); im_initdesc( out, x, y, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT, IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 ); if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Save parameters. */ if( !(gin = IM_NEW( out, GnoiseInfo )) ) return( -1 ); gin->mean = mean; gin->sigma = sigma; if( im_generate( out, NULL, gnoise_gen, NULL, gin, NULL ) ) return( -1 ); return( 0 ); }
/* Wrap up as a partial. */ int im_wraptwo( IMAGE *in1, IMAGE *in2, IMAGE *out, im_wraptwo_fn fn, void *a, void *b ) { if( im_pincheck( in1 ) || im_pincheck( in2 ) || im_poutcheck( out )) return -1; { UserBundle *bun= IM_NEW( out, UserBundle ); IMAGE **ins= im_allocate_input_array( out, in1, in2, NULL ); if( ! bun || ! ins ) return -1; bun-> fn= fn; bun-> a= a; bun-> b= b; return im_demand_hint( out, IM_THINSTRIP, in1, in2, NULL ) || im_generate( out, im_start_many, process_region, im_stop_many, (void*) ins, (void*) bun ); } }
/** * im_magick2vips: * @filename: file to load * @out: image to write to * * Read in an image using libMagick, the ImageMagick library. This library can * read more than 80 file formats, including SVG, BMP, EPS, DICOM and many * others. * The reader can handle any ImageMagick image, including the float and double * formats. It will work with any quantum size, including HDR. Any metadata * attached to the libMagick image is copied on to the VIPS image. * * The reader should also work with most versions of GraphicsMagick. * * See also: #VipsFormat. * * Returns: 0 on success, -1 on error. */ int im_magick2vips( const char *filename, IMAGE *out ) { Read *read; if( !(read = read_new( filename, out )) ) return( -1 ); #ifdef HAVE_SETIMAGEOPTION /* When reading DICOM images, we want to ignore any * window_center/_width setting, since it may put pixels outside the * 0-65535 range and lose data. * * These window settings are attached as vips metadata, so our caller * can interpret them if it wants. */ SetImageOption( read->image_info, "dcm:display-range", "reset" ); #endif /*HAVE_SETIMAGEOPTION*/ read->image = ReadImage( read->image_info, &read->exception ); if( !read->image ) { im_error( "im_magick2vips", _( "unable to read file \"%s\"\n" "libMagick error: %s %s" ), filename, read->exception.reason, read->exception.description ); return( -1 ); } if( parse_header( read ) || im_poutcheck( out ) || im_demand_hint( out, IM_SMALLTILE, NULL ) || im_generate( out, NULL, magick_fill_region, NULL, read, NULL ) ) return( -1 ); return( 0 ); }
/* Plot image. */ static int plot( IMAGE *in, IMAGE *out ) { double max; int tsize; int xsize; int ysize; if( im_incheck( in ) || im_poutcheck( out ) ) return( -1 ); /* Find range we will plot. */ if( im_max( in, &max ) ) return( -1 ); g_assert( max >= 0 ); if( in->BandFmt == IM_BANDFMT_UCHAR ) tsize = 256; else tsize = ceil( max ); /* Make sure we don't make a zero height image. */ if( tsize == 0 ) tsize = 1; if( in->Xsize == 1 ) { /* Vertical graph. */ xsize = tsize; ysize = in->Ysize; } else { /* Horizontal graph. */ xsize = in->Xsize; ysize = tsize; } /* Set image. */ im_initdesc( out, xsize, ysize, in->Bands, IM_BBITS_BYTE, IM_BANDFMT_UCHAR, IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 ); /* Set hints - ANY is ok with us. */ if( im_demand_hint( out, IM_ANY, NULL ) ) return( -1 ); /* Generate image. */ if( in->Xsize == 1 ) { if( im_generate( out, NULL, make_vert_gen, NULL, in, NULL ) ) return( -1 ); } else { if( im_generate( out, NULL, make_horz_gen, NULL, in, NULL ) ) return( -1 ); } return( 0 ); }
/** * im_linreg: * @ins: NULL-terminated array of input images * @out: results of analysis * @xs: X position of each image (pixel value is Y) * * Function to find perform pixelwise linear regression on an array of * single band images. The output is a seven-band douuble image * * TODO: figure out how this works and fix up these docs! */ int im_linreg( IMAGE **ins, IMAGE *out, double *xs ){ #define FUNCTION_NAME "im_linreg" int n; x_set *x_vals; if( im_poutcheck( out ) ) return( -1 ); for( n= 0; ins[ n ]; ++n ){ /* if( ! isfinite( xs[ n ] ) ){ im_error( FUNCTION_NAME, "invalid argument" ); return( -1 ); } */ if( im_pincheck( ins[ n ] ) ) return( -1 ); if( 1 != ins[ n ]-> Bands ){ im_error( FUNCTION_NAME, "image is not single band" ); return( -1 ); } if( ins[ n ]-> Coding ){ im_error( FUNCTION_NAME, "image is not uncoded" ); return( -1 ); } if( n ){ if( ins[ n ]-> BandFmt != ins[ 0 ]-> BandFmt ){ im_error( FUNCTION_NAME, "image band formats differ" ); return( -1 ); } } else { if( vips_bandfmt_iscomplex( ins[ 0 ]->BandFmt ) ){ im_error( FUNCTION_NAME, "image has non-scalar band format" ); return( -1 ); } } if( n && ( ins[ n ]-> Xsize != ins[ 0 ]-> Xsize || ins[ n ]-> Ysize != ins[ 0 ]-> Ysize ) ){ im_error( FUNCTION_NAME, "image sizes differ" ); return( -1 ); } } if( n < 3 ){ im_error( FUNCTION_NAME, "not enough input images" ); return( -1 ); } if( im_cp_desc_array( out, ins ) ) return( -1 ); out-> Bands= 7; out-> BandFmt= IM_BANDFMT_DOUBLE; out-> Type= 0; if( im_demand_hint_array( out, IM_THINSTRIP, ins ) ) return( -1 ); x_vals= x_anal( out, xs, n ); if( ! x_vals ) return( -1 ); switch( ins[ 0 ]-> BandFmt ){ #define LINREG_RET( TYPE ) return im_generate( out, linreg_start_ ## TYPE, linreg_gen_ ## TYPE, linreg_stop_ ## TYPE, ins, x_vals ) case IM_BANDFMT_CHAR: LINREG_RET( gint8 ); case IM_BANDFMT_UCHAR: LINREG_RET( guint8 ); case IM_BANDFMT_SHORT: LINREG_RET( gint16 ); case IM_BANDFMT_USHORT: LINREG_RET( guint16 ); case IM_BANDFMT_INT: LINREG_RET( gint32 ); case IM_BANDFMT_UINT: LINREG_RET( guint32 ); case IM_BANDFMT_FLOAT: LINREG_RET( float ); case IM_BANDFMT_DOUBLE: LINREG_RET( double ); default: /* keep -Wall happy */ return( -1 ); } #undef FUNCTION_NAME }
/* Use fftw2. */ static int invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out ) { IMAGE *cmplx = im_open_local( dummy, "invfft1-1", "t" ); IMAGE *real = im_open_local( out, "invfft1-2", "t" ); const int half_width = in->Xsize / 2 + 1; /* Transform to halfcomplex here. */ double *half_complex = IM_ARRAY( dummy, in->Ysize * half_width * 2, double ); rfftwnd_plan plan; int x, y; double *q, *p; if( !cmplx || !real || !half_complex || im_pincheck( in ) || im_poutcheck( out ) ) return( -1 ); if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) { im_error( "im_invfft", _( "one band uncoded only" ) ); return( -1 ); } /* Make dp complex image for input. */ if( im_clip2fmt( in, cmplx, IM_BANDFMT_DPCOMPLEX ) ) return( -1 ); /* Make mem buffer real image for output. */ if( im_cp_desc( real, in ) ) return( -1 ); real->BandFmt = IM_BANDFMT_DOUBLE; if( im_setupout( real ) ) return( -1 ); /* Build half-complex image. */ q = half_complex; for( y = 0; y < cmplx->Ysize; y++ ) { p = ((double *) cmplx->data) + y * in->Xsize * 2; for( x = 0; x < half_width; x++ ) { q[0] = p[0]; q[1] = p[1]; p += 2; q += 2; } } /* Make the plan for the transform. Yes, they really do use nx for * height and ny for width. */ if( !(plan = rfftw2d_create_plan( in->Ysize, in->Xsize, FFTW_BACKWARD, FFTW_MEASURE | FFTW_USE_WISDOM )) ) { im_error( "im_invfft", _( "unable to create transform plan" ) ); return( -1 ); } rfftwnd_one_complex_to_real( plan, (fftw_complex *) half_complex, (fftw_real *) real->data ); rfftwnd_destroy_plan( plan ); /* Copy to out. */ if( im_copy( real, out ) ) return( -1 ); return( 0 ); }