コード例 #1
0
ファイル: im_remainder.c プロジェクト: aturcotte/libvips
/**
 * im_remainder:
 * @in1: input #IMAGE 1
 * @in2: input #IMAGE 2
 * @out: output #IMAGE
 *
 * This operation calculates @in1 % @in2 (remainder after division) and writes 
 * the result to @out. The images may have any 
 * non-complex format. For float formats, im_remainder() calculates @in1 -
 * @in2 * floor (@in1 / @in2).
 *
 * If the images differ in size, the smaller image is enlarged to match the
 * larger by adding zero pixels along the bottom and right.
 *
 * If the number of bands differs, one of the images 
 * must have one band. In this case, an n-band image is formed from the 
 * one-band image by joining n copies of the one-band image together, and then
 * the two n-band images are operated upon.
 *
 * The two input images are cast up to the smallest common type (see table 
 * Smallest common format in 
 * <link linkend="VIPS-arithmetic">arithmetic</link>), and that format is the
 * result type.
 *
 * See also: im_remainderconst(), im_divide().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_remainder( IMAGE *in1, IMAGE *in2, IMAGE *out )
{
	if( im_check_noncomplex( "im_remainder", in1 ) ||
		im_check_noncomplex( "im_remainder", in2 ) )
		return( -1 );

	return( im__arith_binary( "im_remainder", 
		in1, in2, out, 
		bandfmt_remainder,
		(im_wrapmany_fn) remainder_buffer, NULL ) );
}
コード例 #2
0
ファイル: im_shrink.c プロジェクト: aturcotte/libvips
/**
 * im_shrink:
 * @in: input image
 * @out: output image
 * @xshrink: horizontal shrink
 * @yshrink: vertical shrink
 *
 * Shrink @in by a pair of factors with a simple box filter.
 *
 * You will get aliasing for non-integer shrinks. In this case, shrink with
 * this function to the nearest integer size above the target shrink, then
 * downsample to the exact size with im_affinei() and your choice of
 * interpolator.
 *
 * im_rightshift_size() is faster for factors which are integer powers of two.
 *
 * See also: im_rightshift_size(), im_affinei().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_shrink( IMAGE *in, IMAGE *out, double xshrink, double yshrink )
{
    if( im_check_noncomplex( "im_shrink", in ) ||
            im_check_coding_known( "im_shrink", in ) ||
            im_piocheck( in, out ) )
        return( -1 );
    if( xshrink < 1.0 || yshrink < 1.0 ) {
        im_error( "im_shrink",
                  "%s", _( "shrink factors should be >= 1" ) );
        return( -1 );
    }

    if( xshrink == 1 && yshrink == 1 ) {
        return( im_copy( in, out ) );
    }
    else if( in->Coding == IM_CODING_LABQ ) {
        IMAGE *t[2];

        if( im_open_local_array( out, t, 2, "im_shrink:1", "p" ) ||
                im_LabQ2LabS( in, t[0] ) ||
                shrink( t[0], t[1], xshrink, yshrink ) ||
                im_LabS2LabQ( t[1], out ) )
            return( -1 );
    }
    else if( shrink( in, out, xshrink, yshrink ) )
        return( -1 );

    return( 0 );
}
コード例 #3
0
ファイル: power.c プロジェクト: Ikulagin/transmem
/**
 * im_expntra_vec:
 * @in: input #IMAGE 
 * @out: output #IMAGE
 * @n: number of elements in array
 * @e: array of constants
 *
 * im_expntra_vec() transforms element x of input to 
 * <function>pow</function>(@b, x) in output. 
 * It detects division by zero, setting those pixels to zero in the output. 
 * Beware: it does this silently!
 *
 * If the array of constants has one element, that constant is used for each
 * image band. If the array has more than one element, it must have the same
 * number of elements as there are bands in the image, and one array element
 * is used for each band.
 *
 * See also: im_logtra(), im_powtra()
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_expntra_vec( IMAGE *in, IMAGE *out, int n, double *c )
{
	if( im_check_noncomplex( "im_expntra_vec", in ) )
		return( -1 );

	return( im__arith_binary_const( "im_expntra_vec", 
		in, out, n, c, IM_BANDFMT_DOUBLE,
		bandfmt_power,
		(im_wrapone_fn) POWC1_buffer, 
		(im_wrapone_fn) POWCn_buffer ) );
}
コード例 #4
0
ファイル: im_remainder.c プロジェクト: aturcotte/libvips
/**
 * im_remainder_vec:
 * @in: input #IMAGE 
 * @out: output #IMAGE
 * @n: number of elements in array
 * @c: array of constants
 *
 * This operation calculates @in % @c (remainder after division by constant) 
 * and writes the result to @out. 
 * The image may have any 
 * non-complex format. For float formats, im_remainder() calculates @in -
 * @c * floor (@in / @c).
 *
 * If the number of image bands end array elements differs, one of them
 * must have one band. Either the image is up-banded by joining n copies of
 * the one-band image together, or the array is upbanded by copying the single
 * element n times.
 *
 * See also: im_remainder(), im_remainderconst(), im_divide().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_remainder_vec( IMAGE *in, IMAGE *out, int n, double *c )
{
	if( im_check_noncomplex( "im_remainder", in ) )
		return( -1 );

	return( im__arith_binary_const( "im_remainder", 
		in, out, n, c, in->BandFmt,
		bandfmt_remainder,
		(im_wrapone_fn) remainderconst1_buffer, 
		(im_wrapone_fn) remainderconstn_buffer ) );
}
コード例 #5
0
ファイル: im_histplot.c プロジェクト: ashishof77/libvips
/* Normalise an image using the rules noted above.
 */
static int
normalise( IMAGE *in, IMAGE *out )
{
	if( im_check_uncoded( "im_histplot", in ) ||
		im_check_noncomplex( "im_histplot", in ) )
		return( -1 );

	if( vips_bandfmt_isuint( in->BandFmt ) ) {
		if( im_copy( in, out ) )
			return( -1 );
	}
	else if( vips_bandfmt_isint( in->BandFmt ) ) {
		IMAGE *t1;
		double min;

		/* Move min up to 0. 
		 */
		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_min( in, &min ) ||
			im_lintra( 1.0, in, -min, t1 ) )
			return( -1 );
	}
	else {
		/* Float image: scale min--max to 0--any. Output square
		 * graph.
		 */
		IMAGE *t1;
		DOUBLEMASK *stats;
		double min, max;
		int any;

		if( in->Xsize == 1 )
			any = in->Ysize;
		else
			any = in->Xsize;

		if( !(stats = im_stats( in )) )
			return( -1 );
		min = VIPS_MASK( stats, 0, 0 );
		max = VIPS_MASK( stats, 1, 0 );
		im_free_dmask( stats );

		if( !(t1 = im_open_local( out, "im_histplot", "p" )) ||
			im_lintra( any / (max - min), in, 
				-min * any / (max - min), out ) )
			return( -1 );
	}

	return( 0 );
}
コード例 #6
0
ファイル: im_histindexed.c プロジェクト: nrobidoux/libvips
/**
 * 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 );
}
コード例 #7
0
ファイル: im_zerox.c プロジェクト: nrobidoux/libvips
/**
 * im_zerox:
 * @in: input image
 * @out: output image
 * @sign: detect positive or negative zero crossings
 *
 * im_zerox() detects the positive or negative zero crossings @in, 
 * depending on @sign. If @sign is -1, negative zero crossings are returned,
 * if @sign is 1, positive zero crossings are returned.
 *
 * The output image is byte with zero crossing set to 255 and all other values
 * set to zero. Input can have any number of channels, and be any non-complex 
 * type.
 *
 * See also: im_conv(), im_rot90.
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_zerox( IMAGE *in, IMAGE *out, int sign )
{
	IMAGE *t1;

	if( sign != -1 && sign != 1 ) {
		im_error( "im_zerox", "%s", _( "flag not -1 or 1" ) );
		return( -1 );
	}
	if( in->Xsize < 2 ) {
		im_error( "im_zerox", "%s", _( "image too narrow" ) );
		return( -1 );
	}
	if( !(t1 = im_open_local( out, "im_zerox" , "p" )) ||
		im_piocheck( in, t1 ) ||
		im_check_uncoded( "im_zerox", in ) ||
		im_check_noncomplex( "im_zerox", in ) )
		return( -1 );
	if( vips_bandfmt_isuint( in->BandFmt ) )
		/* Unsigned type, therefore there will be no zero-crossings.
		 */
		return( im_black( out, in->Xsize, in->Ysize, in->Bands ) );

	/* Force output to be BYTE. Output is narrower than input by 1 pixel.
	 */
	if( im_cp_desc( t1, in ) )
		return( -1 );
	t1->BandFmt = IM_BANDFMT_UCHAR;
	t1->Xsize -= 1;

	/* Set hints - THINSTRIP is ok with us.
	 */
	if( im_demand_hint( t1, IM_THINSTRIP, NULL ) )
		return( -1 );

	/* Generate image.
	 */
	if( im_generate( t1, im_start_one, zerox_gen, im_stop_one, 
		in, GINT_TO_POINTER( sign ) ) )
		return( -1 );

	/* Now embed it in a larger image.
	 */
	if( im_embed( t1, out, 0, 0, 0, in->Xsize, in->Ysize ) )
		return( -1 );

	return( 0 );
}
コード例 #8
0
ファイル: im_measure.c プロジェクト: Ikulagin/transmem
/**
 * im_measure_area:
 * @im: image to measure
 * @left: area of image containing chart
 * @top: area of image containing chart
 * @width: area of image containing chart
 * @height: area of image containing chart
 * @h: patches across chart
 * @v: patches down chart
 * @sel: array of patch numbers to measure (numbered from 1 in row-major order)
 * @nsel: length of patch number array
 * @name: name to give to returned @DOUBLEMASK
 *
 * Analyse a grid of colour patches, producing a #DOUBLEMASK of patch averages.
 * The mask has a row for each measured patch, and a column for each image
 * band. The operations issues a warning if any patch has a deviation more 
 * than 20% of
 * the mean. Only the central 50% of each patch is averaged. If @sel is %NULL
 * then all patches are measured.
 *
 * Example: 6 band image of 4x2 block of colour patches.
 *
 * <tgroup cols='4' align='left' colsep='1' rowsep='1'>
 *   <tbody>
 *     <row>
 *       <entry>1</entry>
 *       <entry>2</entry>
 *       <entry>3</entry>
 *       <entry>4</entry>
 *     </row>
 *     <row>
 *       <entry>5</entry>
 *       <entry>6</entry>
 *       <entry>7</entry>
 *       <entry>8</entry>
 *     </row>
 *   </tbody>
 * </tgroup>
 *
 * Then call im_measure( im, box, 4, 2, { 2, 4 }, 2, "fred" ) makes a mask
 * "fred" which has 6 columns, two rows. The first row contains the averages
 * for patch 2, the second for patch 4.
 *
 * See also: im_avg(), im_deviate(), im_stats().
 * 
 * Returns: #DOUBLEMASK of measurements.
 */
DOUBLEMASK *
im_measure_area( IMAGE *im, 
	int left, int top, int width, int height, 
	int u, int v, 
	int *sel, int nsel, const char *name )
{	
	DOUBLEMASK *mask;

	/* Check input image.
	 */
	if( im->Coding == IM_CODING_LABQ ) {
		IMAGE *t1;
		
		if( !(t1 = im_open( "measure-temp", "p" )) )
			return( NULL );
		if( im_LabQ2Lab( im, t1 ) ||
			!(mask = im_measure_area( t1, 
				left, top, width, height,
				u, v, 
				sel, nsel, name )) ) {
			im_close( t1 );
			return( NULL );
		}

		im_close( t1 );

		return( mask );
	}

	if( im_check_uncoded( "im_measure", im ) ||
		im_check_noncomplex( "im_measure", im ) )
		return( NULL );

	/* Default to all patches if sel == NULL.
	 */
	if( sel == NULL ) {
		int i;

		nsel = u * v;
		if( !(sel = IM_ARRAY( im, nsel, int )) )
			return( NULL );
		for( i = 0; i < nsel; i++ )
			sel[i] = i + 1;
	}
コード例 #9
0
ファイル: im_measure.c プロジェクト: alon/libvips
static DOUBLEMASK *
internal_im_measure_area( IMAGE *im, 
	int left, int top, int width, int height, 
	int u, int v, 
	int *sel, int nsel, const char *name )
{	
	DOUBLEMASK *mask;

	if( im_check_uncoded( "im_measure", im ) ||
		im_check_noncomplex( "im_measure", im ) )
		return( NULL );

	/* Default to all patches if sel == NULL.
	 */
	if( sel == NULL ) {
		int i;

		nsel = u * v;
		if( !(sel = IM_ARRAY( im, nsel, int )) )
			return( NULL );
		for( i = 0; i < nsel; i++ )
			sel[i] = i + 1;
	}
コード例 #10
0
ファイル: fits.c プロジェクト: nrobidoux/libvips
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsImage *flip;
	VipsImage *type;
	VipsFits *fits;
	int status;

	status = 0;

	if( im_check_noncomplex( "im_vips2fits", in ) ||
		im_check_uncoded( "im_vips2fits", in ) )
		return( NULL );

	/* Cast to a supported format.
	 */
	if( !(type = vips_image_new()) ||
		vips_object_local( in, type ) ||
		im_clip2fmt( in, type, vips_fits_bandfmt[in->BandFmt] ) )
		return( NULL );
	in = type;

	/* FITS has (0,0) in the bottom left, we need to flip.
	 */
	if( !(flip = vips_image_new()) ||
		vips_object_local( in, flip ) ||
		im_flipver( in, flip ) )
		return( NULL );
	in = flip;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = im_strdup( NULL, filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = im_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, PEL )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		im_error( "fits", _( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = g_mutex_new();

	return( fits );
}