Exemple #1
0
/* Yuk! Have to malloc enough space for the whole image. Interlaced PNG
 * is not really suitable for large objects ...
 */
static int
png2vips_interlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->row_pointer = IM_ARRAY( NULL, 
		read->pInfo->height, png_bytep )) )
		return( -1 );
	if( !(read->data = (png_bytep) im_malloc( NULL,
		read->pInfo->height * rowbytes ))  )
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		read->row_pointer[y] = read->data + y * rowbytes;
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	png_read_image( read->pPng, read->row_pointer );

	for( y = 0; y < (int) read->pInfo->height; y++ )
		if( im_writeline( y, read->out, read->row_pointer[y] ) )
			return( -1 );

	return( 0 );
}
Exemple #2
0
static int
mat2vips_get_data( mat_t *mat, matvar_t *var, IMAGE *im )
{
	int y;
	PEL *buffer;
	const int es = IM_IMAGE_SIZEOF_ELEMENT( im );

	/* Matlab images are plane-separate, so we have to assemble bands in
	 * image-size chunks.
	 */
	const int is = es * im->Xsize * im->Ysize;

	if( Mat_VarReadDataAll( mat, var ) ) {
		im_error( "im_mat2vips", "%s", 
			_( "Mat_VarReadDataAll failed" ) );
		return( -1 );
	}
	if( im_outcheck( im ) ||
		im_setupout( im ) )
		return( -1 );

	/* Matlab images are in columns, so we have to transpose into
	 * scanlines with this buffer.
	 */
	if( !(buffer = IM_ARRAY( im, IM_IMAGE_SIZEOF_LINE( im ), PEL )) )
		return( -1 );

	for( y = 0; y < im->Ysize; y++ ) {
		const PEL *p = var->data + y * es;
		int x;
		PEL *q;

		q = buffer;
		for( x = 0; x < im->Xsize; x++ ) {
			int b;

			for( b = 0; b < im->Bands; b++ ) {
				const PEL *p2 = p + b * is;
				int z;

				for( z = 0; z < es; z++ )
					q[z] = p2[z];

				q += es;
			}

			p += es * im->Ysize;
		}

		if( im_writeline( y, im, buffer ) )
			return( -1 );
	}

	return( 0 );
}
Exemple #3
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 );
}
Exemple #4
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 );
}
Exemple #5
0
/* Read a cinfo to a VIPS image.
 */
static int
read_jpeg_image( struct jpeg_decompress_struct *cinfo, IMAGE *out, 
	gboolean invert_pels )
{
	int x, y, sz;
	JSAMPROW row_pointer[1];

	/* Check VIPS.
	 */
	if( im_outcheck( out ) || im_setupout( out ) )
		return( -1 );

	/* Get size of output line and make a buffer.
	 */
	sz = cinfo->output_width * cinfo->output_components;
	row_pointer[0] = (JSAMPLE *) (*cinfo->mem->alloc_large) 
		( (j_common_ptr) cinfo, JPOOL_IMAGE, sz );

	/* Start up decompressor.
	 */
	jpeg_start_decompress( cinfo );

	/* Process image.
	 */
	for( y = 0; y < out->Ysize; y++ ) {
		/* We set an error handler that longjmps() out, so I don't
		 * think this can fail.
		 */
		jpeg_read_scanlines( cinfo, &row_pointer[0], 1 );

		if( invert_pels ) {
			for( x = 0; x < sz; x++ )
				row_pointer[0][x] = 255 - row_pointer[0][x];
		}
		if( im_writeline( y, out, row_pointer[0] ) )
			return( -1 );
	}

	/* Stop decompressor.
	 */
	jpeg_finish_decompress( cinfo );

	return( 0 );
}
Exemple #6
0
int
im_fzone( IMAGE *image, int size )
{
	int x, y;
	int i, j;

	float *buf;
	const int size2 = size/2;

	/* Check args.
	 */
	if( im_outcheck( image ) )
		return( -1 );
	if( size <= 0 || (size % 2) != 0 ) {
		im_error( "im_zone", "%s", 
			_( "size must be even and positive" ) );
		return( -1 );
	}

	/* Set up output image.
	 */
        im_initdesc( image, size, size, 1, IM_BBITS_FLOAT, IM_BANDFMT_FLOAT,
		IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 );
        if( im_setupout( image ) )
                return( -1 );

	/* Create output buffer.
	 */
        if( !(buf = IM_ARRAY( image, size, float )) )
                return( -1 );

	/* Make zone plate.
	 */
	for( y = 0, j = -size2; j < size2; j++, y++ ) {
		for( x = 0, i = -size2; i < size2; i++, x++ )
			buf[x] = cos( (IM_PI / size) * (i * i + j * j) );
		if( im_writeline( y, image, (PEL *) buf ) )
			return( -1 );
	}

	return( 0 );
}
Exemple #7
0
/* Read an ascii ppm/pgm file.
 */
static int
read_ascii( FILE *fp, IMAGE *out )
{
	int x, y;
	PEL *buf;

	if( im_outcheck( out ) || im_setupout( out ) ||
		!(buf = IM_ARRAY( out, IM_IMAGE_SIZEOF_LINE( out ), PEL )) )
		return( -1 );

	for( y = 0; y < out->Ysize; y++ ) {
		for( x = 0; x < out->Xsize * out->Bands; x++ ) {
			int val;

			if( read_int( fp, &val ) )
				return( -1 );
			
			switch( out->BandFmt ) {
			case IM_BANDFMT_UCHAR:
				buf[x] = IM_CLIP( 0, val, 255 );
				break;

			case IM_BANDFMT_USHORT:
				((unsigned short *) buf)[x] = 
					IM_CLIP( 0, val, 65535 );
				break;

			case IM_BANDFMT_UINT:
				((unsigned int *) buf)[x] = val;
				break;

			default:
				g_assert( 0 );
			}
		}

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

	return( 0 );
}
Exemple #8
0
static int
lgrab_capture( LGrab *lg, IMAGE *im )
{
	int x, y;
	unsigned char *line;

	if( lgrab_capturen( lg ) )
		return( -1 );

	if( im_outcheck( im ) )
		return( -1 );
        im_initdesc( im, lg->c_width, lg->c_height, 3,
                IM_BBITS_BYTE, IM_BANDFMT_UCHAR,
                IM_CODING_NONE, IM_TYPE_MULTIBAND, 1.0, 1.0, 0, 0 );
        if( im_setupout( im ) )
                return( -1 );
	if( !(line = IM_ARRAY( im, 
		IM_IMAGE_SIZEOF_LINE( im ), unsigned char )) )
                return( -1 );

        for( y = 0; y < lg->c_height; y++ ) {
                unsigned char *p = (unsigned char *) lg->capture_buffer + 
			y * IM_IMAGE_SIZEOF_LINE( im );
                unsigned char *q = line;

		for( x = 0; x < lg->c_width; x++ ) {
			q[0] = p[2];
			q[1] = p[1];
			q[2] = p[0];

			p += 3;
			q += 3;
		}

                if( im_writeline( y, im, line ) )
                        return( -1 );
	}

	return( 0 );
}
Exemple #9
0
/* Noninterlaced images can be read without needing enough RAM for the whole
 * image.
 */
static int
png2vips_noninterlace( Read *read )
{
	const int rowbytes = IM_IMAGE_SIZEOF_LINE( read->out );
	int y;

	if( !(read->data = (png_bytep) im_malloc( NULL, rowbytes ))  )
		return( -1 );
	if( im_outcheck( read->out ) || 
		im_setupout( read->out ) || 
		setjmp( read->pPng->jmpbuf ) ) 
		return( -1 );

	for( y = 0; y < (int) read->pInfo->height; y++ ) {
		png_read_row( read->pPng, read->data, NULL );

		if( im_writeline( y, read->out, read->data ) )
			return( -1 );
	}

	return( 0 );
}
Exemple #10
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 );
}
Exemple #11
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 );
}
Exemple #12
0
/**
 * im_simcontr:
 * @out: output image
 * @xsize: image size
 * @ysize: image size
 *
 * Creates a pattern showing the similtaneous constrast effect.
 *
 * See also: im_eye().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_simcontr( IMAGE *out, int xsize, int ysize )
{
	int x, y;
	unsigned char *line1, *line2, *cpline;


/* Check input args */
	if( im_outcheck( out ) )
		return( -1 );

/* Set now image properly */
        im_initdesc(out, xsize, ysize, 1, IM_BBITS_BYTE, IM_BANDFMT_UCHAR,
		IM_CODING_NONE, IM_TYPE_B_W, 1.0, 1.0, 0, 0 );

/* Set up image checking whether the output is a buffer or a file */
        if (im_setupout( out ) == -1 )
                return( -1 );
/* Create data */
        line1 = (unsigned char *)calloc((unsigned)xsize, sizeof(char));
        line2 = (unsigned char *)calloc((unsigned)xsize, sizeof(char));
        if ( (line1 == NULL) || (line2 == NULL) ) { 
		im_error( "im_simcontr", "%s", _( "calloc failed") ); 
		return(-1); }

	cpline = line1;
	for (x=0; x<xsize; x++)
		*cpline++ = (PEL)255;
	cpline = line1;
	for (x=0; x<xsize/2; x++)
		*cpline++ = (PEL)0;
	
	cpline = line2;
	for (x=0; x<xsize; x++)
		*cpline++ = (PEL)255;
	cpline = line2;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)0;
	for (x=0; x<xsize/4; x++)
		*cpline++ = (PEL)128;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)0;
	for (x=0; x<xsize/8; x++)
		*cpline++ = (PEL)255;
	for (x=0; x<xsize/4; x++)
		*cpline++ = (PEL)128;

	for (y=0; y<ysize/4; y++)
		{
		if ( im_writeline( y, out, (PEL *)line1 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	for (y=ysize/4; y<(ysize/4+ysize/2); y++)
		{
		if ( im_writeline( y, out, (PEL *)line2 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	for (y=(ysize/4 + ysize/2); y<ysize; y++)
		{
		if ( im_writeline( y, out, (PEL *)line1 ) == -1 )
			{
			free ( (char *)line1 ); free ( (char *)line2 );
			return( -1 );
			}
		}
	free ( (char *)line1 ); free ( (char *)line2 );
	return(0);
}
Exemple #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 );
}
Exemple #14
0
/**
 * im_tone_build_range:
 * @out: output image
 * @in_max: input range
 * @out_max: output range
 * @Lb: black-point [0-100]
 * @Lw: white-point [0-100]
 * @Ps: shadow point (eg. 0.2)
 * @Pm: mid-tone point (eg. 0.5)
 * @Ph: highlight point (eg. 0.8)
 * @S: shadow adjustment (+/- 30)
 * @M: mid-tone adjustment (+/- 30)
 * @H: highlight adjustment (+/- 30)
 *
 * im_tone_build_range() generates a tone curve for the adjustment of image
 * levels. It is mostly designed for adjusting the L* part of a LAB image in
 * way suitable for print work, but you can use it for other things too.
 *
 * The curve is an unsigned 16-bit image with (@in_max + 1) entries,
 * each in the range [0, @out_max].
 *
 * @Lb, @Lw are expressed as 0-100, as in LAB colour space. You
 * specify the scaling for the input and output images with the @in_max and
 * @out_max parameters.
 *
 * See also: im_ismonotonic(), im_tone_map(), im_tone_analyse().
 *
 * Returns: 0 on success, -1 on error
 */
int
im_tone_build_range( IMAGE *out,
                     int in_max, int out_max,
                     double Lb, double Lw,
                     double Ps, double Pm, double Ph,
                     double S, double M, double H )
{
    ToneShape *ts;
    unsigned short lut[65536];
    int i;

    /* Check args.
     */
    if( !(ts = IM_NEW( out, ToneShape )) ||
            im_outcheck( out ) )
        return( -1 );
    if( in_max < 0 || in_max > 65535 ||
            out_max < 0 || out_max > 65535 ) {
        im_error( "im_tone_build",
                  "%s", _( "bad in_max, out_max parameters" ) );
        return( -1 );
    }
    if( Lb < 0 || Lb > 100 || Lw < 0 || Lw > 100 || Lb > Lw ) {
        im_error( "im_tone_build",
                  "%s", _( "bad Lb, Lw parameters" ) );
        return( -1 );
    }
    if( Ps < 0.0 || Ps > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Ps not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( Pm < 0.0 || Pm > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Pm not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( Ph < 0.0 || Ph > 1.0 ) {
        im_error( "im_tone_build",
                  "%s", _( "Ph not in range [0.0,1.0]" ) );
        return( -1 );
    }
    if( S < -30 || S > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "S not in range [-30,+30]" ) );
        return( -1 );
    }
    if( M < -30 || M > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "M not in range [-30,+30]" ) );
        return( -1 );
    }
    if( H < -30 || H > 30 ) {
        im_error( "im_tone_build",
                  "%s", _( "H not in range [-30,+30]" ) );
        return( -1 );
    }

    /* Note params.
     */
    ts->Lb = Lb;
    ts->Lw = Lw;
    ts->Ps = Ps;
    ts->Pm = Pm;
    ts->Ph = Ph;
    ts->S = S;
    ts->M = M;
    ts->H = H;

    /* Note derived params.
     */
    ts->Ls = Lb + Ps * (Lw - Lb);
    ts->Lm = Lb + Pm * (Lw - Lb);
    ts->Lh = Lb + Ph * (Lw - Lb);

    /* Generate curve.
     */
    for( i = 0; i <= in_max; i++ ) {
        int v = (out_max / 100.0) *
                tone_curve( ts, 100.0 * i / in_max );

        if( v < 0 )
            v = 0;
        else if( v > out_max )
            v = out_max;

        lut[i] = v;
    }

    /* Make the output image.
     */
    im_initdesc( out,
                 in_max + 1, 1, 1, IM_BBITS_SHORT, IM_BANDFMT_USHORT,
                 IM_CODING_NONE, IM_TYPE_HISTOGRAM, 1.0, 1.0, 0, 0 );
    if( im_setupout( out ) )
        return( -1 );

    if( im_writeline( 0, out, (VipsPel *) lut ) )
        return( -1 );

    return( 0 );
}
Exemple #15
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 );
}
Exemple #16
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 );
}
Exemple #17
0
/**
 * im_sines:
 * @out: output image
 * @xsize: image size
 * @ysize: image size
 * @horfreq: horizontal frequency
 * @verfreq: vertical frequency
 *
 * im_sines() creates a float one band image of the a sine waveform in two
 * dimensions.  
 *
 * The number of horizontal and vertical spatial frequencies are
 * determined by the variables @horfreq and @verfreq respectively.  The
 * function is useful for creating displayable sine waves and
 * square waves in two dimensions.
 *
 * If horfreq and verfreq are integers the resultant image is periodical
 * and therfore the Fourier transform doesnot present spikes
 * 
 * See also: im_grey(), im_make_xy(). 
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_sines( IMAGE *out, int xsize, int ysize, double horfreq, double verfreq )
{
	int x, y;
	float *line, *cpline;
	int size;
	double cons, factor;
	double theta_rad, costheta, sintheta, ysintheta;

/* Check input args */
	if( im_outcheck( out ) )
		return( -1 );
        if ( xsize <= 0 || ysize <= 0 ) { 
		im_error( "im_sines", "%s", _( "wrong sizes") ); 
		return(-1); }

/* Set now out properly */
        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 up out checking whether the output is a buffer or a file */
        if (im_setupout( out ) == -1 )
                return( -1 );
/* Create data */
	size = out->Xsize;
        if ( (line=(float *)calloc((unsigned)size, sizeof(float))) == NULL ) { 
		im_error( "im_sines", "%s", _( "calloc failed") ); 
		return(-1); }

/* make angle in rad */
	if (horfreq == 0)
		theta_rad = IM_PI/2.0;
	else
		theta_rad = atan(verfreq/horfreq);
	costheta = cos(theta_rad); sintheta = sin(theta_rad);
	factor = sqrt ((double)(horfreq*horfreq + verfreq*verfreq));
	cons =  factor * IM_PI * 2.0/(double)out->Xsize;
/* There is a bug (rounding error ?) for horfreq=0,
 *so do this calculation independantly */
	if ( horfreq != 0 )
		{
		for (y=0; y<out->Ysize; y++)
			{
			ysintheta = y * sintheta;
			cpline = line;
			for (x=0; x<out->Xsize; x++)
				*cpline++ =
				(float)(cos(cons*(x*costheta-ysintheta)));
			if ( im_writeline( y, out, (PEL *)line ) == -1 )
				{
				free ( (char *)line );
				return( -1 );
				}
			}
		}
	else
		{
		for (y=0; y<out->Ysize; y++)
			{
			cpline = line;
			ysintheta = cos (- cons * y * sintheta);
			for (x=0; x<out->Xsize; x++)
				*cpline++ = (float)ysintheta;
			if ( im_writeline( y, out, (PEL *)line ) == -1 )
				{
				free ( (char *)line );
				return( -1 );
				}
			}
		}
	free ( (char *)line );
	return(0);
}