/* Like im_insert, but perform an in-place insertion.
 */
int
im_insertplace( IMAGE *big, IMAGE *small, int x, int y )
{	
	Rect br, sr;
	PEL *p, *q;
	int z;

	/* Check IO.
	 */
	if( im_rwcheck( big ) || im_incheck( small ) )
		return( -1 );

	/* Check compatibility.
	 */
        if( big->BandFmt != small->BandFmt || big->Bands != small->Bands ||
                big->Coding != small->Coding ) {
                im_error( "im_insertplace", _( "inputs differ in format" ) );
                return( -1 );
        }
        if( big->Coding != IM_CODING_NONE && big->Coding != IM_CODING_LABQ ) {
                im_error( "im_insertplace", _( "input should be uncoded "
                        "or IM_CODING_LABQ" ) );
                return( -1 );
        }

	/* Make rects for big and small.
	 */
	br.left = 0;
	br.top = 0;
	br.width = big->Xsize;
	br.height = big->Ysize;
	sr.left = x;
	sr.top = y;
	sr.width = small->Xsize;
	sr.height = small->Ysize;

	/* Small fits inside big?
	 */
	if( !im_rect_includesrect( &br, &sr ) ) {
		im_error( "im_insertplace", _( "small not inside big" ) );
		return( -1 );
	}

	/* Loop, memcpying small to big.
	 */
	p = (PEL *) IM_IMAGE_ADDR( small, 0, 0 );
	q = (PEL *) IM_IMAGE_ADDR( big, x, y );
	for( z = 0; z < small->Ysize; z++ ) {
		memcpy( (char *) q, (char *) p, IM_IMAGE_SIZEOF_LINE( small ) );
		p += IM_IMAGE_SIZEOF_LINE( small );
		q += IM_IMAGE_SIZEOF_LINE( big );
	}

	im_invalidate( big );

	return( 0 );
}
Beispiel #2
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 );
}
Beispiel #3
0
/* Read an ascii 1 bit file.
 */
static int
read_1bit_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 );

			if( val == 1 )
				buf[x] = 0;
			else
				buf[x] = 255;
		}

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

	return( 0 );
}
Beispiel #4
0
/* Print a one-line description of an image, with an index.
 */
static void *
print_one_line( IMAGE *im, int *n, int *total )
{
	printf( "%2d) %p, %s, %s: %dx%d, %d bands, %s\n",
		*n, 
		im,
		im_dtype2char( im->dtype ), im->filename, 
		im->Xsize, im->Ysize, im->Bands,
		im_BandFmt2char( im->BandFmt ) );
	*n += 1;

	if( im->dtype == IM_SETBUF && im->data ) {
		int size = IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize;

		printf( "\t*** %d malloced bytes\n", size );
		*total += size;
	}

	if( im->regions ) {
		int n2;
		int total2;

		printf( "\t%d regions\n", g_slist_length( im->regions ) );
		n2 = 0;
		total2 = 0;
		(void) im_slist_map2( im->regions, 
			(VSListMap2Fn) print_one_line_region, &n2, &total2 );
		if( total2 )
			printf( "\t*** using total of %d bytes\n", total2 );
		*total += total2;
	}

	return( NULL );
}
Beispiel #5
0
/* Read a 1 bit binary file.
 */
static int
read_1bit_binary( FILE *fp, IMAGE *out )
{
	int x, y, i;
	int bits;
	PEL *buf;

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

	bits = fgetc( fp );
	for( i = 0, y = 0; y < out->Ysize; y++ ) {
		for( x = 0; x < out->Xsize * out->Bands; x++, i++ ) {
			buf[x] = (bits & 128) ? 255 : 0;
			bits <<= 1;
			if( (i & 7) == 7 )
				bits = fgetc( fp );
		}

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

	return( 0 );
}
Beispiel #6
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 );
}
Beispiel #7
0
/**
 * im_draw_image:
 * @image: image to draw on
 * @sub: image to draw
 * @x: position to insert
 * @y: position to insert
 *
 * Draw @sub on top of @image at position @x, @y. The two images must have the
 * same
 * Coding. If @sub has 1 band, the bands will be duplicated to match the
 * number of bands in @image. @sub will be converted to @image's format, see
 * im_clip2fmt().
 *
 * See also: im_insert().
 *
 * Returns: 0 on success, or -1 on error.
 */
int
im_draw_image( VipsImage *image, VipsImage *sub, int x, int y )
{
    Rect br, sr, clip;
    PEL *p, *q;
    int z;

    /* Make rects for main and sub and clip.
     */
    br.left = 0;
    br.top = 0;
    br.width = image->Xsize;
    br.height = image->Ysize;
    sr.left = x;
    sr.top = y;
    sr.width = sub->Xsize;
    sr.height = sub->Ysize;
    im_rect_intersectrect( &br, &sr, &clip );
    if( im_rect_isempty( &clip ) )
        return( 0 );

    if( !(sub = im__inplace_base( "im_draw_image", image, sub, image )) ||
            im_rwcheck( image ) ||
            im_incheck( sub ) )
        return( -1 );

    /* Loop, memcpying sub to main.
     */
    p = (PEL *) IM_IMAGE_ADDR( sub, clip.left - x, clip.top - y );
    q = (PEL *) IM_IMAGE_ADDR( image, clip.left, clip.top );
    for( z = 0; z < clip.height; z++ ) {
        memcpy( (char *) q, (char *) p,
                clip.width * IM_IMAGE_SIZEOF_PEL( sub ) );
        p += IM_IMAGE_SIZEOF_LINE( sub );
        q += IM_IMAGE_SIZEOF_LINE( image );
    }

    return( 0 );
}
Beispiel #8
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 );
}
Beispiel #9
0
Draw *
im__draw_init( Draw *draw, IMAGE *im, PEL *ink )
{
	if( im_rwcheck( im ) )
		return( NULL );

	draw->im = im;
	draw->ink = NULL;

	draw->lsize = IM_IMAGE_SIZEOF_LINE( im );
	draw->psize = IM_IMAGE_SIZEOF_PEL( im );
	draw->noclip = FALSE;

	if( ink ) {
		if( !(draw->ink = (PEL *) im_malloc( NULL, draw->psize )) ) 
			return( NULL );
		memcpy( draw->ink, ink, draw->psize );
	}

	return( draw );
}
Beispiel #10
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 );
}
Beispiel #11
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 );
}
Beispiel #12
0
/* Sort of open for read for image files. Shared with im_binfile().
 */
int
im__open_image_file( const char *filename )
{
	int fd;

	/* Try to open read-write, so that calls to im_makerw() will work.
	 * When we later mmap this file, we set read-only, so there 
	 * is little danger of scrubbing over files we own.
	 */
#ifdef BINARY_OPEN
	if( (fd = open( filename, O_RDWR | O_BINARY )) == -1 ) {
#else /*BINARY_OPEN*/
	if( (fd = open( filename, O_RDWR )) == -1 ) {
#endif /*BINARY_OPEN*/
		/* Open read-write failed. Fall back to open read-only.
		 */
#ifdef BINARY_OPEN
		if( (fd = open( filename, O_RDONLY | O_BINARY )) == -1 ) {
#else /*BINARY_OPEN*/
		if( (fd = open( filename, O_RDONLY )) == -1 ) {
#endif /*BINARY_OPEN*/
			im_error( "im__open_image_file", 
				_( "unable to open \"%s\", %s" ),
				filename, strerror( errno ) );
			return( -1 );
		}
	}

	return( fd );
}

/* Predict the size of the header plus pixel data. Don't use off_t,
 * it's sometimes only 32 bits (eg. on many windows build environments) and we
 * want to always be 64 bit.
 */
static gint64
im__image_pixel_length( IMAGE *im )
{
	gint64 psize;

	switch( im->Coding ) {
	case IM_CODING_LABQ:
	case IM_CODING_NONE:
		psize = (gint64) IM_IMAGE_SIZEOF_LINE( im ) * im->Ysize;
		break;

	default:
		psize = im->Length;
		break;
	}

	return( psize + im->sizeof_header );
}

/* Read short/int/float LSB and MSB first.
 */
void
im__read_4byte( int msb_first, unsigned char *to, unsigned char **from )
{
	unsigned char *p = *from;
	int out;

	if( msb_first )
		out = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
	else
		out = p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];

	*from += 4;
	*((guint32 *) to) = out;
}
Beispiel #13
0
/**
 * im_profile:
 * @in: input image
 * @out: output image
 * @dir: search direction
 *
 * im_profile() searches inward from the edge of @in and finds the 
 * first non-zero pixel. It outputs an image containing a list of the offsets 
 * for each row or column.
 *
 * If @dir == 0, then im_profile() searches down from the top edge, writing an 
 * image as wide as the input image, but only 1 pixel high, containing the 
 * number of pixels down to the first non-zero pixel for each column of input 
 * pixels.
 *
 * If @dir == 1, then im_profile() searches across from the left edge, 
 * writing an image as high as the input image, but only 1 pixel wide, 
 * containing the number of pixels across to the
 * first non-zero pixel for each row of input pixels.
 *
 * See also: im_cntlines().
 *
 * Returns: 0 on success, -1 on error
 */
int 
im_profile( IMAGE *in, IMAGE *out, int dir )
{
	int sz;
	unsigned short *buf;
	int x, y, b;

	/* If in is not uchar, do (!=0) to make a uchar image.
	 */
	if( in->BandFmt != IM_BANDFMT_UCHAR ) {
		IMAGE *t;

		if( !(t = im_open_local( out, "im_profile", "p" )) ||
			im_notequalconst( in, t, 0 ) )
			return( -1 );

		in = t;
	}

	/* Check im.
	 */
	if( im_iocheck( in, out ) ||
		im_check_uncoded( "im_profile", in ) ||
		im_check_format( "im_profile", in, IM_BANDFMT_UCHAR ) )
		return( -1 );
	if( dir != 0 && 
		dir != 1 ) {
		im_error( "im_profile", "%s", _( "dir not 0 or 1" ) );
		return( -1 ); 
	}

	if( im_cp_desc( out, in ) )
		return( -1 );
	out->Type = IM_TYPE_HISTOGRAM;
	if( dir == 0 ) {
		out->Xsize = in->Xsize;
		out->Ysize = 1;
	}
	else {
		out->Xsize = 1;
		out->Ysize = in->Ysize;
	}
	out->BandFmt = IM_BANDFMT_USHORT;
	if( im_setupout( out ) )
		return( -1 );
	sz = IM_IMAGE_N_ELEMENTS( out );
	if( !(buf = IM_ARRAY( out, sz, unsigned short )) )
		return( -1 );

	if( dir == 0 ) {
		/* Find vertical lines.
		 */
		for( x = 0; x < sz; x++ ) {
			PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, 0 ) + x;
			int lsk = IM_IMAGE_SIZEOF_LINE( in );

			for( y = 0; y < in->Ysize; y++ ) {
				if( *p )
					break;
				p += lsk;
			}

			buf[x] = y;
		}

		if( im_writeline( 0, out, (PEL *) buf ) )
			return( -1 );
	}
	else {
		/* Search horizontal lines.
		 */
		for( y = 0; y < in->Ysize; y++ ) {
			PEL *p = (PEL *) IM_IMAGE_ADDR( in, 0, y );

			for( b = 0; b < in->Bands; b++ ) {
				PEL *p1;

				p1 = p + b;
				for( x = 0; x < in->Xsize; x++ ) {
					if( *p1 )
						break;
					p1 += in->Bands;
				}

				buf[b] = x;
			}

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

	return( 0 );
}
Beispiel #14
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 );
}
Beispiel #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 );
}
Beispiel #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 );
}
Beispiel #17
0
/**
 * im_region_image:
 * @reg: region to operate upon
 * @r: #Rect of pixels you need to be able to address
 *
 * The region is transformed so that at least @r pixels are available directly
 * from the image. The image needs to be a memory buffer or represent a file
 * on disc that has been mapped or can be mapped.
 *
 * Returns: 0 on success, or -1 for error.
 */
int
im_region_image( REGION *reg, Rect *r )
{
    Rect image;
    Rect clipped;

    /* Sanity check.
     */
    im__region_check_ownership( reg );

    /* Clip against image.
     */
    image.top = 0;
    image.left = 0;
    image.width = reg->im->Xsize;
    image.height = reg->im->Ysize;
    im_rect_intersectrect( r, &image, &clipped );

    /* Test for empty.
     */
    if( im_rect_isempty( &clipped ) ) {
        im_error( "im_region_image",
                  "%s", _( "valid clipped to nothing" ) );
        return( -1 );
    }

    if( reg->im->data ) {
        /* We have the whole image available ... easy!
         */
        im_region_reset( reg );

        /* We can't just set valid = clipped, since this may be an
         * incompletely calculated memory buffer. Just set valid to r.
         */
        reg->valid = clipped;
        reg->bpl = IM_IMAGE_SIZEOF_LINE( reg->im );
        reg->data = reg->im->data +
                    (gint64) clipped.top * IM_IMAGE_SIZEOF_LINE( reg->im ) +
                    clipped.left * IM_IMAGE_SIZEOF_PEL( reg->im );
        reg->type = IM_REGION_OTHER_IMAGE;
    }
    else if( reg->im->dtype == IM_OPENIN ) {
        /* No complete image data ... but we can use a rolling window.
         */
        if( reg->type != IM_REGION_WINDOW || !reg->window ||
                reg->window->top > clipped.top ||
                reg->window->top + reg->window->height <
                clipped.top + clipped.height ) {
            im_region_reset( reg );

            if( !(reg->window = im_window_ref( reg->im,
                                               clipped.top, clipped.height )) )
                return( -1 );

            reg->type = IM_REGION_WINDOW;
        }

        /* Note the area the window actually represents.
         */
        reg->valid.left = 0;
        reg->valid.top = reg->window->top;
        reg->valid.width = reg->im->Xsize;
        reg->valid.height = reg->window->height;
        reg->bpl = IM_IMAGE_SIZEOF_LINE( reg->im );
        reg->data = reg->window->data;
    }
    else {
        im_error( "im_region_image",
                  "%s", _( "bad image type" ) );
        return( -1 );
    }

    return( 0 );
}
int 
im_resize_linear( IMAGE *in, IMAGE *out, int X, int Y )
{
    double	dx, dy, xscale, yscale;
    double	Xnew, Ynew;	/* inv. coord. of the interpolated pt */

    int		x, y;
    int		Xint, Yint;
    int		bb;

    PEL		*input, *opline;
    PEL 	*q, *p;

    int 	ils, ips, ies;		/* Input and output line, pel and */
    int 	ols, ops, oes;		/* element sizes */

	if( im_iocheck( in, out ) )
		return( -1 );
	if( im_iscomplex( in ) ) {
		im_errormsg( "im_lowpass: non-complex input only" );
		return( -1 );
	}
	if( in->Coding != IM_CODING_NONE ) {
		im_errormsg("im_lowpass: input should be uncoded");
		return( -1 );
	}
	if( im_cp_desc( out, in ) ) 
		return( -1 );

	out->Xsize = X;
	out->Ysize = Y;

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

	ils = IM_IMAGE_SIZEOF_LINE( in );
	ips = IM_IMAGE_SIZEOF_PEL( in );
	ies = IM_IMAGE_SIZEOF_ELEMENT( in );

	ols = IM_IMAGE_SIZEOF_LINE( out );
	ops = IM_IMAGE_SIZEOF_PEL( out );
	oes = IM_IMAGE_SIZEOF_ELEMENT( out );

/* buffer lines
***************/
	if( !(opline = IM_ARRAY( out, ols, PEL )) ) 
		return( -1 );

/* Resampling
*************/
	input = (PEL*) in->data;
	xscale = ((double)in->Xsize-1)/(X-1);
	yscale = ((double)in->Ysize-1)/(Y-1);

for (y=0; y<Y; y++)
  {
    q = opline;
    for (x=0; x<X; x++)
      {
	Xnew = x*xscale;
	Ynew = y*yscale;
	Xint = floor(Xnew);
	Yint = floor(Ynew);
	dx = Xnew - Xint;
	dy = Ynew - Yint;
	p = input + Xint*ips + Yint*ils;

	switch( in->BandFmt ) {
	case IM_BANDFMT_UCHAR:		LOOP( unsigned char); break;
	case IM_BANDFMT_USHORT:		LOOP( unsigned short ); break;
	case IM_BANDFMT_UINT:		LOOP( unsigned int ); break;
	case IM_BANDFMT_CHAR:		LOOP( signed char ); break;
	case IM_BANDFMT_SHORT:		LOOP( signed short ); break;
	case IM_BANDFMT_INT:		LOOP( signed int ); break;
	case IM_BANDFMT_FLOAT:		LOOP( float ); break;
	case IM_BANDFMT_DOUBLE:		LOOP( double ); break;

	default:
		im_errormsg( "im_lowpass: unsupported image type" );
		return( -1 );
		/*NOTREACHED*/
	}
      }

    if (im_writeline(y, out, opline) )
	    return(-1);
  } 
return(0);
}
Beispiel #19
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 );
}