Example #1
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 );
}
Example #2
0
/**
 * 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 );
}
Example #3
0
int 
im_subtract( IMAGE *in1, IMAGE *in2, IMAGE *out )
{	
	/* Basic checks.
	 */
	if( im_piocheck( in1, out ) || im_pincheck( in2 ) )
		return( -1 );
	if( in1->Bands != in2->Bands &&
		(in1->Bands != 1 && in2->Bands != 1) ) {
		im_error( "im_subtract", _( "not same number of bands" ) );
		return( -1 );
	}
	if( in1->Coding != IM_CODING_NONE || in2->Coding != IM_CODING_NONE ) {
		im_error( "im_subtract", _( "not uncoded" ) );
		return( -1 );
	}
	if( im_cp_descv( out, in1, in2, NULL ) )
		return( -1 );

	/* What number of bands will we write?
	 */
	out->Bands = IM_MAX( in1->Bands, in2->Bands );

	/* What output type will we write? int, float or complex.
	 */
	if( im_iscomplex( in1 ) || im_iscomplex( in2 ) ) {
		/* What kind of complex?
		 */
		if( in1->BandFmt == IM_BANDFMT_DPCOMPLEX || 
			in2->BandFmt == IM_BANDFMT_DPCOMPLEX )
			/* Output will be DPCOMPLEX. 
			 */
			out->BandFmt = IM_BANDFMT_DPCOMPLEX;
		else
			out->BandFmt = IM_BANDFMT_COMPLEX;
	}
	else if( im_isfloat( in1 ) || im_isfloat( in2 ) ) {
		/* What kind of float?
		 */
		if( in1->BandFmt == IM_BANDFMT_DOUBLE || 
			in2->BandFmt == IM_BANDFMT_DOUBLE )
			out->BandFmt = IM_BANDFMT_DOUBLE;
		else
			out->BandFmt = IM_BANDFMT_FLOAT;
	}
	else 
		/* Must be int+int -> int.
		 */
		out->BandFmt = iformat[in1->BandFmt][in2->BandFmt];

	/* And process!
	 */
	if( im__cast_and_call( in1, in2, out, 
		(im_wrapmany_fn) subtract_buffer, NULL ) )
		return( -1 );

	/* Success!
	 */
	return( 0 );
}
Example #4
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 );
  }
}
Example #5
0
/**
 * im_vips2raw:
 * @in: image to save 
 * @fd: file descriptor to write to
 *
 * Writes the pixels in @in to the file descriptor. It's handy for writing
 * writers for other formats.
 *
 * See also: #VipsFormat, im_raw2vips().
 *
 * Returns: 0 on success, -1 on error.
 */
int
im_vips2raw( IMAGE *in, int fd )
{
  Write *write;
      
  if( im_pincheck( in ) || !(write = write_new( in, fd )) )
    return( -1 );

  if( vips_sink_disc( in, write_block, write ) ) {
    write_destroy( write );
    return( -1 );
  }  

  write_destroy( write );
  return( 0 );
}
Example #6
0
/* Transform an n-band image with a 1-band processing function.
 */
int 
im__fftproc( IMAGE *dummy, IMAGE *in, IMAGE *out, im__fftproc_fn fn )
{
	if( im_pincheck( in ) || im_outcheck( out ) )
                return( -1 );
	
	if( in->Bands == 1 ) {
		if( fn( dummy, in, out ) )
			return( -1 );
	}
	else {
		IMAGE *acc;
		int b;

		for( acc = NULL, b = 0; b < in->Bands; b++ ) {
			IMAGE *t1 = im_open_local( dummy, 
				"fwfftn:1", "p" );
			IMAGE *t2 = im_open_local( dummy, 
				"fwfftn:2", "p" );

			if( !t1 || !t2 || 
				im_extract_band( in, t1, b ) ||
				fn( dummy, t1, t2 ) )
				return( -1 );
			
			if( !acc )
				acc = t2;
			else {
				IMAGE *t3 = im_open_local( dummy, 
					"fwfftn:3", "p" );

				if( !t3 || im_bandjoin( acc, t2, t3 ) )
					return( -1 );

				acc = t3;
			}
		}

		if( im_copy( acc, out ) )
			return( -1 );
	}

	return( 0 );
}
Example #7
0
/** 
 * im_maxpos_avg:
 * @im: image to scan
 * @xpos: returned X position
 * @ypos: returned Y position
 * @out: returned value
 *
 * Function to find the maximum of an image.  Returns coords and value at
 * double precision.  In the event of a draw, returns average of all 
 * drawing coords.
 *
 * See also: im_maxpos(), im_min(), im_stats().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_maxpos_avg( IMAGE *in, double *xpos, double *ypos, double *out )
{
	Maxposavg *global_maxposavg;

	if( im_pincheck( in ) ||
		im_check_uncoded( "im_maxpos_avg", in ) )
		return( -1 );

	if( !(global_maxposavg = IM_NEW( in, Maxposavg )) ) 
		return( -1 );
	if( im__value( in, &global_maxposavg->max ) )
		return( -1 );
	global_maxposavg->xpos = 0;
	global_maxposavg->ypos = 0;
	global_maxposavg->occurences = 1;

	/* We use square mod for scanning, for speed.
	 */
	if( vips_band_format_iscomplex( in->BandFmt ) )
		global_maxposavg->max *= global_maxposavg->max;

	if( vips_sink( in, maxposavg_start, maxposavg_scan, maxposavg_stop, 
		in, global_maxposavg ) ) 
		return( -1 );

	/* Back to modulus.
	 */
	if( vips_band_format_iscomplex( in->BandFmt ) )
		global_maxposavg->max = sqrt( global_maxposavg->max );

	if( xpos )
		*xpos = (double) global_maxposavg->xpos / 
			global_maxposavg->occurences;
	if( ypos )
		*ypos = (double) global_maxposavg->ypos / 
			global_maxposavg->occurences;
	if( out )
		*out = global_maxposavg->max;

	return( 0 );
}
Example #8
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
}
Example #9
0
/* Find the average of an image.
 */
int
im_deviate( IMAGE *in, double *out )
{	
	double sum[2] = { 0.0, 0.0 };
	gint64 N;

	/* Check our args. 
	 */
	if( im_pincheck( in ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE ) {
		im_error( "im_deviate", _( "not uncoded" ) );
		return( -1 );
	}
	if( im_iscomplex( in ) ) {
		im_error( "im_deviate", _( "bad input type" ) );
		return( -1 );
	}

	/* Loop over input, summing pixels.
	 */
	if( im_iterate( in, start_fn, scan_fn, stop_fn, &sum, NULL ) )
		return( -1 );

	/*
	  
	   	NOTE: NR suggests a two-pass algorithm to minimise roundoff. 
		But that's too expensive for us :-( so do it the old one-pass 
		way.

	 */

	/* Calculate and return deviation. Add a fabs to stop sqrt(<=0).
	 */
	N = (gint64) in->Xsize * in->Ysize * in->Bands;
	*out = sqrt( fabs( sum[1] - (sum[0] * sum[0] / N) ) / (N - 1) );

	return( 0 );
}
Example #10
0
/* The common part of most binary inplace operators.
 *
 * Unlike im__formatalike() and friends, we can only change one of the images,
 * since the other is being updated.
 */
VipsImage *
im__inplace_base( const char *domain,
                  VipsImage *main, VipsImage *sub, VipsImage *out )
{
    VipsImage *t[2];

    if( im_rwcheck( main ) ||
            im_pincheck( sub ) ||
            im_check_coding_known( domain, main ) ||
            im_check_coding_same( domain, main, sub ) ||
            im_check_bands_1orn_unary( domain, sub, main->Bands ) )
        return( NULL );

    /* Cast sub to match main in bands and format.
     */
    if( im_open_local_array( out, t, 2, domain, "p" ) ||
            im__bandup( domain, sub, t[0], main->Bands ) ||
            im_clip2fmt( t[0], t[1], main->BandFmt ) )
        return( NULL );

    return( t[1] );
}
Example #11
0
int
im_min( IMAGE *in, double *out )
{	
	MinInfo inf;

	inf.in = in;
	inf.out = out;
	inf.valid = 0;

	if( im_pincheck( in ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE ) {
		im_error( "im_min", _( "not uncoded" ) );
		return( -1 );
	}

	if( im_iterate( in, start_fn, scan_fn, stop_fn, &inf, NULL ) ) 
		return( -1 );

	*out = inf.value;

	return( 0 );
}
Example #12
0
int 
im_histnD( IMAGE *in, IMAGE *out, int bins )
{
	int max_val;
	Histogram *mhist;
	int x, y, z, i;
	unsigned int *obuffer;

	/* Check images. PIO from in, WIO to out.
	 */
	if( im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE ) {
		im_error( "im_histnD", _( " uncoded images only" ) );
		return( -1 );
	}
	if( in->BandFmt != IM_BANDFMT_UCHAR && 
		in->BandFmt != IM_BANDFMT_USHORT ) {
		im_error( "im_histnD", 
			_( " unsigned 8 or 16 bit images only" ) );
		return( -1 );
	}

	max_val = in->BandFmt == IM_BANDFMT_UCHAR ? 256 : 65536;
	if( bins < 1 || bins > max_val ) {
		im_error( "im_histnD", 
			_( " bins out of range [1,%d]" ), max_val );
		return( -1 );
	}

	/* Build main hist we accumulate to.
	 */
	if( !(mhist = build_hist( in, out, bins )) )
		return( -1 );

	/* Accumulate data.
	 */
	if( im_iterate( in, 
		build_subhist, find_hist, merge_subhist, mhist, NULL ) )
		return( -1 );

	/* Make the output image.
	 */
	if( im_cp_desc( out, in ) ) 
		return( -1 );
	im_initdesc( out,
		bins, in->Bands > 1 ? bins : 1, in->Bands > 2 ? bins : 1,
		IM_BBITS_INT, IM_BANDFMT_UINT, 
		IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
	if( im_setupout( out ) )
		return( -1 );

	/* Interleave to output buffer.
	 */
	if( !(obuffer = IM_ARRAY( out, 
		IM_IMAGE_N_ELEMENTS( out ), unsigned int )) )
		return( -1 );

	for( y = 0; y < out->Ysize; y++ ) {
		for( i = 0, x = 0; x < out->Xsize; x++ ) 
			for( z = 0; z < out->Bands; z++, i++ )
				obuffer[i] = mhist->data[z][y][x];

		if( im_writeline( y, out, (PEL *) obuffer ) )
			return( -1 );
	}

	return( 0 );
}
Example #13
0
/* Call rfftw for a 1 band real image.
 */
static int 
rfwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	const int size = in->Xsize * in->Ysize;
	const int half_width = in->Xsize / 2 + 1;

	/* Pack to double real here.
	 */
	IMAGE *real = im_open_local( dummy, "fwfft1:1", "t" );

	/* Transform to halfcomplex here.
	 */
	double *half_complex = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	rfftwnd_plan plan;
	double *buf, *q, *p;
	int x, y;

	if( !real || !half_complex || im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_fwfft", _( "one band uncoded only" ) );
                return( -1 );
	}
	if( im_clip2d( in, real ) )
                return( -1 );

	/* Make the plan for the transform. Yes, they really do use nx for
	 * height and ny for width.
	 */
	if( !(plan = rfftw2d_create_plan( in->Ysize, in->Xsize,
		FFTW_FORWARD, FFTW_MEASURE | FFTW_USE_WISDOM )) ) {
                im_error( "im_fwfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	rfftwnd_one_real_to_complex( plan, 
		(fftw_real *) real->data, (fftw_complex *) half_complex );

	rfftwnd_destroy_plan( plan );

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_DPCOMPLEX;
	out->BandFmt = IM_BANDFMT_DPCOMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (double *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Copy to out and normalise. The right half is the up/down and 
	 * left/right flip of the left, but conjugated. Do the first 
	 * row separately, then mirror around the centre row.
	 */
	p = half_complex;
	q = buf;

	for( x = 0; x < half_width; x++ ) {
		q[0] = p[0] / size;
		q[1] = p[1] / size;
		p += 2;
		q += 2;
	}

	p = half_complex + ((in->Xsize + 1) / 2 - 1) * 2; 

	for( x = half_width; x < out->Xsize; x++ ) {
		q[0] = p[0] / size;
		q[1] = -1.0 * p[1] / size;
		p -= 2;
		q += 2;
	}

	if( im_writeline( 0, out, (PEL *) buf ) )
		return( -1 );

	for( y = 1; y < out->Ysize; y++ ) {
		p = half_complex + y * half_width * 2; 
		q = buf;

		for( x = 0; x < half_width; x++ ) {
			q[0] = p[0] / size;
			q[1] = p[1] / size;
			p += 2;
			q += 2;
		}

		/* Good grief. 
		 */
		p = half_complex + 2 *
			((out->Ysize - y + 1) * half_width - 2 + 
				(in->Xsize & 1));

		for( x = half_width; x < out->Xsize; x++ ) {
			q[0] = p[0] / size;
			q[1] = -1.0 * p[1] / size;
			p -= 2;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
Example #14
0
/* Transform a 1 band image with vips's built-in fft routine.
 */
static int 
fwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	int size = in->Xsize * in->Ysize;
	int bpx = im_ispoweroftwo( in->Xsize );
	int bpy = im_ispoweroftwo( in->Ysize );
	float *buf, *q, *p1, *p2;
	int x, y;

	/* Buffers for real and imaginary parts.
	 */
	IMAGE *real = im_open_local( dummy, "fwfft1:1", "t" );
	IMAGE *imag = im_open_local( dummy, "fwfft1:2", "t" );

	/* Temporaries.
	 */
	IMAGE *t1 = im_open_local( dummy, "fwfft1:3", "p" );

	if( !real || !imag || !t1 )
		return( -1 );
        if( im_pincheck( in ) || im_outcheck( out ) )
                return( -1 );
        if( in->Coding != IM_CODING_NONE || in->Bands != 1 || 
		im_iscomplex( in ) ) {
                im_error( "im_fwfft", 
			_( "one band non-complex uncoded only" ) );
                return( -1 );
	}
	if( !bpx || !bpy ) {
		im_error( "im_fwfft", _( "sides must be power of 2" ) );
		return( -1 );
	}

	/* Make sure we have a float input image.
	 */
	if( im_clip2f( in, real ) )
		return( -1 );

	/* Make a buffer of 0 floats of the same size for the imaginary part.
	 */
	if( im_black( t1, in->Xsize, in->Ysize, 1 ) )
		return( -1 );
	if( im_clip2f( t1, imag ) )
		return( -1 );

	/* Transform!
	 */
	if( im__fft_sp( (float *) real->data, (float *) imag->data, 
		bpx - 1, bpy - 1 ) ) {
                im_error( "im_fwfft", _( "fft_sp failed" ) );
                return( -1 );
	}	

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_COMPLEX;
	out->BandFmt = IM_BANDFMT_COMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (float *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Gather together real and imag parts. We have to normalise output!
	 */
	for( p1 = (float *) real->data, p2 = (float *) imag->data,
		y = 0; y < out->Ysize; y++ ) {
		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[0] = *p1++ / size;
			q[1] = *p2++ / size;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
Example #15
0
/* Complex to complex forward transform.
 */
static int 
cfwfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	fftw_plan plan;
	double *buf, *q, *p;
	int x, y;

	IMAGE *cmplx = im_open_local( dummy, "fwfft1:1", "t" );

	/* We have to have a separate buffer for the planner to work on.
	 */
	double *planner_scratch = IM_ARRAY( dummy, 
		in->Xsize * in->Ysize * 2, double );

	/* Make dp complex image.
	 */
	if( !cmplx || im_pincheck( in ) || im_outcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_fwfft", _( "one band uncoded only" ) );
                return( -1 );
	}
	if( im_clip2dcm( in, cmplx ) )
                return( -1 );

	/* Make the plan for the transform.
	 */
	if( !(plan = fftw_plan_dft_2d( in->Ysize, in->Xsize,
		(fftw_complex *) planner_scratch, 
		(fftw_complex *) planner_scratch,
		FFTW_FORWARD, 
		0 )) ) {
                im_error( "im_fwfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	fftw_execute_dft( plan,
		(fftw_complex *) cmplx->data, (fftw_complex *) cmplx->data );

	fftw_destroy_plan( plan );

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->Bbits = IM_BBITS_DPCOMPLEX;
	out->BandFmt = IM_BANDFMT_DPCOMPLEX;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (double *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Copy to out, normalise.
	 */
	for( p = (double *) cmplx->data, y = 0; y < out->Ysize; y++ ) {
		int size = out->Xsize * out->Ysize;

		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[0] = p[0] / size;
			q[1] = p[1] / size;
			p += 2;
			q += 2;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
Example #16
0
/* Fall back to vips's built-in fft.
 */
static int 
invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	int bpx = im_ispoweroftwo( in->Xsize );
	int bpy = im_ispoweroftwo( in->Ysize );
	float *buf, *q, *p1;
	int x, y;

	/* Buffers for real and imaginary parts.
	 */
	IMAGE *real = im_open_local( dummy, "invfft1:1", "t" );
	IMAGE *imag = im_open_local( dummy, "invfft1:2", "t" );

	/* Temps.
	 */
	IMAGE *t1 = im_open_local( dummy, "invfft1:3", "p" );
	IMAGE *t2 = im_open_local( dummy, "invfft1:4", "p" );

	if( !real || !imag || !t1 )
		return( -1 );
        if( im_pincheck( in ) || im_outcheck( out ) )
                return( -1 );
        if( in->Coding != IM_CODING_NONE || 
		in->Bands != 1 || !im_iscomplex( in ) ) {
                im_error( "im_invfft", 
			"%s", _( "one band complex uncoded only" ) );
                return( -1 );
	}
	if( !bpx || !bpy ) {
		im_error( "im_invfft", 
			"%s", _( "sides must be power of 2" ) );
		return( -1 );
	}

	/* Make sure we have a single-precision complex input image.
	 */
	if( im_clip2fmt( in, t1, IM_BANDFMT_COMPLEX ) )
		return( -1 );

	/* Extract real and imag parts. We have to complement the imaginary.
	 */
	if( im_c2real( t1, real ) )
		return( -1 );
	if( im_c2imag( t1, t2 ) || im_lintra( -1.0, t2, 0.0, imag ) )
		return( -1 );

	/* Transform!
	 */
	if( im__fft_sp( (float *) real->data, (float *) imag->data, 
		bpx - 1, bpy - 1 ) ) {
                im_error( "im_invfft", 
			"%s", _( "fft_sp failed" ) );
                return( -1 );
	}

	/* WIO to out.
	 */
        if( im_cp_desc( out, in ) )
                return( -1 );
	out->BandFmt = IM_BANDFMT_FLOAT;
        if( im_setupout( out ) )
                return( -1 );
	if( !(buf = (float *) IM_ARRAY( dummy, 
		IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	/* Just write real part.
	 */
	for( p1 = (float *) real->data, y = 0; y < out->Ysize; y++ ) {
		q = buf;

		for( x = 0; x < out->Xsize; x++ ) {
			q[x] = *p1++;
		}

		if( im_writeline( y, out, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
Example #17
0
/** 
 * im_linreg:
 * @ins: NULL-terminated array of input images
 * @out: results of analysis
 * @xs:	X position of each image (pixel value is Y)
 *
 * Function to find perform pixelwise linear regression on an array of 
 * single band images. The output is a seven-band douuble image
 *
 * TODO: figure out how this works and fix up these docs!
 */
int im_linreg( IMAGE **ins, IMAGE *out, double *xs ){
#define FUNCTION_NAME "im_linreg"
  int n;
  x_set *x_vals;

  if( im_poutcheck( out ) )
    return( -1 );

  for( n= 0; ins[ n ]; ++n ){
/*
    if( ! isfinite( xs[ n ] ) ){
      im_error( FUNCTION_NAME, "invalid argument" );
      return( -1 );
    }
*/
    if( im_pincheck( ins[ n ] ) )
      return( -1 );

    if( 1 != ins[ n ]-> Bands ){
      im_error( FUNCTION_NAME, "image is not single band" );
      return( -1 );
    }
    if( ins[ n ]-> Coding ){
      im_error( FUNCTION_NAME, "image is not uncoded" );
      return( -1 );
    }
    if( n ){
      if( ins[ n ]-> BandFmt != ins[ 0 ]-> BandFmt ){
        im_error( FUNCTION_NAME, "image band formats differ" );
        return( -1 );
      }
    }
    else {
      if( vips_bandfmt_iscomplex( ins[ 0 ]->BandFmt ) ){
        im_error( FUNCTION_NAME, "image has non-scalar band format" );
        return( -1 );
      }
    }
    if( n && ( ins[ n ]-> Xsize != ins[ 0 ]-> Xsize
        || ins[ n ]-> Ysize != ins[ 0 ]-> Ysize ) ){

      im_error( FUNCTION_NAME, "image sizes differ" );
      return( -1 );
    }
  }
  if( n < 3 ){
    im_error( FUNCTION_NAME, "not enough input images" );
    return( -1 );
  }
  if( im_cp_desc_array( out, ins ) )
    return( -1 );

  out-> Bands= 7;
  out-> BandFmt= IM_BANDFMT_DOUBLE;
  out-> Type= 0;

  if( im_demand_hint_array( out, IM_THINSTRIP, ins ) )
    return( -1 );

  x_vals= x_anal( out, xs, n );

  if( ! x_vals )
    return( -1 );

  switch( ins[ 0 ]-> BandFmt ){
#define LINREG_RET( TYPE )  return im_generate( out, linreg_start_ ## TYPE, linreg_gen_ ## TYPE, linreg_stop_ ## TYPE, ins, x_vals )

    case IM_BANDFMT_CHAR:
      LINREG_RET( gint8 );

    case IM_BANDFMT_UCHAR:
      LINREG_RET( guint8 );

    case IM_BANDFMT_SHORT:
      LINREG_RET( gint16 );

    case IM_BANDFMT_USHORT:
      LINREG_RET( guint16 );

    case IM_BANDFMT_INT:
      LINREG_RET( gint32 );

    case IM_BANDFMT_UINT:
      LINREG_RET( guint32 );

    case IM_BANDFMT_FLOAT:
      LINREG_RET( float );

    case IM_BANDFMT_DOUBLE:
      LINREG_RET( double );

    default:  /* keep -Wall happy */
      return( -1 );
  }
#undef FUNCTION_NAME
}
Example #18
0
/* Write a VIPS image to a JPEG compress struct.
 */
static int
write_vips( Write *write, int qfac, const char *profile )
{
	IMAGE *in;
	J_COLOR_SPACE space;

	/* The image we'll be writing ... can change, see CMYK.
	 */
	in = write->in;

	/* Should have been converted for save.
	 */
        g_assert( in->BandFmt == IM_BANDFMT_UCHAR );
	g_assert( in->Coding == IM_CODING_NONE );
        g_assert( in->Bands == 1 || in->Bands == 3 || in->Bands == 4 );

        /* Check input image.
         */
	if( im_pincheck( in ) )
		return( -1 );
        if( qfac < 0 || qfac > 100 ) {
                im_error( "im_vips2jpeg", 
			"%s", _( "qfac should be in 0-100" ) );
                return( -1 );
        }

	/* Set compression parameters.
	 */
        write->cinfo.image_width = in->Xsize;
        write->cinfo.image_height = in->Ysize;
	write->cinfo.input_components = in->Bands;
	if( in->Bands == 4 && in->Type == IM_TYPE_CMYK ) {
		space = JCS_CMYK;
		/* IJG always sets an Adobe marker, so we should invert CMYK.
		 */
		if( !(write->inverted = im_open( "vips2jpeg_invert", "p" )) ||
			im_invert( in, write->inverted ) )
			return( -1 );
		in = write->inverted;
	}
	else if( in->Bands == 3 )
		space = JCS_RGB;
	else if( in->Bands == 1 )
		space = JCS_GRAYSCALE;
	else 
		/* Use luminance compression for all channels.
		 */
		space = JCS_UNKNOWN;
	write->cinfo.in_color_space = space; 

	/* Build VIPS output stuff now we know the image we'll be writing.
	 */
	if( !(write->row_pointer = 
		IM_ARRAY( NULL, write->in->Ysize, JSAMPROW )) )
		return( -1 );

	/* Rest to default. 
	 */
        jpeg_set_defaults( &write->cinfo );
        jpeg_set_quality( &write->cinfo, qfac, TRUE );

	/* Build compress tables.
	 */
	jpeg_start_compress( &write->cinfo, TRUE );

	/* Write any APP markers we need.
	 */
	if( write_exif( write ) )
		return( -1 );

	/* A profile supplied as an argument overrides an embedded profile.
	 * "none" means don't attach a profile.
	 */
	if( profile && 
		strcmp( profile, "none" ) != 0 &&
		write_profile_file( write, profile ) )
		return( -1 );
	if( !profile && 
		im_header_get_typeof( in, IM_META_ICC_NAME ) && 
		write_profile_meta( write ) )
		return( -1 );

	/* Write data. Note that the write function grabs the longjmp()!
	 */
	if( vips_sink_disc( write->in, write_jpeg_block, write ) )
		return( -1 );

	/* We have to reinstate the setjmp() before we jpeg_finish_compress().
	 */
	if( setjmp( write->eman.jmp ) ) 
		return( -1 );

	jpeg_finish_compress( &write->cinfo );

	return( 0 );
}
Example #19
0
/* Use fftw2.
 */
static int 
invfft1( IMAGE *dummy, IMAGE *in, IMAGE *out )
{
	IMAGE *cmplx = im_open_local( dummy, "invfft1-1", "t" );
	IMAGE *real = im_open_local( out, "invfft1-2", "t" );
	const int half_width = in->Xsize / 2 + 1;

	/* Transform to halfcomplex here.
	 */
	double *half_complex = IM_ARRAY( dummy, 
		in->Ysize * half_width * 2, double );

	rfftwnd_plan plan;
	int x, y;
	double *q, *p;

	if( !cmplx || !real || !half_complex || im_pincheck( in ) || 
		im_poutcheck( out ) )
		return( -1 );
	if( in->Coding != IM_CODING_NONE || in->Bands != 1 ) {
                im_error( "im_invfft", _( "one band uncoded only" ) );
                return( -1 );
	}

	/* Make dp complex image for input.
	 */
	if( im_clip2fmt( in, cmplx, IM_BANDFMT_DPCOMPLEX ) )
                return( -1 );

	/* Make mem buffer real image for output.
	 */
        if( im_cp_desc( real, in ) )
                return( -1 );
	real->BandFmt = IM_BANDFMT_DOUBLE;
        if( im_setupout( real ) )
                return( -1 );

	/* Build half-complex image.
	 */
	q = half_complex;
	for( y = 0; y < cmplx->Ysize; y++ ) {
		p = ((double *) cmplx->data) + y * in->Xsize * 2; 

		for( x = 0; x < half_width; x++ ) {
			q[0] = p[0];
			q[1] = p[1];
			p += 2;
			q += 2;
		}
	}

	/* Make the plan for the transform. Yes, they really do use nx for
	 * height and ny for width.
	 */
	if( !(plan = rfftw2d_create_plan( in->Ysize, in->Xsize,
		FFTW_BACKWARD, FFTW_MEASURE | FFTW_USE_WISDOM )) ) {
                im_error( "im_invfft", _( "unable to create transform plan" ) );
		return( -1 );
	}

	rfftwnd_one_complex_to_real( plan, 
		(fftw_complex *) half_complex, (fftw_real *) real->data );

	rfftwnd_destroy_plan( plan );

	/* Copy to out.
	 */
        if( im_copy( real, out ) )
                return( -1 );

	return( 0 );
}