/* Call im_conv via arg vector.
 */
static int
conv_vec( im_object *argv )
{
	im_mask_object *mo = argv[2];

	return( im_conv( argv[0], argv[1], mo->mask ) );
}
Beispiel #2
0
int 
im_lindetect( IMAGE *in, IMAGE *out, INTMASK *mask )
{
	IMAGE *filtered[4];
	IMAGE *absed[4];
	int i;

	if( im_open_local_array( out, filtered, 4, "im_lindetect:1", "p" ) ||
		im_open_local_array( out, absed, 4, "im_lindetect:2", "p" ) )
		return( -1 );

	for( i = 0; i < 4; i++ ) {
		if( im_conv( in, filtered[i], mask ) ||
		    !(mask = (INTMASK *) im_local( out, 
			(im_construct_fn) im_rotate_imask45,
			(im_callback_fn) im_free_imask,
			mask, mask->filename, NULL )) )
			return( -1 );
	}

	for( i = 0; i < 4; i++ ) 
		if( im_abs( filtered[i], absed[i] ) )
			return( -1 );

	return( im_maxvalue( absed, out, 4 ) );
}
Beispiel #3
0
/**
 * im_ismonotonic:
 * @lut: lookup-table to test
 * @out: set non-zero if @lut is monotonic
 *
 * Test @lut for monotonicity. @out is set non-zero if @lut is monotonic.
 *
 * See also: im_tone_build_range().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_ismonotonic( IMAGE *lut, int *out )
{
    IMAGE *t[2];
    INTMASK *mask;
    double m;

    if( im_check_hist( "im_ismonotonic", lut ) ||
            im_open_local_array( lut, t, 2, "im_ismonotonic", "p" ) )
        return( -1 );

    if( lut->Xsize == 1 )
        mask = im_create_imaskv( "im_ismonotonic", 1, 2, -1, 1 );
    else
        mask = im_create_imaskv( "im_ismonotonic", 2, 1, -1, 1 );
    if( !(mask = im_local_imask( lut, mask )) )
        return( -1 );
    mask->offset = 128;

    /* We want >=128 everywhere, ie. no -ve transitions.
     */
    if( im_conv( lut, t[0], mask ) ||
            im_moreeqconst( t[0], t[1], 128 ) ||
            im_min( t[1], &m ) )
        return( -1 );

    *out = m;

    return( 0 );
}
Beispiel #4
0
/**
 * im_gradient:
 * @in: input image
 * @out: output image
 * @mask: convolution mask
 *
 * @in is convolved with @mask and with @mask after a 90 degree rotation. The
 * result is the sum of the absolute value of the two convolutions. 
 *
 * See also: im_lindetect(), im_gradient(), im_conv().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
{
	IMAGE *t[4];
	INTMASK *rmask;

	if( im_open_local_array( out, t, 4, "im_gradient", "p" ) )
		return( -1 );

	if( !(rmask = im_local_imask( out, 
		im_rotate_imask90( mask, mask->filename ) )) ) 
		return( -1 );

	if( im_conv( in, t[0], mask ) ||
		im_conv( in, t[1], rmask ) ||
		im_abs( t[0], t[2] ) ||
		im_abs( t[1], t[3] ) ||
		im_add( t[2], t[3], out ) )
		return( -1 );

	return( 0 );
}
Beispiel #5
0
int
im_gradient( IMAGE *in, IMAGE *out, INTMASK *mask )
{
	IMAGE *t[GTEMPS];
	INTMASK *rmask;

	if( im_open_local_array( out, t, GTEMPS, "im_gradient", "p" ) )
		return( -1 );

	if( !(rmask = (INTMASK *) im_local( out, 
		(im_construct_fn) im_rotate_imask90,
		(im_callback_fn) im_free_imask, mask, mask->filename, NULL )) )
		return( -1 );

	if( im_conv( in, t[0], mask ) ||
		im_conv( in, t[1], rmask ) ||
		im_abs( t[0], t[2] ) ||
		im_abs( t[1], t[3] ) ||
		im_add( t[2], t[3], out ) )
		return( -1 );

	return( 0 );
}
Beispiel #6
0
VALUE
img_conv(VALUE obj, VALUE m)
{
    DOUBLEMASK *dmask;
    INTMASK *imask;

    GetImg(obj, data, im);
	OutImg2(obj, m, new, data_new, im_new);

    mask_arg2mask(m, &imask, &dmask);

    if (imask) {
        if (im_conv(im, im_new, imask))
            vips_lib_error();
    } else if (im_conv_f(im, im_new, dmask))
        vips_lib_error();

    return new;
}   
Beispiel #7
0
/**
 * im_compass:
 * @in: input image
 * @out: output image
 * @mask: convolution mask
 *
 * @in is convolved 8 times with @mask, each time @mask is rotated by 45
 * degrees. Each output pixel is the largest absolute value of the 8
 * convolutions.
 *
 * See also: im_lindetect(), im_gradient(), im_conv().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_compass( IMAGE *in, IMAGE *out, INTMASK *mask )
{
	IMAGE *filtered[8];
	IMAGE *absed[8];
	int i;

	if( im_open_local_array( out, filtered, 8, "im_compass:1", "p" ) ||
		im_open_local_array( out, absed, 8, "im_compass:2", "p" ) )
		return( -1 );

	for( i = 0; i < 8; i++ ) {
		if( im_conv( in, filtered[i], mask ) ||
			!(mask = im_local_imask( out, 
				im_rotate_imask45( mask, mask->filename ) )) )
			return( -1 );
	}

	for( i = 0; i < 8; i++ ) 
		if( im_abs( filtered[i], absed[i] ) )
			return( -1 );

	return( im_maxvalue( absed, out, 8 ) );
}
int
main (int argc, char **argv) {
    const int NTMPS = 3;
	VipsImage *in, *out;
    VipsImage *tmps[NTMPS];
    INTMASK *mask;
    int stat;
    const char *ifile, *ofile;
    int extractTop = 100, extractBtm = 200;

    check(argc == 3, "Syntax: %s <input> <output>", argv[0]);
    ifile = argv[1];
    ofile = argv[2];

    timer_start(ifile, "Setup");

    if (im_init_world (argv[0])) error_exit ("unable to start VIPS");

    in = im_open( ifile, "r" );
    if (!in) vips_error_exit( "unable to read %s", ifile );
    check(in->Ysize > 5 && in->Xsize > 5,
          "Input image must be larger than 5 in both dimensions",
          extractBtm);

    stat = im_open_local_array(in, tmps, NTMPS, "tt", "p");
    check(!stat, "Unable to create temps.");

    mask = mk_convmat();

    timer_done();

    /* Reduce the extraction size if it's bigger than the image. */
    if (extractBtm + extractTop >= in->Ysize ||
        extractBtm + extractTop >= in->Xsize) {
        extractTop = 2;
        extractBtm = 2;
    }/* if */

    timer_start(ifile, "im_extract_area");
    check(
        !im_extract_area(in, tmps[0], extractTop, extractTop, in->Xsize - extractBtm,
                         in->Ysize - extractBtm),
        "extract failed.");
    timer_done();

    timer_start(ifile, "im_affine");
    check(
        !im_affine(tmps[0], tmps[1], 0.9, 0, 0, 0.9, 0, 0,
                   0, 0, in->Xsize * 0.9, in->Ysize * 0.9),
        "im_affine failed.");
    timer_done();

    timer_start(ifile, "im_conv");
    check(
        !im_conv (tmps[1], tmps[2], mask),
        "im_conv failed.");
    timer_done();
        
    timer_start(ofile, "writing output");
    out = im_open(ofile, "w");
    check(!!out, "file output failed.");

    im_copy(tmps[2], out);
    timer_done();
    

    timer_start(ofile, "teardown");
    im_close(out);
    im_close(in);
    timer_done();

    print_times();

    return 0;
}/* main */
Beispiel #9
0
static int
shrink_factor( IMAGE *in, IMAGE *out, 
	int shrink, double residual, VipsInterpolate *interp )
{
	IMAGE *t[9];
	VipsImage **s = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 1 );
	IMAGE *x;
	int tile_width;
	int tile_height;
	int nlines;

	if( im_open_local_array( out, t, 9, "thumbnail", "p" ) )
		return( -1 );
	x = in;

	/* Unpack the two coded formats we support to float for processing.
	 */
	if( x->Coding == IM_CODING_LABQ ) {
		if( verbose ) 
			printf( "unpacking LAB to RGB\n" );

		if( im_LabQ2disp( x, t[1], im_col_displays( 7 ) ) )
			return( -1 );
		x = t[1];
	}
	else if( x->Coding == IM_CODING_RAD ) {
		if( verbose ) 
			printf( "unpacking Rad to float\n" );

		if( im_rad2float( x, t[1] ) )
			return( -1 );
		x = t[1];
	}

	if( im_shrink( x, t[2], shrink, shrink ) )
		return( -1 );

	/* We want to make sure we read the image sequentially.
	 * However, the convolution we may be doing later will force us 
	 * into SMALLTILE or maybe FATSTRIP mode and that will break
	 * sequentiality.
	 *
	 * So ... read into a cache where tiles are scanlines, and make sure
	 * we keep enough scanlines to be able to serve a line of tiles.
	 */
	vips_get_tile_size( t[2], 
		&tile_width, &tile_height, &nlines );
	if( vips_tilecache( t[2], &s[0], 
		"tile_width", t[2]->Xsize,
		"tile_height", 10,
		"max_tiles", (nlines * 2) / 10,
		"strategy", VIPS_CACHE_SEQUENTIAL,
		NULL ) ||
		im_affinei_all( s[0], t[4], 
			interp, residual, 0, 0, residual, 0, 0 ) )
		return( -1 );
	x = t[4];

	/* If we are upsampling, don't sharpen, since nearest looks dumb
	 * sharpened.
	 */
	if( shrink > 1 && residual <= 1.0 && !nosharpen ) {
		if( verbose ) 
			printf( "sharpening thumbnail\n" );

		if( im_conv( x, t[5], sharpen_filter() ) )
			return( -1 );
		x = t[5];
	}

	/* Colour management: we can transform the image if we have an output
	 * profile and an input profile. The input profile can be in the
	 * image, or if there is no profile there, supplied by the user.
	 */
	if( export_profile &&
		(im_header_get_typeof( x, IM_META_ICC_NAME ) || 
		 import_profile) ) {
		if( im_header_get_typeof( x, IM_META_ICC_NAME ) ) {
			if( verbose ) 
				printf( "importing with embedded profile\n" );

			if( im_icc_import_embedded( x, t[6], 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}
		else {
			if( verbose ) 
				printf( "importing with profile %s\n",
					import_profile );

			if( im_icc_import( x, t[6], 
				import_profile, 
				IM_INTENT_RELATIVE_COLORIMETRIC ) )
				return( -1 );
		}

		if( verbose ) 
			printf( "exporting with profile %s\n", export_profile );

		if( im_icc_export_depth( t[6], t[7], 
			8, export_profile, 
			IM_INTENT_RELATIVE_COLORIMETRIC ) )
			return( -1 );

		x = t[7];
	}

	if( delete_profile ) {
		if( verbose )
			printf( "deleting profile from output image\n" );

		if( im_meta_get_typeof( x, IM_META_ICC_NAME ) &&
			!im_meta_remove( x, IM_META_ICC_NAME ) )
			return( -1 );
	}

	if( im_copy( x, out ) )
		return( -1 );

	return( 0 );
}