Пример #1
0
/**
 * im_mpercent_hist:
 * @hist: input histogram image
 * @percent: threshold percentage
 * @out: output threshold value
 *
 * Just like im_mpercent(), except it works on an image histogram. Handy if
 * you want to run im_mpercent() several times without having to recompute the
 * histogram each time.
 *
 * See also: im_mpercent().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_mpercent_hist( IMAGE *hist, double percent, int *out )
{
	IMAGE *base;
	IMAGE *t[6];
	double pos;

	if( im_check_hist( "im_mpercent", hist ) )
		return( -1 );

	if( !(base = im_open( "im_mpercent", "p" )) )
		return( -1 );
	if( im_open_local_array( base, t, 6, "im_mpercent", "p" ) ) {
		im_close( base );
		return( -1 );
	}

	if( im_histcum( hist, t[1] ) ||
		im_histnorm( t[1], t[2] ) ||
		im_lessconst( t[2], t[3], percent * t[2]->Xsize ) ||
		im_fliphor( t[3], t[4] ) ||
		im_profile( t[4], t[5], 1 ) ||
		im_avg( t[5], &pos ) ) {
		im_close( base );
		return( -1 );
	}
	im_close( base );

	*out = pos;

	return( 0 );
}
Пример #2
0
/* Init function for RW images.
 */
static int
rw_image_init( im_object *obj, char *str )
{
	IMAGE **im = (IMAGE **) obj;

	return( !(*im = im_open( str, "rw" )) );
}
Пример #3
0
/* Init function for imagevec input.
 */
static int
input_imagevec_init( im_object *obj, char *str )
{
	im_imagevec_object *iv = *obj;
	char **strv;
	int nargs;
	int i;

	strv = g_strsplit( str, VEC_SEPS, -1 );
	nargs = g_strv_length( strv );

	if( !(iv->vec = VIPS_ARRAY( NULL, nargs, IMAGE * )) ) {
		g_strfreev( strv );
		return( -1 );
	}
	iv->n = nargs;

	/* Must NULL them out in case we fail halfway though opening them all.
	 */
	for( i = 0; i < nargs; i++ )
		iv->vec[i] = NULL;

	for( i = 0; i < nargs; i++ ) 
		if( !(iv->vec[i] = im_open( strv[i], "rd" )) ) {
			g_strfreev( strv );
			return( -1 );
		}

	g_strfreev( strv );

	return( 0 );
}
Пример #4
0
int 
im_lrmosaic( IMAGE *ref, IMAGE *sec, IMAGE *out, 
	int bandno, 
	int xref, int yref, int xsec, int ysec, 
	int hwindowsize, int hsearchsize,
	int balancetype,
	int mwidth )
{
	int dx0, dy0;
	double scale1, angle1, dx1, dy1;
	IMAGE *dummy;

	/* Correct overlap. dummy is just a placeholder used to ensure that
	 * memory used by the analysis phase is freed as soon as possible.
	 */
	if( !(dummy = im_open( "placeholder:1", "p" )) )
		return( -1 );
	if( im__find_lroverlap( ref, sec, dummy,
		bandno, 
		xref, yref, xsec, ysec,
		hwindowsize, hsearchsize,
		&dx0, &dy0,
		&scale1, &angle1, &dx1, &dy1 ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	/* Merge left right.
	 */
        if( im_lrmerge( ref, sec, out, dx0, dy0, mwidth ) )
		return( -1 ); 

	return( 0 );
}
Пример #5
0
/* Call im__find_tboverlap via arg vector.
 */
static int
find_tboverlap_vec( im_object *argv )
{
	int bandno = *((int *) argv[2]);
	int xr = *((int *) argv[3]);
	int yr = *((int *) argv[4]);
	int xs = *((int *) argv[5]);
	int ys = *((int *) argv[6]);
	int halfcorrelation = *((int *) argv[7]);
	int halfarea = *((int *) argv[8]);
	int *dx0 = (int *) argv[9];
	int *dy0 = (int *) argv[10];
	double *scale1 = (double *) argv[11];
	double *angle1 = (double *) argv[12];
	double *dx1 = (double *) argv[13];
	double *dy1 = (double *) argv[14];

	IMAGE *t;
	int result;

	if( !(t = im_open( "find_tboverlap_vec", "p" )) )
		return( -1 );
	result = im__find_tboverlap( argv[0], argv[1], t, 
		bandno, 
		xr, yr, xs, ys, 
		halfcorrelation, halfarea,
		dx0, dy0, scale1, angle1, dx1, dy1 );
	im_close( t );

	return( result );
}
Пример #6
0
static VALUE
png_buf_internal(VALUE obj, VALUE compression, VALUE interlace)
{
#if IM_MAJOR_VERSION > 7 || IM_MINOR_VERSION >= 23
    VipsImage *im_out;
    char *buf;
    int length;
    GetImg(obj, data, im);

    if (!(im_out = im_open("writer_png_buf", "p")))
        vips_lib_error();

    if (im_vips2bufpng(im, im_out, NUM2INT(compression), NUM2INT(interlace),
        &buf, &length)) {
		im_close(im_out);
        vips_lib_error();
	}

    im_close(im_out);

    return rb_tainted_str_new(buf, length);
#else
    rb_raise(eVIPSError, "This method is not implemented in your version of VIPS");
#endif
}
Пример #7
0
/* Can this PPM file be read with a mmap?
 */
static int
isppmmmap( const char *filename )
{
	IMAGE *im;
        FILE *fp;
	int bits;
	int ascii;
	int msb_first;

	if( !(fp = im__file_open_read( filename, NULL, FALSE )) ) 
                return( -1 );

	if( !(im = im_open( "temp", "p" )) ) {
		fclose( fp );
		return( 0 );
	}
	if( read_header( fp, im, &bits, &ascii, &msb_first ) ) {
		im_close( im );
		fclose( fp );
		return( 0 );
	}
	im_close( im );
	fclose( fp );

	return( !ascii && bits >= 8 );
}
Пример #8
0
int
main( int argc, char *argv[] )
{
	GOptionContext *context;
	GError *error = NULL;
	int i;
	int result;

	if( im_init_world( argv[0] ) )
	        error_exit( "unable to start VIPS" );
	textdomain( GETTEXT_PACKAGE );
	setlocale( LC_ALL, "" );

        context = g_option_context_new( _( "- print image header" ) );

	g_option_context_add_main_entries( context,
		main_option, GETTEXT_PACKAGE );
	g_option_context_add_group( context, im_get_option_group() );

	if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
		if( error ) {
			fprintf( stderr, "%s\n", error->message );
			g_error_free( error );
		}

		error_exit( "try \"%s --help\"", g_get_prgname() );
	}

	g_option_context_free( context );

	result = 0;

	for( i = 1; i < argc; i++ ) {
		IMAGE *im;

		if( !(im = im_open( argv[i], "r" )) ) {
			print_error();
			result = 1;
		}

		if( im && 
			print_header( im, argc > 2 ) ) {
			print_error();
			result = 1;
		}

		if( im )
			im_close( im );
	}

	vips_shutdown();

	return( result );
}
Пример #9
0
/* Just for compatibility. New code should use vips_object_local() directly.
 */
VipsImage *
im_open_local( VipsImage *parent, 
	const char *filename, const char *mode )
{
	VipsImage *image;

	if( !(image = im_open( filename, mode )) )
		return( NULL );
	vips_object_local( parent, image );

	return( image );
}
Пример #10
0
static VALUE
writer_write_internal(VALUE obj, VALUE path)
{
    VipsImage *out;
    GetImg(obj, data, im);

    if (!(out = im_open(StringValuePtr(path), "w")) || im_copy(im, out))
        vips_lib_error();

    im_close(out);

    return obj;
}
Пример #11
0
static int
ismagick( const char *filename )
{
	IMAGE *im;
	int result;

	if( !(im = im_open( "dummy", "p" )) )
		return( -1 );
	result = magick2vips_header( filename, im );
	im_error_clear();
	im_close( im );

	return( result == 0 );
}
Пример #12
0
int 
im_freqflt( IMAGE *in, IMAGE *mask, IMAGE *out )
{
	IMAGE *dummy;

	/* Placeholder for memory free.
	 */
	if( !(dummy = im_open( "memory-1", "p" )) )
		return( -1 );

	if( im_iscomplex( in ) ) {
		/* Easy case! Assume it has already been transformed.
		 */
		IMAGE *t1 = im_open_local( dummy, "im_freqflt-1", "p" );

		if( !t1 ||
			im_multiply( in, mask, t1 ) ||
			im_invfftr( t1, out ) ) {
			im_close( dummy );
			return( -1 );
		}
	}
	else {
		/* Harder - fft first, then mult, then force back to start
		 * type.
		 * 
		 * Optimisation: output of im_invfft() is float buffer, we 
		 * will usually chagetype to char, so rather than keeping a
		 * large float buffer and partial to char from that, do
		 * changetype to a memory buffer, and copy to out from that.
		 */
		IMAGE *t[3];
		IMAGE *t3;

		if( im_open_local_array( dummy, t, 3, "im_freqflt-1", "p" ) ||
			!(t3 = im_open_local( out, "im_freqflt-3", "t" )) ||
			im_fwfft( in, t[0] ) ||
			im_multiply( t[0], mask, t[1] ) ||
			im_invfftr( t[1], t[2] ) ||
			im_clip2fmt( t[2], t3, in->BandFmt ) ||
			im_copy( t3, out ) ) {
			im_close( dummy );
			return( -1 );
		}	
	}

	im_close( dummy );

	return( 0 );
}
Пример #13
0
/**
 * im_disp_ps:
 * @in: input image
 * @out: output image
 *
 * Make a displayable (ie. 8-bit unsigned int) power spectrum. 
 *
 * If @in is non-complex, it is transformed to Fourier space. Then the
 * absolute value is passed through im_scaleps(), and im_rotquad().
 *
 * See also: im_scaleps(), im_rotquad().
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_disp_ps( IMAGE *in, IMAGE *out )
{
	IMAGE *dummy;

	if( !(dummy = im_open( "memory:1", "p" )) )
		return( -1 );
	if( disp_ps( dummy, in, out ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	return( 0 );
}
Пример #14
0
/* Get the value of pixel (0, 0). Use this to init the min/max value for
 * im_max()/im_stats()/etc.
 */
int
im__value( IMAGE *im, double *value )
{
	IMAGE *t;

	if( !(t = im_open( "im__value", "p" )) )
		return( -1 );
	if( im_extract_areabands( im, t, 0, 0, 1, 1, 0, 1 ) ||
		im_avg( t, value ) ) {
		im_close( t );
		return( -1 );
	}
	im_close( t );

	return( 0 );
}
Пример #15
0
/**
 * im_mpercent:
 * @in: input image
 * @percent: threshold percentage
 * @out: output threshold value
 *
 * im_mpercent() returns (through the @out parameter) the threshold above 
 * which there are @percent values of @in. If for example percent=.1, the
 * number of pels of the input image with values greater than the returned 
 * int will correspond to 10% of all pels of the image.
 *
 * The function works for uchar and ushort images only.  It can be used 
 * to threshold the scaled result of a filtering operation.
 *
 * See also: im_histgr(), im_profile().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_mpercent( IMAGE *in, double percent, int *out )
{
	IMAGE *t;

	if( !(t = im_open( "im_mpercent1", "p" )) )
		return( -1 );
	if( im_histgr( in, t, -1 ) ||
		im_mpercent_hist( t, percent, out ) ) {
		im_close( t );
		return( -1 );
	}
	im_close( t );

	return( 0 );
}
Пример #16
0
/**
 * 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;
	}
Пример #17
0
int 
im_tbmosaic( IMAGE *ref, IMAGE *sec, IMAGE *out, 
	int bandno, 
	int xref, int yref, int xsec, int ysec, 
	int halfcorrelation, int halfarea,
	int balancetype,
	int mwidth )
{
	int dx0, dy0;
	double scale1, angle1, dx1, dy1;
	IMAGE *ref2, *sec2;
	IMAGE *dummy;

	/* Correct overlap. dummy is just a placeholder used to ensure that
	 * memory used by the analysis phase is freed as soon as possible.
	 */
	if( !(dummy = im_open( "placeholder:1", "p" )) )
		return( -1 );
	if( im__find_tboverlap( ref, sec, dummy,
		bandno, 
		xref, yref, xsec, ysec,
		halfcorrelation, halfarea,
		&dx0, &dy0,
		&scale1, &angle1, &dx1, &dy1 ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	/* Balance.
	 */
	if( im__balance( ref, sec, out,
		&ref2, &sec2,
		dx0, dy0, balancetype ) )
		return( -1 );

	/* Merge top-bottom.
	 */
        if( im_tbmerge( ref2, sec2, out, dx0, dy0, mwidth ) )
		return( -1 ); 

	return( 0 );
}
Пример #18
0
int 
im_fwfft( IMAGE *in, IMAGE *out )
{
	IMAGE *dummy = im_open( "im_fwfft:1", "p" );

	if( !dummy )
		return( -1 );
	if( im__fftproc( dummy, in, out, fwfft1 ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	/* Set type hint.
	 */
	out->Type = IM_TYPE_FOURIER;

	return( 0 );
}
Пример #19
0
/* JPEGs get special treatment. libjpeg supports fast shrink-on-read,
 * so if we have a JPEG, we can ask VIPS to load a lower resolution
 * version.
 */
static int
thumbnail( const char *filename )
{
	VipsFormatClass *format;
	int shrink;

	if( verbose )
		printf( "thumbnailing %s\n", filename );

	if( !(format = vips_format_for_file( filename )) )
		return( -1 );

	if( verbose )
		printf( "detected format as %s\n", 
			VIPS_OBJECT_CLASS( format )->nickname );

	shrink = 1;
	if( strcmp( VIPS_OBJECT_CLASS( format )->nickname, "jpeg" ) == 0 ) {
		IMAGE *im;

		/* This will just read in the header and is quick.
		 */
		if( !(im = im_open( filename, "r" )) )
			return( -1 );
		shrink = calculate_shrink( im->Xsize, im->Ysize, NULL );
		im_close( im );

		if( shrink > 8 )
			shrink = 8;
		else if( shrink > 4 )
			shrink = 4;
		else if( shrink > 2 )
			shrink = 2;
		else 
			shrink = 1;

		if( verbose )
			printf( "using fast jpeg shrink, factor %d\n", shrink );
	}

	return( thumbnail2( filename, shrink ) );
}
Пример #20
0
int
main( int argc, char *argv[] )
{
	GOptionContext *context;
	GError *error = NULL;
	int i;

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

        context = g_option_context_new( _( "- print image header" ) );

	g_option_context_add_main_entries( context,
		main_option, GETTEXT_PACKAGE );
	g_option_context_add_group( context, im_get_option_group() );

	if( !g_option_context_parse( context, &argc, &argv, &error ) ) {
		if( error ) {
			fprintf( stderr, "%s\n", error->message );
			g_error_free( error );
		}

		error_exit( "try \"%s --help\"", g_get_prgname() );
	}

	g_option_context_free( context );

	for( i = 1; i < argc; i++ ) {
		IMAGE *im;

		if( !(im = im_open( argv[i], "r" )) )
			print_error( "%s: unable to open", argv[i] );

		if( im && print_header( im ) )
			print_error( "%s: unable to print header", argv[i] );

		if( im )
			im_close( im );
	}

	return( 0 );
}
Пример #21
0
/**
 * im_invfftr:
 * @in: input image
 * @out: output image
 *
 * Transform an image from Fourier space to real space, giving a real result.
 * This is faster than im_invfft(), which gives a complex result. 
 *
 * VIPS uses the fftw3 or fftw2 Fourier transform libraries if possible. If 
 * they were not available when VIPS was built, it falls back to it's own 
 * FFT functions which are slow and only work for square images whose sides
 * are a power of two.
 *
 * See also: im_invfft(), im_fwfft(), im_disp_ps().
 *
 * Returns: 0 on success, -1 on error.
 */
int 
im_invfftr( IMAGE *in, IMAGE *out )
{
	IMAGE *dummy = im_open( "im_invfft:1", "p" );

	if( !dummy )
		return( -1 );
	if( im__fftproc( dummy, in, out, invfft1 ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	if( out->Bands == 1 )
		out->Type = IM_TYPE_B_W;
	else
		out->Type = IM_TYPE_MULTIBAND;

	return( 0 );
}
Пример #22
0
static int
thumbnail2( const char *filename, int shrink )
{
	IMAGE *in;
	IMAGE *out;
	char *tn_filename;
	int result;

	/* Open in sequential mode.
	 */
	if( shrink > 1 ) {
		if( vips_foreign_load( filename, &in,
			"sequential", TRUE,
			"shrink", shrink,
			NULL ) )
			return( -1 );
	}
	else {
		if( vips_foreign_load( filename, &in,
			"sequential", TRUE,
			NULL ) )
			return( -1 );
	}

	tn_filename = make_thumbnail_name( filename );
	if( !(out = im_open( tn_filename, "w" )) ) {
		im_close( in );
		g_free( tn_filename );
		return( -1 );
	}

	result = thumbnail3( in, out );

	g_free( tn_filename );
	im_close( out );
	im_close( in );

	return( result );
}
Пример #23
0
int
main( int argc, char *argv[] )
{
	IMAGE *matrix;
	double fasm, fent, fmean, fcon;

	if( im_init_world( argv[0] ) )
	        error_exit( "unable to start VIPS" );
	textdomain( GETTEXT_PACKAGE );
	setlocale( LC_ALL, "" );

	if( argc != 2 )
		error_exit( "usage: %s matrix_image", argv[0] );


	if( !(matrix = im_open(argv[1],"r")) )
		error_exit( "unable to open %s for input",
			argv[1] );

	if( im_glds_asm( matrix, &fasm ) )
		error_exit( "unable to im_glds_asm");

	if( im_glds_contrast( matrix, &fcon ) )
		error_exit( "unable to im_glds_contrast");

	if( im_glds_entropy( matrix, &fent ) )
		error_exit( "unable to im_glds_entropy");

	if( im_glds_mean( matrix, &fmean ) )
		error_exit( "unable to im_glds_mean");

	if( im_close( matrix ) )
		error_exit( "unable to close %s", argv[1]);

	printf( "glds: ASM=%f, ENT=%f, MEAN=%f, CON=%f\n",
		fasm, fent, fmean, fcon);

	return(0);
}
Пример #24
0
/**
 * im_draw_smudge:
 * @image: image to smudge
 * @left: area to smudge
 * @top: area to smudge
 * @width: area to smudge
 * @height: area to smudge
 *
 * Smudge a section of @image. Each pixel in the area @left, @top, @width,
 * @height is replaced by the average of the surrounding 3x3 pixels. 
 *
 * This an inplace operation, so @image 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_draw_line().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_draw_smudge( VipsImage *im, int left, int top, int width, int height )
{
	Rect area, image, clipped;
	IMAGE *t[2];

	area.left = left;
	area.top = top;
	area.width = width;
	area.height = height;
	image.left = 0;
	image.top = 0;
	image.width = im->Xsize;
	image.height = im->Ysize;
	im_rect_intersectrect( &area, &image, &clipped );
	if( im_rect_isempty( &clipped ) )
		return( 0 );

	if( !blur ) {
		blur = im_create_imaskv( "im_draw_smudge", 3, 1, 1, 4, 1 );
		blur->scale = 6;
	}

	if( !(t[0] = im_open( "im_draw_smudge", "p" )) )
		return( -1 );
	if( !(t[1] = im_open_local( t[0], "im_draw_smudge", "p" )) ||
		im_convsep( im, t[0], blur ) ||
		im_extract_area( t[0], t[1], 
			clipped.left, clipped.top, 
			clipped.width, clipped.height ) ||
		im_draw_image( im, t[1], clipped.left, clipped.top ) ) {
		im_close( t[0] );
		return( -1 );
	}
	im_close( t[0] );

	return( 0 );
}
Пример #25
0
static VALUE
jpeg_buf_internal(VALUE obj, VALUE quality)
{
    VipsImage *im_out;
    char *buf = NULL;
    int length;
    VALUE str;

    GetImg(obj, data, im);

    if (!(im_out = im_open("writer_jpeg_buf", "p")))
        vips_lib_error();

    if (im_vips2bufjpeg(im, im_out, NUM2INT(quality), &buf, &length)) {
		im_close(im_out);
        vips_lib_error();
	}

    str = rb_tainted_str_new(buf, length);
    im_close(im_out);

    return str;
}
Пример #26
0
/* 1st order mosaic using im__find_lroverlap() ... does not work too well :(
 * Look at im__find_lroverlap() for problem?
 */
static int
old_lrmosaic1( IMAGE *ref, IMAGE *sec, IMAGE *out,
	int bandno,
	int xr1, int yr1, int xs1, int ys1, 
	int xr2, int yr2, int xs2, int ys2,
	int halfcorrelation, int halfarea,
	int balancetype,
	int mwidth )
{ 
	Transformation trn1, trn2;
	int dx0, dy0;
	double a, b, dx, dy;
	double a1, b1, dx1, dy1;
	double af, bf, dxf, dyf;
	int xpos, ypos;
	int xpos1, ypos1;

	/* Temps.
	 */
	IMAGE *t1 = im_open_local( out, "im_lrmosaic1:1", "p" );
	IMAGE *t2 = im_open_local( out, "im_lrmosaic1:2", "p" );
	IMAGE *dummy;

	if( !t1 || !t2 )
		return( -1 );

	/* Solve to get scale + rot + disp.
	 */
	if( im__coeff( xr1, yr1, xs1, ys1, xr2, yr2, xs2, ys2, 
		&a, &b, &dx, &dy ) ||
		apply_similarity( &trn1, sec, t1, a, b, dx, dy ) )
		return( -1 );

	/* Correct tie-points. dummy is just a placeholder used to ensure that
	 * memory used by the analysis phase is freed as soon as possible.
	 */
	if( !(dummy = im_open( "placeholder:1", "p" )) )
		return( -1 );
	if( im__find_lroverlap( ref, t1, dummy,
		bandno, 
		-trn1.area.left, -trn1.area.top, 0, 0,
		halfcorrelation, halfarea,
		&dx0, &dy0,
		&a1, &b1, &dx1, &dy1 ) ) {
		im_close( dummy );
		return( -1 );
	}
	im_close( dummy );

	/* Now combine the two transformations to get a corrected transform.
	 */
	af = a1 * a - b1 * b;
	bf = a1 * b + b1 * a;
	dxf = a1 * dx - b1 * dy + dx1;
	dyf = b1 * dx + a1 * dy + dy1;

	printf( "transform was: a = %g, b = %g, dx = %g, dy = %g\n",
		a, b, dx, dy );
	printf( "correction: a = %g, b = %g, dx = %g, dy = %g\n",
		a1, b1, dx1, dy1 );
	printf( "final: a = %g, b = %g, dx = %g, dy = %g\n",
		af, bf, dxf, dyf );

	/* Scale and rotate final.
	 */
	if( apply_similarity( &trn2, sec, t2, af, bf, dxf, dyf ) )
		return( -1 );

	printf( "disp: trn1 left = %d, top = %d\n", 
		trn1.area.left, trn1.area.top );
	printf( "disp: trn2 left = %d, top = %d\n", 
		trn2.area.left, trn2.area.top );

	/* And join to ref.
	 */
	if( im_lrmerge( ref, t2, out, 
		-trn2.area.left, -trn2.area.top, mwidth ) )
		return( -1 );

	return( 0 );
}
Пример #27
0
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 */
Пример #28
0
/* Start here!
 */
int
main( int argc, char **argv )
{	
	IMAGE *im = NULL;
	FILE *out = stdout;
	int width = -1;
	int height = -1;
	int dpi = -1;
	int max = 0;
	int rotate = 0;
	int one2one = 0;
	PrinterGeometry *geo = find_printer( "2500cp" );
	char *mode;
	int i;

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

	argv0 = argv[0];

	if( argc <= 1 ) {
		printf( 
"usage:\n"
"\t%s [options] <image file>\n"
"convert RGB, LAB, CMYK and mono image files to postscript\n"
"\tRGB converted to LAB, assuming sRGB\n"
"\tLAB printed with printer colour management\n"
"\tCMYK sent directly as dot percent\n"
"\tmono prints as K only\n"
"options include:\n"
"\t-printer <name>\tformat for printer <name>\n"
"\t-3500cp\t\tfor HP 3500CP printer (default 2500cp)\n"
"\t-max\t\tprint as large as possible\n"
"\t-rotate\t\trotate, if necessary, to fill the page\n"
"\t-1:1\t\tsize the image to print at 1:1 ... resolution in\n"
"\t\t\timage header must be set for this\n"
"\t-width <n>\tforce specified width, in points\n"
"\t-height <n>\tforce specified height, in points\n"
"\t-dpi <n>\tforce specified resolution (default 150dpi)\n"
"\t-a5, -a4, -a3, -a2, -a1, -a0\n"
"\t\t\tforce specified height (width ignored)\n"
"\t-o <file>\toutput to file (default stdout)\n",
			argv0 );
		printf( "supported printers:\n" );
		print_printers();
		return( 1 );
	}

	/* Decode args .. just look for file names and our three options.
	 */
	for( i = 1; i < argc; i++ )
		if( *argv[i] == '-' ) {
			if( strcmp( argv[i]+1, "width" ) == 0 ) {
				if( !argv[i+1] || sscanf( argv[i+1], 
					"%d", &width ) != 1 || width <= 10 )
					error_exit( "bad width" );
				i++;
			}
			else if( strcmp( argv[i]+1, "height" ) == 0 ) {
				if( !argv[i+1] || sscanf( argv[i+1], 
					"%d", &height ) != 1 || height <= 10 )
					error_exit( "bad height" );
				i++;
			}
			else if( strcmp( argv[i]+1, "3500cp" ) == 0 ) {
				geo = find_printer( "3500cp" );
			}
			else if( strcmp( argv[i]+1, "printer" ) == 0 ) {
				if( !argv[i+1] || 
					!(geo = find_printer( argv[i+1] )) )
					error_exit( "bad printer model" );
				i++;
			}
			else if( strcmp( argv[i]+1, "dpi" ) == 0 ) {
				if( !argv[i+1] || sscanf( argv[i+1], 
					"%d", &dpi ) != 1 || dpi <= 1 ||
					dpi >= 600 )
					error_exit( "bad dpi" );
				i++;
			}
			else if( strcmp( argv[i]+1, "o" ) == 0 ) {
				if( !argv[i+1] || !(out = fopen( 
					argv[i+1], "w" )) )
					error_exit( "bad output name" );
				i++;
			}
			else if( strcmp( argv[i]+1, "1:1" ) == 0 ) 
				one2one = 1;	
			else if( strcmp( argv[i]+1, "a5" ) == 0 ) 
				height = 595;
			else if( strcmp( argv[i]+1, "a4" ) == 0 ) 
				height = 839;
			else if( strcmp( argv[i]+1, "a3" ) == 0 ) 
				height = 1187;
			else if( strcmp( argv[i]+1, "a2" ) == 0 ) 
				height = 1678;
			else if( strcmp( argv[i]+1, "a1" ) == 0 ) 
				height = 2373;
			else if( strcmp( argv[i]+1, "a0" ) == 0 ) 
				height = 3356;
			else if( strcmp( argv[i]+1, "max" ) == 0 ) 
				max = 1;
			else if( strcmp( argv[i]+1, "rotate" ) == 0 ) 
				rotate = 1;
			else
				error_exit( "bad flag" );
		}
		else {
			/* Try to open the file. 
			 */
			if( im != NULL || !(im = im_open( argv[i], "r" )) )
				error_exit( "bad input image" );
		}

	if( im == NULL ) 
		error_exit( "no input image" );

	/* Turn 3-band uchar images into LABQ. Yuk! But convenient.
	 */
	if( im->Coding == IM_CODING_NONE &&
		im->Bands == 3 && im->BandFmt == IM_BANDFMT_UCHAR ) {
		IMAGE *t[3];

		if( im_open_local_array( im, t, 3, "vips2dj", "p" ) ||
			im_sRGB2XYZ( im, t[0] ) ||
			im_XYZ2Lab( t[0], t[1] ) ||
			im_Lab2LabQ( t[1], t[2] ) )
			error_exit( "error converting to LAB" );

		im = t[2];
	}

	/* Stop used-before-set complaints on mode.
	 */
	mode = "lab";

	/* Pick a PS mode.
	 */
	if( im->Coding == IM_CODING_LABQ )
		mode = "lab";
	else if( im->Coding == IM_CODING_NONE && 
		im->Bands == 4 && im->BandFmt == IM_BANDFMT_UCHAR )
		mode = "cmyk";
	else if( im->Coding == IM_CODING_NONE && 
		im->Bands == 1 && im->BandFmt == IM_BANDFMT_UCHAR )
		mode = "mono";
	else 
		error_exit( "unsupported image type "
			"(IM_CODING_LABQ, mono, IM_TYPE_CMYK only)" );

	/* Autorotate image to fill the page. We ought to get PS to do the
	 * rotate, really.
	 */
	if( rotate ) {
		float iaspect = (float) im->Xsize / im->Ysize;
		float paspect = (float) geo->width / geo->length;

		if( iaspect > paspect ) {
			IMAGE *t[1];

			if( im_open_local_array( im, t, 1, "vips2dj", "p" ) ||
				im_rot90( im, t[0] ) )
				error_exit( "error rotating" );

			im = t[0];
		}
	}

	/* Make sure width and height are both set.
	 */
	if( one2one ) {
		/* Set width/height from res.
		 */
		if( im->Xres <= 0 || im->Xres >= 100 ||
			im->Yres <= 0 || im->Yres >= 100 )
			error_exit( "uanble to print 1:1 - resolution not "
				"set in image" );

		height = (((im->Ysize / im->Yres) / 10.0) / 2.54) * 72.0;
		width = (((im->Xsize / im->Xres) / 10.0) / 2.54) * 72.0;
	}
	else if( max ) {
		float iaspect = (float) im->Xsize / im->Ysize;
		float paspect = (float) geo->width / geo->length;

		if( iaspect > paspect ) 
			/* Image aspect ratio > paper ... fit width.
			 */
			width = geo->width;
		else
			height = geo->length;
	}
	else if( dpi > 0 ) {
		/* Given res ... set width/height.
		 */
		height = (im->Ysize / (float) dpi) * 72.0;
		width = (im->Xsize / (float) dpi) * 72.0;
	}

	if( width >= 0 || height >= 0 ) {
		/* Given width or height or both --- set other one.
		 */
		if( height < 0 ) {
			float fdpi = im->Xsize / (width / 72.0);
			height = (im->Ysize / fdpi) * 72.0;
		}
		else {
			float fdpi = im->Ysize / (height / 72.0);
			width = (im->Xsize / fdpi) * 72.0;
		}
	}
	else {
		/* Nothing set ... default to 150 dpi.
		 */
		height = (im->Ysize / 150.0) * 72.0;
		width = (im->Xsize / 150.0) * 72.0;
	}

	if( send_file( geo, im, mode, out, width, height ) )
		error_exit( "error sending file" );

	return( 0 );
}
Пример #29
0
/**
 * im_vips2mask:
 * @in: input image
 * @filename: name for output mask 
 *
 * Make a mask from an image. All images are cast to %IM_BANDFMT_DOUBLE
 * before processing. There are two cases for handling bands:
 *
 * If the image has a single band, im_vips2mask() will write a mask the same
 * size as the image.
 *
 * If the image has more than one band, it must be one pixel high or wide. In
 * this case the output mask uses that axis to represent band values.
 *
 * See also: im_mask2vips(), im_measure_area().
 *
 * Returns: a #DOUBLEMASK with @outname set as the name, or NULL on error
 */
DOUBLEMASK *
im_vips2mask( IMAGE *in, const char *filename )
{
	int width, height;
	DOUBLEMASK *out;

	/* double* only: cast if necessary.
	 */
	if( in->BandFmt != IM_BANDFMT_DOUBLE ) {
		IMAGE *t;

		if( !(t = im_open( "im_vips2mask", "p" )) )
			return( NULL );
		if( im_clip2fmt( in, t, IM_BANDFMT_DOUBLE ) ||
			!(out = im_vips2mask( t, filename )) ) {
			im_close( t );
			return( NULL );
		}
		im_close( t );

		return( out );
	}

	/* Check the image.
	 */
	if( im_incheck( in ) ||
		im_check_uncoded( "im_vips2mask", in ) )
		return( NULL );

	if( in->Bands == 1 ) {
		width = in->Xsize;
		height = in->Ysize;
	}
	else if( in->Xsize == 1 ) {
		width = in->Bands;
		height = in->Ysize;
	}
	else if( in->Ysize == 1 ) {
		width = in->Xsize;
		height = in->Bands;
	}
	else {
		im_error( "im_vips2mask", 
			"%s", _( "one band, nx1, or 1xn images only" ) );
		return( NULL );
	}

	if( !(out = im_create_dmask( filename, width, height )) )
		return( NULL );
	if( in->Bands > 1 && in->Ysize == 1 ) {
		double *data = (double *) in->data;
		int x, y;

		/* Need to transpose: the image is RGBRGBRGB, we need RRRGGGBBB.
		 */
		for( y = 0; y < height; y++ )
			for( x = 0; x < width; x++ )
				out->coeff[x + y * width] =
					data[x * height + y];
	}
	else
		memcpy( out->coeff, in->data, 
			width * height * sizeof( double ) );

	out->scale = vips_image_get_scale( in );
	out->offset = vips_image_get_offset( in );

	return( out );
}
Пример #30
0
INTMASK *
im_vips2imask( IMAGE *in, const char *filename )
{
	int width, height;
	INTMASK *out;

	double *data;
	int x, y;
	double double_result;
	int int_result;

	/* double* only: cast if necessary.
	 */
	if( in->BandFmt != IM_BANDFMT_DOUBLE ) {
		IMAGE *t;

		if( !(t = im_open( "im_vips2imask", "p" )) )
			return( NULL );
		if( im_clip2fmt( in, t, IM_BANDFMT_DOUBLE ) ||
			!(out = im_vips2imask( t, filename )) ) {
			im_close( t );
			return( NULL );
		}
		im_close( t );

		return( out );
	}

	/* Check the image.
	 */
	if( im_incheck( in ) ||
		im_check_uncoded( "im_vips2imask", in ) )
		return( NULL );

	if( in->Bands == 1 ) {
		width = in->Xsize;
		height = in->Ysize;
	}
	else if( in->Xsize == 1 ) {
		width = in->Bands;
		height = in->Ysize;
	}
	else if( in->Ysize == 1 ) {
		width = in->Xsize;
		height = in->Bands;
	}
	else {
		im_error( "im_vips2imask", 
			"%s", _( "one band, nx1, or 1xn images only" ) );
		return( NULL );
	}

	data = (double *) in->data;
	if( !(out = im_create_imask( filename, width, height )) )
		return( NULL );

	/* We want to make an intmask which has the same input to output ratio
	 * as the double image.
	 *
	 * Imagine convolving with the double image, what's the ratio of
	 * brightness between input and output? We want the same ratio for the
	 * int version, if we can.
	 *
	 * Imaging an input image where every pixel is 1, what will the output
	 * be?
	 */
	double_result = 0;
	for( y = 0; y < height; y++ )
		for( x = 0; x < width; x++ )
			double_result += data[x + width * y];
	double_result /= vips_image_get_scale( in );

	for( y = 0; y < height; y++ )
		for( x = 0; x < width; x++ )
			if( in->Bands > 1 && in->Ysize == 1 ) 
				/* Need to transpose: the image is RGBRGBRGB, 
				 * we need RRRGGGBBB.
				 */
				out->coeff[x + y * width] =
					VIPS_RINT( data[x * height + y] );
			else
				out->coeff[x + y * width] =
					VIPS_RINT( data[x + y * width] );

	out->scale = VIPS_RINT( vips_image_get_scale( in ) );
	if( out->scale == 0 )
		out->scale = 1;
	out->offset = VIPS_RINT( vips_image_get_offset( in ) );

	/* Now convolve a 1 everywhere image with the int version we've made,
	 * what do we get?
	 */
	int_result = 0;
	for( y = 0; y < height; y++ )
		for( x = 0; x < width; x++ )
			int_result += out->coeff[x + width * y];
	int_result /= out->scale;

	/* And adjust the scale to get as close to a match as we can. 
	 */
	out->scale = VIPS_RINT( out->scale + (int_result - double_result) );
	if( out->scale == 0 ) 
		out->scale = 1;

	return( out );
}