Пример #1
0
int 
im_rot270( IMAGE *in, IMAGE *out )
{	
	/* Make output image.
	 */
	if( im_piocheck( in, out ) ) 
		return( -1 );
	if( in->Coding != IM_CODING_NONE && in->Coding != IM_CODING_LABQ ) {
		im_error( "im_rot270", _( "uncoded or IM_CODING_LABQ only" ) );
		return( -1 );
	}
	if( im_cp_desc( out, in ) ) 
		return( -1 );
	out->Xsize = in->Ysize;
	out->Ysize = in->Xsize;

	/* We want smalltile if possible.
	 */
	if( im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
		return( -1 );

	/* Generate!
	 */
	if( im_generate( out, 
		im_start_one, rot270_gen, im_stop_one, in, NULL ) )
		return( -1 );

	out->Xoffset = 0;
	out->Yoffset = in->Xsize;

	return( 0 );
}
Пример #2
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 );
}
Пример #3
0
static int
fits2vips( const char *filename, VipsImage *out, int band_select )
{
	VipsFits *fits;

	/* The -1 mode is just for reading the header.
	 */
	g_assert( band_select >= 0 );

	if( !(fits = vips_fits_new_read( filename, out, band_select )) )
		return( -1 );
	if( vips_fits_get_header( fits, out ) ||
		im_demand_hint( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL ) ||
		im_generate( out, 
			NULL, fits2vips_generate, NULL, fits, NULL ) ) {
		vips_fits_close( fits );
		return( -1 );
	}

	/* Don't vips_fits_close(), we need it to stick around for the
	 * generate.
	 */

	return( 0 );
}
Пример #4
0
/**
 * 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 );
}
Пример #5
0
/* Copy image.
 */
int 
im_fliphor( IMAGE *in, IMAGE *out )
{	
	/* Check args.
	 */
        if( im_piocheck( in, out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE && in->Coding != IM_CODING_LABQ ) {
		im_error( "im_fliphor", _( "in must be uncoded" ) );
		return( -1 );
	}

	/* Prepare output header.
	 */
	if( im_cp_desc( out, in ) )
		return( -1 );

	/* Set demand hints.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
		return( -1 );

	/* Generate!
	 */
	if( im_generate( out, im_start_one, flip_gen, im_stop_one, in, NULL ) )
		return( -1 );

	out->Xoffset = in->Xsize;
	out->Yoffset = 0;

	return( 0 );
}
Пример #6
0
static int
ifthenelse( IMAGE *c, IMAGE *a, IMAGE *b, IMAGE *out )
{
	IMAGE **in;

	/* Check args.
	 */
	if( im_check_uncoded( "im_ifthenelse", c ) ||
		im_check_coding_known( "im_ifthenelse", a ) ||
		im_check_coding_known( "im_ifthenelse", b ) ||
		im_check_format( "ifthenelse", c, IM_BANDFMT_UCHAR ) || 
		im_check_format_same( "ifthenelse", a, b ) ||
		im_check_bands_same( "ifthenelse", a, b ) ||
		im_check_bands_1orn( "im_ifthenelse", c, a ) || 
		im_piocheck( c, out ) || 
		im_pincheck( a ) || 
		im_pincheck( b ) )
                return( -1 );

	/* Make output image.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, c, a, b, NULL ) ||
		im_cp_descv( out, a, b, c, NULL ) || 
		!(in = im_allocate_input_array( out, c, a, b, NULL )) ||
		im_generate( out, 
			im_start_many, ifthenelse_gen, im_stop_many, 
				in, NULL ) )
		return( -1 );

	return( 0 );
}
Пример #7
0
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 );
}
Пример #8
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
}
Пример #9
0
/**
 * im_maplut:
 * @in: input image
 * @out: output image
 * @lut: look-up table
 *
 * Map an image through another image acting as a LUT (Look Up Table). 
 * The lut may have any type, and the output image will be that type.
 * 
 * The input image will be cast to one of the unsigned integer types, that is,
 * IM_BANDFMT_UCHAR, IM_BANDFMT_USHORT or IM_BANDFMT_UINT.
 * 
 * If @lut is too small for the input type (for example, if @in is
 * IM_BANDFMT_UCHAR but @lut only has 100 elements), the lut is padded out
 * by copying the last element. Overflows are reported at the end of 
 * computation.
 * If @lut is too large, extra values are ignored. 
 * 
 * If @lut has one band, then all bands of @in pass through it. If @lut
 * has same number of bands as @in, then each band is mapped
 * separately. If @in has one band, then @lut may have many bands and
 * the output will have the same number of bands as @lut.
 *
 * See also: im_histgr(), im_identity().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_maplut( IMAGE *in, IMAGE *out, IMAGE *lut )
{
	IMAGE *t;
	LutInfo *st;

	/* Check input output. Old-style IO from lut, for simplicity.
	 */
	if( im_check_hist( "im_maplut", lut ) ||
		im_check_uncoded( "im_maplut", lut ) ||
		im_check_uncoded( "im_maplut", in ) ||
		im_check_bands_1orn( "im_maplut", in, lut ) ||
		im_piocheck( in, out ) || 
		im_incheck( lut ) )
		return( -1 );

	/* Cast in to u8/u16/u32.
	 */
	if( !(t = im_open_local( out, "im_maplut", "p" )) ||
		im_clip2fmt( in, t, bandfmt_maplut[in->BandFmt] ) )
		return( -1 );

	/* Prepare the output header.
	 */
        if( im_cp_descv( out, t, lut, NULL ) )
                return( -1 );

	/* Force output to be the same type as lut.
	 */
	out->BandFmt = lut->BandFmt;

	/* Output has same number of bands as LUT, unless LUT has 1 band, in
	 * which case output has same number of bands as input.
	 */
	if( lut->Bands != 1 )
		out->Bands = lut->Bands;

	/* Make tables.
	 */
	if( !(st = build_luts( out, lut )) )
		return( -1 );

	/* Set demand hints.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, t, NULL ) )
		return( -1 );

	/* Process!
	 */
        if( im_generate( out, maplut_start, maplut_gen, maplut_stop, t, st ) )
                return( -1 );

        return( 0 );
}
Пример #10
0
/* Copy image, changing header fields.
 */
static int 
im_copy_set_all( IMAGE *in, IMAGE *out, 
	VipsType type, float xres, float yres, int xoffset, int yoffset,
	int bands, VipsBandFmt bandfmt, VipsCoding coding )
{
	/* Check args.
	 */
        if( im_check_coding_known( "im_copy", in ) ||
		im_piocheck( in, out ) )
		return( -1 );
	if( coding != IM_CODING_NONE && 
		coding != IM_CODING_LABQ &&
		coding != IM_CODING_RAD ) {
		im_error( "im_copy", "%s", 
			_( "coding must be NONE, LABQ or RAD" ) );
		return( -1 );
	}
	if( bandfmt < 0 || bandfmt > IM_BANDFMT_DPCOMPLEX ) {
		im_error( "im_copy", _( "bandfmt must be in range [0,%d]" ),
			IM_BANDFMT_DPCOMPLEX );
		return( -1 );
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = type;
	out->Xres = xres;
	out->Yres = yres;
	out->Xoffset = xoffset;
	out->Yoffset = yoffset;
	out->Bands = bands;
	out->BandFmt = bandfmt;
	out->Coding = coding;

	/* Sanity check: we (may) have changed bytes-per-pixel since we've
	 * changed Bands and BandFmt ... bad!
	 */
	if( IM_IMAGE_SIZEOF_PEL( in ) != IM_IMAGE_SIZEOF_PEL( out ) ) {
		im_error( "im_copy", "%s", _( "sizeof( pixel ) has changed" ) );
		return( -1 );
	}

	/* Generate!
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) ||
		im_generate( out, 
			im_start_one, copy_gen, im_stop_one, in, NULL ) )
		return( -1 );

	return( 0 );
}
Пример #11
0
/* 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_errormsg( "im_fastcor: ref not smaller than in" );
        return( -1 );
    }

    /* Check types.
     */
    if( in->Coding != IM_CODING_NONE || in->Bands != 1 ||
            in->BandFmt != IM_BANDFMT_UCHAR ||
            ref->Coding != IM_CODING_NONE || ref->Bands != 1 ||
            ref->BandFmt != IM_BANDFMT_UCHAR ) {
        im_errormsg( "im_fastcor_raw: input not uncoded 1 band uchar" );
        return( -1 );
    }

    /* Prepare the output image.
     */
    if( im_cp_descv( out, in, ref, NULL ) )
        return( -1 );
    out->Bbits = IM_BBITS_INT;
    out->BandFmt = IM_BANDFMT_UINT;
    out->Xsize = in->Xsize - ref->Xsize + 1;
    out->Ysize = in->Ysize - ref->Ysize + 1;

    /* 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 correlation.
     */
    if( 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 );
}
Пример #12
0
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 );
}
Пример #13
0
/* Join two images. out->Bands = in1->Bands + in2->Bands. in1 goes first in
 * the list.  
 */
int
im_bandjoin( IMAGE *in1, IMAGE *in2, IMAGE *out )
{
	IMAGE **in;

	/* Check our args. 
	 */
	if( im_piocheck( in1, out ) )
		return( -1 );
	if( im_piocheck( in2, out ) ) 
		return( -1 );
	if( in1->Xsize != in2->Xsize ||
		in1->Ysize != in2->Ysize ) {
		im_errormsg( "im_bandjoin: images not same size" );
		return( -1 );
	}
	if( in1->BandFmt != in2->BandFmt ) {
		im_errormsg( "im_bandjoin: images not same type" );
		return( -1 );
	}
	if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) {
		im_errormsg( "im_bandjoin: input coded" );
		return( -1 );
	}

	/* Set up the output header.
	 */
	if( im_cp_descv( out, in1, in2, NULL ) )
                return( -1 ); 
	out->Bands = in1->Bands + in2->Bands;

	/* Set demand hints.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in1, in2, NULL ) )
		 return( -1 );

	/* Make input array. 
	 */
	if( !(in = im_allocate_input_array( out, in1, in2, NULL )) )
		return( -1 );

	/* Make output image.
	 */
	if( im_generate( out, 
		im_start_many, bandjoin_gen, im_stop_many, in, NULL ) )
		return( -1 );

	return( 0 );
}
Пример #14
0
/* Morph an image.
 */
static int
morphology( IMAGE *in, IMAGE *out, INTMASK *mask, MorphOp op )
{
	Morph *morph;
	im_generate_fn generate;

	/* Check parameters.
	 */
	if( !(morph = morph_new( in, out, mask, op )) )
		return( -1 );

	/* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output
	 * would be 1x1.
	 */
	if( im_cp_desc( morph->out, morph->in ) )
		return( -1 );
	morph->out->Xsize -= morph->mask->xsize - 1;
	morph->out->Ysize -= morph->mask->ysize - 1;
	if( morph->out->Xsize <= 0 || 
		morph->out->Ysize <= 0 ) {
		im_error( "morph", "%s", _( "image too small for mask" ) );
		return( -1 );
	}

	if( morph->n_pass ) {
		generate = morph_vector_gen;

#ifdef DEBUG
		printf( "morph_vector_gen: %d passes\n", morph->n_pass );
#endif /*DEBUG*/
	}
	else if( morph->op == DILATE )
		generate = dilate_gen;
	else
		generate = erode_gen;

	/* Set demand hints. FATSTRIP is good for us, as THINSTRIP will cause
	 * too many recalculations on overlaps.
	 */
	if( im_demand_hint( morph->out, IM_FATSTRIP, morph->in, NULL ) ||
		im_generate( morph->out, 
			morph_start, generate, morph_stop, morph->in, morph ) )
		return( -1 );

	morph->out->Xoffset = -morph->mask->xsize / 2;
	morph->out->Yoffset = -morph->mask->ysize / 2;

	return( 0 );
}
Пример #15
0
/**
 * 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 );
}
Пример #16
0
/* 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 );
}
Пример #17
0
int
im__tbmerge( IMAGE *ref, IMAGE *sec, IMAGE *out, int dx, int dy, int mwidth )
{  
	Overlapping *ovlap;

	if( dy > 0 || dy < 1 - ref->Ysize ) {
		/* No overlap, use insert instead.
		 */
  		if( im_insert( ref, sec, out, -dx, -dy ) )
			return( -1 );
		out->Xoffset = -dx;
		out->Yoffset = -dy;

		return( 0 );
	}

	/* Build state for this join.
	 */
	if( !(ovlap = build_tbstate( ref, sec, out, dx, dy, mwidth )) )
		return( -1 );

	/* Prepare the output IMAGE.
	 */ 
	if( im_cp_descv( out, ref, sec, NULL ) )
		return( -1 );
	out->Xsize = ovlap->oarea.width;
	out->Ysize = ovlap->oarea.height;
	out->Xoffset = ovlap->sarea.left;
	out->Yoffset = ovlap->sarea.top;

	/* Set demand hints. 
	 */
	if( im_demand_hint( out, IM_THINSTRIP, ref, sec, NULL ) )
		return( -1 );

	/* Generate!
	 */
	if( im_generate( out,
		im__start_merge, im__merge_gen, im__stop_merge, ovlap, NULL ) )
		return( -1 );

	return ( 0 );
}
Пример #18
0
static int
shrink( IMAGE *in, IMAGE *out, double xshrink, double yshrink )
{
    ShrinkInfo *st;

    /* Prepare output. Note: we round the output width down!
     */
    if( im_cp_desc( out, in ) )
        return( -1 );
    out->Xsize = in->Xsize / xshrink;
    out->Ysize = in->Ysize / yshrink;
    out->Xres = in->Xres / xshrink;
    out->Yres = in->Yres / yshrink;
    if( out->Xsize <= 0 || out->Ysize <= 0 ) {
        im_error( "im_shrink",
                  "%s", _( "image has shrunk to nothing" ) );
        return( -1 );
    }

    /* Build and attach state struct.
     */
    if( !(st = IM_NEW( out, ShrinkInfo )) )
        return( -1 );
    st->xshrink = xshrink;
    st->yshrink = yshrink;
    st->mw = ceil( xshrink );
    st->mh = ceil( yshrink );
    st->np = st->mw * st->mh;

    /* Set demand hints. We want THINSTRIP, as we will be demanding a
     * large area of input for each output line.
     */
    if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
        return( -1 );

    /* Generate!
     */
    if( im_generate( out,
                     shrink_start, shrink_gen, shrink_stop, in, st ) )
        return( -1 );

    return( 0 );
}
Пример #19
0
/**
 * im_rot180:
 * @in: input image
 * @out: output image
 *
 * Rotate an image 180 degrees.
 *
 * See also: im_rot90(), im_rot270(), im_affinei_all().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_rot180( IMAGE *in, IMAGE *out )
{
	if( im_piocheck( in, out ) || 
		im_check_coding_known( "im_rot180", in ) )
		return( -1 );

	if( im_cp_desc( out, in ) || 
		im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
		return( -1 );

	if( im_generate( out, 
		im_start_one, rot180_gen, im_stop_one, in, NULL ) )
		return( -1 );

	out->Xoffset = in->Xsize;
	out->Yoffset = in->Ysize;

	return( 0 );
}
Пример #20
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 );
  }
}
Пример #21
0
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
}
Пример #22
0
/** 
 * im_tile_cache:
 * @in: input image
 * @out: output image
 * @tile_width: tile width
 * @tile_height: tile height
 * @max_tiles: maximum number of tiles to cache
 *
 * This operation behaves rather like im_copy() between images
 * @in and @out, except that it keeps a cache of computed pixels. 
 * This cache is made of up to @max_tiles tiles (a value of -1 for
 * means any number of tiles), and each tile is of size @tile_width
 * by @tile_height pixels. Each cache tile is made with a single call to 
 * im_prepare().
 *
 * This is a lower-level operation than im_cache() since it does no 
 * subdivision. It is suitable for caching the output of operations like
 * im_exr2vips() on tiled images.
 *
 * See also: im_cache().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_tile_cache( IMAGE *in, IMAGE *out,
	int tile_width, int tile_height, int max_tiles )
{
	Read *read;

	if( tile_width <= 0 || tile_height <= 0 || max_tiles < -1 ) {
		im_error( "im_tile_cache", "%s", _( "bad parameters" ) );
		return( -1 );
	}

	if( im_piocheck( in, out ) ||
		im_cp_desc( out, in ) ||
		im_demand_hint( out, IM_SMALLTILE, in, NULL ) ||
		!(read = read_new( in, out, 
			tile_width, tile_height, max_tiles )) ||
		im_generate( out, 
			im_start_one, tile_cache_fill, im_stop_one, in, read ) )
		return( -1 );

	return( 0 );
}
Пример #23
0
/**
 * im_replicate:
 * @in: input image
 * @out: output image
 * @across: repeat @in this many times across
 * @down: repeat @in this many times down
 *
 * Replicate an image x times horizontally and vertically.
 * 
 * See also: im_embed(), im_copy().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_replicate( IMAGE *in, IMAGE *out, int across, int down )
{
	if( across <= 0 || down <= 0 ) {
		im_error( "im_replicate", "%s", _( "bad parameters" ) );
		return( -1 );
	}
	if( im_piocheck( in, out ) ||
		im_cp_desc( out, in ) )
		return( -1 );
	out->Xsize *= across;
	out->Ysize *= down;

	/* We can render small tiles with pointer copies.
	 */
	if( im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
		return( -1 );

	if( im_generate( out, 
		im_start_one, replicate_gen, im_stop_one, in, NULL ) )
		return( -1 );

	return( 0 );
}
Пример #24
0
/**
 * 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 );
}
Пример #25
0
static int 
affinei( IMAGE *in, IMAGE *out, 
	VipsInterpolate *interpolate, Transformation *trn )
{
	Affine *affine;
	double edge;

	/* Make output image.
	 */
	if( im_piocheck( in, out ) ) 
		return( -1 );
	if( im_cp_desc( out, in ) ) 
		return( -1 );

	/* Need a copy of the params for the lifetime of out.
	 */
	if( !(affine = IM_NEW( out, Affine )) )
		return( -1 );
	affine->interpolate = NULL;
	if( im_add_close_callback( out, 
		(im_callback_fn) affine_free, affine, NULL ) )
		return( -1 );
	affine->in = in;
	affine->out = out;
	affine->interpolate = interpolate;
	g_object_ref( interpolate );
	affine->trn = *trn;

	if( im__transform_calc_inverse( &affine->trn ) )
		return( -1 );

	out->Xsize = affine->trn.oarea.width;
	out->Ysize = affine->trn.oarea.height;

	/* Normally SMALLTILE ... except if this is a size up/down affine.
	 */
	if( affine->trn.b == 0.0 && affine->trn.c == 0.0 ) {
		if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
			return( -1 );
	}
	else {
		if( im_demand_hint( out, IM_SMALLTILE, in, NULL ) )
			return( -1 );
	}

	/* Check for coordinate overflow ... we want to be able to hold the
	 * output space inside INT_MAX / TRANSFORM_SCALE.
	 */
	edge = INT_MAX / VIPS_TRANSFORM_SCALE;
	if( affine->trn.oarea.left < -edge || affine->trn.oarea.top < -edge ||
		IM_RECT_RIGHT( &affine->trn.oarea ) > edge || 
		IM_RECT_BOTTOM( &affine->trn.oarea ) > edge ) {
		im_error( "im_affinei", 
			"%s", _( "output coordinates out of range" ) );
		return( -1 );
	}

	/* Generate!
	 */
	if( im_generate( out, 
		im_start_one, affinei_gen, im_stop_one, in, affine ) )
		return( -1 );

	return( 0 );
}
Пример #26
0
/* Dilate an image.
 */
int
im_dilate_raw( IMAGE *in, IMAGE *out, INTMASK *m )
{
	INTMASK *msk;

	/* Check mask has odd number of elements in width and height.
	 */
	if( m->xsize < 1 || !(m->xsize & 0x1) ||
		m->ysize < 1 || !(m->ysize & 0x1) ) {
		im_error( "im_dilate", _( "mask size not odd" ) ); 
		return( -1 ); 
	}

	/* Standard checks.
	 */
	if( im_piocheck( in, out ) ) 
		return( -1 ); 
	if( in->Coding != IM_CODING_NONE || in->Bbits != 8 || 
		in->BandFmt != IM_BANDFMT_UCHAR ) {
		im_error( "im_dilate", _( "uchar uncoded only" ) );
		return( -1 );
	}
	if( im_cp_desc( out, in ) ) 
		return( -1 ); 

	/* Prepare output. Consider a 7x7 mask and a 7x7 image --- the output
	 * would be 1x1.
	 */
	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Xsize -= m->xsize - 1;
	out->Ysize -= m->ysize - 1;
	if( out->Xsize <= 0 || out->Ysize <= 0 ) {
		im_error( "im_dilate", _( "image too small for mask" ) );
		return( -1 );
	}

	/* Take a copy of m.
	 */
	if( !(msk = im_dup_imask( m, "conv_mask" )) )
		return( -1 );
	if( im_add_close_callback( out, 
		(im_callback_fn) im_free_imask, msk, NULL ) ) {
		im_free_imask( msk );
		return( -1 );
	}

	/* 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 );

	/* Generate! 
	 */
	if( im_generate( out, dilate_start, dilate_gen, dilate_stop, in, msk ) )
		return( -1 );

	out->Xoffset = -m->xsize / 2;
	out->Yoffset = -m->ysize / 2;

	return( 0 );
}
Пример #27
0
int
im_stretch3( IMAGE *in, IMAGE *out, double dx, double dy )
{
	StretchInfo *sin;
	int i;
 
        /* Check our args. 
	 */
        if( in->Coding != IM_CODING_NONE || in->BandFmt != IM_BANDFMT_USHORT ) {
        	im_error( "im_stretch3", 
			"%s", _( "not uncoded unsigned short" ) );
        	return( -1 );
        }
	if( dx < 0 || dx >= 1.0 || dy < 0 || dy >= 1.0 ) {
		im_error( "im_stretch3", 
			"%s", _( "displacements out of range [0,1)" ) );
		return( -1 );
	}
	if( im_piocheck( in, out ) )
		return( -1 );

        /* Prepare the output image.
	 */
        if( im_cp_desc( out, in ) )
		return( -1 );
 	out->Xsize = 34*(in->Xsize / 33) + in->Xsize%33 - 3;
        out->Ysize = in->Ysize - 3;

        if( im_demand_hint( out, IM_FATSTRIP, in, NULL ) )
        	return( -1 );

        if( !(sin = IM_NEW( out, StretchInfo )) )
        	return( -1 );

	/* Save parameters.
	 */
	sin->in = in;
	sin->dx = dx;
	sin->dy = dy;

	/* Generate masks.
	 */
        for( i = 0; i < 34; i++ ) {
        	double d = (34.0 - i)/34.0;

		double y0 = 2.0*d*d - d - d*d*d;
		double y1 = 1.0 - 2.0*d*d + d*d*d;
		double y2 = d + d*d - d*d*d;
		double y3 = -d*d + d*d*d;

		sin->mask[i][0] = IM_RINT( y0 * 32768 );
		sin->mask[i][1] = IM_RINT( y1 * 32768 );
		sin->mask[i][2] = IM_RINT( y2 * 32768 );
		sin->mask[i][3] = IM_RINT( y3 * 32768 );
	}

	/* Which mask do we start with to apply these offsets?
	 */
	sin->xoff = (dx * 33.0) + 0.5;
	sin->yoff = (dy * 33.0) + 0.5;

        if( im_generate( out, 
		stretch_start, stretch_gen, stretch_stop, in, sin ) )
        	return( -1 );

	return( 0 );
}
Пример #28
0
/**
 * im_subsample:
 * @in: input image
 * @out: output image
 * @xshrink: horizontal shrink factor
 * @yshrink: vertical shrink factor
 *
 * Subsample an image by an integer fraction. This is fast nearest-neighbour
 * shrink.
 *
 * See also: im_shrink(), im_affinei(), im_zoom().
 * 
 * Returns: 0 on success, -1 on error.
 */
int 
im_subsample( IMAGE *in, IMAGE *out, int xshrink, int yshrink )
{
	SubsampleInfo *st;

	/* Check parameters.
	 */
	if( xshrink < 1 || yshrink < 1 ) {
		im_error( "im_subsample", 
			"%s", _( "factors should both be >= 1" ) );
		return( -1 );
	}
	if( xshrink == 1 && yshrink == 1 ) 
		return( im_copy( in, out ) );
	if( im_piocheck( in, out ) ||
		im_check_coding_known( "im_subsample", in ) )
		return( -1 );

	/* Prepare output. Note: we round the output width down!
	 */
	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Xsize = in->Xsize / xshrink;
	out->Ysize = in->Ysize / yshrink;
	out->Xres = in->Xres / xshrink;
	out->Yres = in->Yres / yshrink;
	if( out->Xsize <= 0 || out->Ysize <= 0 ) {
		im_error( "im_subsample", 
			"%s", _( "image has shrunk to nothing" ) );
		return( -1 );
	}

	/* Build and attach state struct.
	 */
	if( !(st = IM_NEW( out, SubsampleInfo )) )
		return( -1 );
	st->xshrink = xshrink;
	st->yshrink = yshrink;

	/* Set demand hints. We want THINSTRIP, as we will be demanding a
	 * large area of input for each output line.
	 */
	if( im_demand_hint( out, IM_THINSTRIP, in, NULL ) )
		return( -1 );

	/* Generate! If this is a very large shrink, then it's
	 * probably faster to do it a pixel at a time. 
	 */
	if( xshrink > 10 ) {
		if( im_generate( out, 
			im_start_one, point_shrink_gen, im_stop_one, in, st ) )
			return( -1 );
	}
	else {
		if( im_generate( out, 
			im_start_one, line_shrink_gen, im_stop_one, in, st ) )
			return( -1 );
	}

	return( 0 );
}
Пример #29
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 );
}