Exemplo n.º 1
0
/* Out is a huge "t" buffer we decompress to.
 */
static int
png2vips_interlace( Read *read, VipsImage *out )
{
	int y;

#ifdef DEBUG
	printf( "png2vips_interlace: reading whole image\n" ); 
#endif /*DEBUG*/

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

	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( -1 );

	if( !(read->row_pointer = VIPS_ARRAY( NULL, out->Ysize, png_bytep )) )
		return( -1 );
	for( y = 0; y < out->Ysize; y++ )
		read->row_pointer[y] = VIPS_IMAGE_ADDR( out, 0, y );

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

	png_read_end( read->pPng, NULL ); 

	read_destroy( read );

	return( 0 );
}
Exemplo n.º 2
0
static Write *
write_new( VipsImage *in )
{
	Write *write;

	if( !(write = VIPS_NEW( in, Write )) )
		return( NULL );
	memset( write, 0, sizeof( Write ) );
	write->in = in;
	g_signal_connect( in, "close", 
		G_CALLBACK( write_destroy ), write ); 

	if( !(write->row_pointer = VIPS_ARRAY( in, in->Ysize, png_bytep )) )
		return( NULL );
	if( !(write->pPng = png_create_write_struct( 
		PNG_LIBPNG_VER_STRING, NULL,
		user_error_function, user_warning_function )) ) 
		return( NULL );

	/* Catch PNG errors from png_create_info_struct().
	 */
	if( setjmp( png_jmpbuf( write->pPng ) ) ) 
		return( NULL );

	if( !(write->pInfo = png_create_info_struct( write->pPng )) ) 
		return( NULL );

	return( write );
}
Exemplo n.º 3
0
/* Read a 1 bit binary file.
 */
static int
read_1bit_binary( FILE *fp, VipsImage *out )
{
	int x, y, i;
	int bits;
	VipsPel *buf;

	if( !(buf = VIPS_ARRAY( out, VIPS_IMAGE_SIZEOF_LINE( out ), VipsPel )) )
		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( vips_image_write_line( out, y, buf ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 4
0
/* Out is a huge "t" buffer we decompress to.
 */
static int
png2vips_interlace( Read *read, VipsImage *out )
{
	int y;

#ifdef DEBUG
	printf( "png2vips_interlace: reading whole image\n" ); 
#endif /*DEBUG*/

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

	if( setjmp( png_jmpbuf( read->pPng ) ) ) 
		return( -1 );
 
	if( !(read->row_pointer = VIPS_ARRAY( NULL, out->Ysize, png_bytep )) )
		return( -1 );
	for( y = 0; y < out->Ysize; y++ )
		read->row_pointer[y] = VIPS_IMAGE_ADDR( out, 0, y );

	/* Some libpng warn you to call png_set_interlace_handling(); here, but
	 * that can actually break interlace. We have to live with the warning,
	 * unfortunately.
	 */

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

	png_read_end( read->pPng, NULL ); 

	read_destroy( read );

	return( 0 );
}
Exemplo n.º 5
0
/* Read an ascii 1 bit file.
 */
static int
read_1bit_ascii( FILE *fp, VipsImage *out )
{
	int x, y;
	VipsPel *buf;

	if( !(buf = VIPS_ARRAY( out, VIPS_IMAGE_SIZEOF_LINE( out ), VipsPel )) )
		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( vips_image_write_line( out, y, buf ) )
			return( -1 );
	}

	return( 0 );
}
Exemplo n.º 6
0
/* Cast a n-band vector of double to a m-band vector in another format.
 */
static PEL *
make_pixel( VipsObject *obj, int m, VipsBandFmt fmt, int n, double *p )
{
	PEL *q;
	int i;

	if( !(q = VIPS_ARRAY( obj, 
		m * vips__image_sizeof_bandformat[fmt], PEL )) )
		return( NULL );

        switch( fmt ) {
        case VIPS_FORMAT_CHAR:		
		CAST_CLIP( signed char, SCHAR_MIN, SCHAR_MAX ); 
		break;

        case VIPS_FORMAT_UCHAR:  	
		CAST_CLIP( unsigned char, 0, UCHAR_MAX ); 
		break;

        case VIPS_FORMAT_SHORT:  	
		CAST_CLIP( signed short, SCHAR_MIN, SCHAR_MAX ); 
		break;

        case VIPS_FORMAT_USHORT: 	
		CAST_CLIP( unsigned short, 0, USHRT_MAX ); 
		break;

        case VIPS_FORMAT_INT:    	
		CAST_CLIP( signed int, INT_MIN, INT_MAX ); 
		break;

        case VIPS_FORMAT_UINT:   	
		CAST_CLIP( unsigned int, 0, UINT_MAX ); 
		break;

        case VIPS_FORMAT_FLOAT: 		
		CAST( float ); 
		break; 

        case VIPS_FORMAT_DOUBLE:		
		CAST( double ); 
		break;

        case VIPS_FORMAT_COMPLEX: 	
		CASTC( float ); 
		break; 

        case VIPS_FORMAT_DPCOMPLEX:	
		CASTC( double ); 
		break;

        default:
                g_assert( 0 );
        }

	return( q );
}
Exemplo n.º 7
0
static int
mat2vips_get_data( mat_t *mat, matvar_t *var, VipsImage *im )
{
	int y;
	VipsPel *buffer;
	const int es = VIPS_IMAGE_SIZEOF_ELEMENT( im );

	/* Matlab images are plane-separate, so we have to assemble bands in
	 * image-size chunks.
	 */
	const guint64 is = es * VIPS_IMAGE_N_PELS( im );

	if( Mat_VarReadDataAll( mat, var ) ) {
		vips_error( "mat2vips", "%s", 
			_( "Mat_VarReadDataAll failed" ) );
		return( -1 );
	}

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

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

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

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

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

				q += es;
			}

			p += es * im->Ysize;
		}

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

	return( 0 );
}
Exemplo n.º 8
0
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsFits *fits;
	int status;

	status = 0;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = vips_strdup( VIPS_OBJECT( in ), filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = vips_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, VipsPel )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		vips_error( "fits", 
			_( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = vips_g_mutex_new();

	return( fits );
}
Exemplo n.º 9
0
/* Make a sequence value.
 */
static void *
vips_shrinkh_start( VipsImage *out, void *a, void *b )
{
	VipsImage *in = (VipsImage *) a;
	VipsShrinkhSequence *seq;

	if( !(seq = VIPS_NEW( out, VipsShrinkhSequence )) )
		return( NULL );

	seq->ir = vips_region_new( in );

	/* Big enough for the largest intermediate. 
	 */
	seq->sum = VIPS_ARRAY( out, 
		in->Bands * vips_format_sizeof( VIPS_FORMAT_DPCOMPLEX ),
		VipsPel );

	return( (void *) seq );
}
Exemplo n.º 10
0
/* Read an ascii ppm/pgm file.
 */
static int
read_ascii( FILE *fp, VipsImage *out )
{
	int x, y;
	VipsPel *buf;

	if( !(buf = VIPS_ARRAY( out, VIPS_IMAGE_SIZEOF_LINE( out ), VipsPel )) )
		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 VIPS_FORMAT_UCHAR:
				buf[x] = VIPS_CLIP( 0, val, 255 );
				break;

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

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

			default:
				g_assert( 0 );
			}
		}

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

	return( 0 );
}
Exemplo n.º 11
0
static Write *
write_new( VipsImage *in )
{
	Write *write;

	if( !(write = VIPS_NEW( in, Write )) )
		return( NULL );
	memset( write, 0, sizeof( Write ) );
	write->in = in;
	write->memory = NULL;
	write->fp = NULL;
	write->buf = NULL;
	write->len = 0;
	write->alloc = 0;
	g_signal_connect( in, "close", 
		G_CALLBACK( write_destroy ), write ); 

	if( !(write->row_pointer = VIPS_ARRAY( in, in->Ysize, png_bytep )) )
		return( NULL );
	if( !(write->pPng = png_create_write_struct( 
		PNG_LIBPNG_VER_STRING, NULL,
		user_error_function, user_warning_function )) ) 
		return( NULL );

#ifdef PNG_SKIP_sRGB_CHECK_PROFILE
	/* Prevent libpng (>=1.6.11) verifying sRGB profiles.
	 */
	png_set_option( write->pPng, 
		PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON );
#endif /*PNG_SKIP_sRGB_CHECK_PROFILE*/

	/* Catch PNG errors from png_create_info_struct().
	 */
	if( setjmp( png_jmpbuf( write->pPng ) ) ) 
		return( NULL );

	if( !(write->pInfo = png_create_info_struct( write->pPng )) ) 
		return( NULL );

	return( write );
}
Exemplo n.º 12
0
static void *
vips_rank_start( IMAGE *out, void *a, void *b )
{
	VipsImage *in = (VipsImage *) a;
	VipsRank *rank = (VipsRank *) b;
	VipsRankSequence *seq;

	if( !(seq = VIPS_NEW( out, VipsRankSequence )) )
		return( NULL );
	seq->ir = NULL;
	seq->sort = NULL;

	seq->ir = vips_region_new( in );
	if( !(seq->sort = VIPS_ARRAY( out, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * rank->n, VipsPel )) ) { 
		vips_rank_stop( seq, in, rank );
		return( NULL );
	}

	return( (void *) seq );
}
Exemplo n.º 13
0
/* Write a VIPS image to a JPEG compress struct.
 */
static int
write_vips( Write *write, int qfac, const char *profile, 
	gboolean optimize_coding, gboolean progressive, gboolean strip, 
	gboolean no_subsample, gboolean trellis_quant,
	gboolean overshoot_deringing, gboolean optimize_scans, int quant_table )
{
	VipsImage *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 == VIPS_FORMAT_UCHAR );
	g_assert( in->Coding == VIPS_CODING_NONE );
        g_assert( in->Bands == 1 || 
		in->Bands == 3 || 
		in->Bands == 4 );

        /* Check input image.
         */
	if( vips_image_pio_input( in ) )
		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 == VIPS_INTERPRETATION_CMYK ) {
		space = JCS_CMYK;
		/* IJG always sets an Adobe marker, so we should invert CMYK.
		 */
		if( vips_invert( in, &write->inverted, NULL ) ) 
			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 = VIPS_ARRAY( NULL, in->Ysize, JSAMPROW )) )
		return( -1 );

#ifdef HAVE_JPEG_EXT_PARAMS
	/* Reset compression profile to libjpeg defaults
	 */
	if( jpeg_c_int_param_supported( &write->cinfo, JINT_COMPRESS_PROFILE ) )
		jpeg_c_set_int_param( &write->cinfo, 
			JINT_COMPRESS_PROFILE, JCP_FASTEST );
#endif

	/* Reset to default.
	 */
        jpeg_set_defaults( &write->cinfo );

 	/* Compute optimal Huffman coding tables.
	 */
	write->cinfo.optimize_coding = optimize_coding;

#ifdef HAVE_JPEG_EXT_PARAMS
	/* Apply trellis quantisation to each 8x8 block. Implies 
	 * "optimize_coding".
	 */
	if( trellis_quant ) {
		if( jpeg_c_bool_param_supported( &write->cinfo, 
			JBOOLEAN_TRELLIS_QUANT ) ) {
			jpeg_c_set_bool_param( &write->cinfo,
				JBOOLEAN_TRELLIS_QUANT, TRUE );
			write->cinfo.optimize_coding = TRUE;
		}
		else 
			vips_warn( "vips2jpeg", 
				"%s", _( "trellis_quant unsupported" ) );
	}

	/* Apply overshooting to samples with extreme values e.g. 0 & 255 
	 * for 8-bit.
	 */
	if( overshoot_deringing ) {
		if( jpeg_c_bool_param_supported( &write->cinfo, 
			JBOOLEAN_OVERSHOOT_DERINGING ) ) 
			jpeg_c_set_bool_param( &write->cinfo,
				JBOOLEAN_OVERSHOOT_DERINGING, TRUE );
		else 
			vips_warn( "vips2jpeg", 
				"%s", _( "overshoot_deringing unsupported" ) );
	}
	/* Split the spectrum of DCT coefficients into separate scans.
	 * Requires progressive output. Must be set before 
	 * jpeg_simple_progression.
	 */
	if( optimize_scans ) {
		if( progressive ) {
			if( jpeg_c_bool_param_supported( &write->cinfo, 
				JBOOLEAN_OPTIMIZE_SCANS ) ) 
				jpeg_c_set_bool_param( &write->cinfo, 
					JBOOLEAN_OPTIMIZE_SCANS, TRUE );
			else 
				vips_warn( "vips2jpeg", 
					"%s", _( "Ignoring optimize_scans" ) );
		}
		else 
			vips_warn( "vips2jpeg", "%s",
				_( "Ignoring optimize_scans for baseline" ) );
	}

	/* Use predefined quantization table.
	 */
	if( quant_table > 0 ) {
		if( jpeg_c_int_param_supported( &write->cinfo,
			JINT_BASE_QUANT_TBL_IDX ) )
			jpeg_c_set_int_param( &write->cinfo,
				JINT_BASE_QUANT_TBL_IDX, quant_table );
		else
			vips_warn( "vips2jpeg",
				"%s", _( "Setting quant_table unsupported" ) );
	}
#else
	/* Using jpeglib.h without extension parameters, warn of ignored 
	 * options.
	 */
	if( trellis_quant ) 
		vips_warn( "vips2jpeg", "%s", _( "Ignoring trellis_quant" ) );
	if( overshoot_deringing ) 
		vips_warn( "vips2jpeg", 
			"%s", _( "Ignoring overshoot_deringing" ) );
	if( optimize_scans ) 
		vips_warn( "vips2jpeg", "%s", _( "Ignoring optimize_scans" ) );
	if( quant_table > 0 )
		vips_warn( "vips2jpeg", "%s", _( "Ignoring quant_table" ) );
#endif

	/* Set compression quality. Must be called after setting params above.
	 */
        jpeg_set_quality( &write->cinfo, qfac, TRUE );

	/* Enable progressive write.
	 */
	if( progressive ) 
		jpeg_simple_progression( &write->cinfo ); 

	/* Turn off chroma subsampling. Follow IM and do it automatically for
	 * high Q. 
	 */
	if( no_subsample ||
		qfac > 90 ) { 
		int i;

		for( i = 0; i < in->Bands; i++ ) { 
			write->cinfo.comp_info[i].h_samp_factor = 1;
			write->cinfo.comp_info[i].v_samp_factor = 1;
		}
	}

	/* Don't write the APP0 JFIF headers if we are stripping.
	 */
	if( strip ) 
		write->cinfo.write_JFIF_header = FALSE;

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

	/* Write any APP markers we need.
	 */
	if( !strip ) { 
		if( write_exif( write ) ||
			write_blob( write, 
				VIPS_META_XMP_NAME, JPEG_APP0 + 1 ) ||
			write_blob( write, 
				VIPS_META_IPCT_NAME, JPEG_APP0 + 13 ) )
			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 && 
			vips_image_get_typeof( in, VIPS_META_ICC_NAME ) && 
			write_profile_meta( write ) )
			return( -1 );
	}

	/* Write data. Note that the write function grabs the longjmp()!
	 */
	if( vips_sink_disc( 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 );
}
Exemplo n.º 14
0
/* This can work inplace, ie. in == out is allowed.
 */
static void
vips_rot45_rot45( VipsImage *out, VipsImage *in )
{
	size_t ps = VIPS_IMAGE_SIZEOF_PEL( in ); 
	VipsPel *temp = VIPS_ARRAY( in, ps, VipsPel ); 
	int size = in->Xsize; 
	int size_2 = size / 2;

	int x, y;

	g_assert( in->Xsize == in->Ysize ); 
	g_assert( out->Xsize == out->Ysize ); 
	g_assert( in->Xsize == out->Xsize ); 
	g_assert( in->Xsize % 2 == 1 );

	/* Split the square into 8 triangles. Loop over the top-left one,
	 * reflect to index the others.
	 *
	 * 	1 1 2 2 3
	 * 	8 1 2 3 3
	 * 	8 8 x 4 4
	 * 	7 7 6 5 4
	 * 	7 6 6 5 5 
	 *
	 * do the centre separately.
	 */

	for( y = 0; y < size_2; y++ )  
		for( x = y; x < size_2; x++ ) {
			/* Save 1, it goes into 2 at the end.
			 */
			POINT_TO_TEMP( temp, x, y ); 

			/* Fill 1 from 8.
			 */
			ASSIGN( x, y, 
				y, size_2 - (x - y) );

			/* 8 from 7.
			 */
			ASSIGN( y, size_2 - (x - y),
				y, (size - 1) - x ); 

			/* 7 from 6.
			 */
			ASSIGN( y, (size - 1) - x,
				size_2 - (x - y), (size - 1) - y );

			/* 6 from 5.
			 */
			ASSIGN( size_2 - (x - y), (size - 1) - y,
				(size - 1) - x, (size - 1) - y ); 

			/* 5 from 4. 
			 */
			ASSIGN( (size - 1) - x, (size - 1) - y,
				(size - 1) - y, (x - y) + size_2 );

			/* 4 from 3. 
			 */
			ASSIGN( (size - 1) - y, (x - y) + size_2,
				(size - 1) - y, x );

			/* 3 from 2.
			 */
			ASSIGN( (size - 1) - y, x,
				(x - y) + size_2, y );

			/* 2 from saved 1. 
			 */
			TEMP_TO_POINT( (x - y) + size_2, y, temp ); 
		}

	/* Centre.
	 */
	ASSIGN( size_2, size_2, size_2, size_2 ); 
}
Exemplo n.º 15
0
static VipsFits *
vips_fits_new_write( VipsImage *in, const char *filename )
{
	VipsImage *flip;
	VipsImage *type;
	VipsFits *fits;
	int status;

	status = 0;

	if( im_check_noncomplex( "im_vips2fits", in ) ||
		im_check_uncoded( "im_vips2fits", in ) )
		return( NULL );

	/* Cast to a supported format.
	 */
	if( !(type = vips_image_new()) ||
		vips_object_local( in, type ) ||
		im_clip2fmt( in, type, vips_fits_bandfmt[in->BandFmt] ) )
		return( NULL );
	in = type;

	/* FITS has (0,0) in the bottom left, we need to flip.
	 */
	if( !(flip = vips_image_new()) ||
		vips_object_local( in, flip ) ||
		im_flipver( in, flip ) )
		return( NULL );
	in = flip;

	if( !(fits = VIPS_NEW( in, VipsFits )) )
		return( NULL );
	fits->filename = im_strdup( NULL, filename );
	fits->image = in;
	fits->fptr = NULL;
	fits->lock = NULL;
	fits->band_select = -1;
	fits->buffer = NULL;
	g_signal_connect( in, "close", 
		G_CALLBACK( vips_fits_close_cb ), fits );

	if( !(fits->filename = im_strdup( NULL, filename )) )
		return( NULL );

	/* We need to be able to hold one scanline of one band.
	 */
	if( !(fits->buffer = VIPS_ARRAY( NULL, 
		VIPS_IMAGE_SIZEOF_ELEMENT( in ) * in->Xsize, PEL )) )
		return( NULL );

	/* fits_create_file() will fail if there's a file of thet name, unless
	 * we put a "!" in front ofthe filename. This breaks conventions with
	 * the rest of vips, so just unlink explicitly.
	 */
	g_unlink( filename );

	if( fits_create_file( &fits->fptr, filename, &status ) ) {
		im_error( "fits", _( "unable to write to \"%s\"" ), filename );
		vips_fits_error( status );
		return( NULL );
	}

	fits->lock = g_mutex_new();

	return( fits );
}
Exemplo n.º 16
0
/* Calculate a pixel for an image from a vec of double. Valid while im is
 * valid. imag can be NULL, meaning all zero for the imaginary component.
 */
VipsPel *
vips__vector_to_ink( const char *domain, 
	VipsImage *im, double *real, double *imag, int n )
{
	/* Run our pipeline relative to this.
	 */
	VipsImage *context = vips_image_new(); 

	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( context ), 6 );

	VipsBandFormat format;
	int bands; 
	double *ones;
	VipsPel *result;
	int i;

#ifdef VIPS_DEBUG
	printf( "vips__vector_to_ink: starting\n" );
#endif /*VIPS_DEBUG*/

	vips_image_decode_predict( im, &bands, &format );
	ones = VIPS_ARRAY( im, n, double );
	for( i = 0; i < n; i++ )
		ones[i] = 1.0;

	/* Cast vec to match the decoded image.
	 */
	if( vips_black( &t[1], 1, 1, "bands", bands, NULL ) ||
		vips_linear( t[1], &t[2], ones, real, n, NULL ) || 
		vips_cast( t[2], &t[3], format, NULL ) ) {
		g_object_unref( context );
		return( NULL );
	}

	/* And now recode the vec to match the original im.
	 */
	if( vips_image_encode( t[3], &t[4], im->Coding ) || 
		!(t[5] = vips_image_new_memory()) ||
		vips_image_write( t[4], t[5] ) ) {
		g_object_unref( context );
		return( NULL );
	}

	if( !(result = 
		VIPS_ARRAY( im, VIPS_IMAGE_SIZEOF_PEL( t[5] ), VipsPel )) ) {
		g_object_unref( context );
		return( NULL );
	}

	g_assert( VIPS_IMAGE_SIZEOF_PEL( t[5] ) == 
		VIPS_IMAGE_SIZEOF_PEL( im ) ); 

	memcpy( result, t[5]->data, VIPS_IMAGE_SIZEOF_PEL( im ) ); 

	g_object_unref( context );

#ifdef VIPS_DEBUG
{
	int i;

	printf( "vips__vector_to_ink:\n" );
	printf( "\t(real, imag) = " ); 
	for( i = 0; i < n; i++ )
		printf( "(%g, %g) ", real[i], imag ? imag[i] : 0 );
	printf( "\n" ); 
	printf( "\tink = " ); 
	for( i = 0; i < VIPS_IMAGE_SIZEOF_PEL( im ); i++ )
		printf( "%d ", result[i] );
	printf( "\n" ); 
}
#endif /*VIPS_DEBUG*/

	return( result ); 
}
Exemplo n.º 17
0
/* Make a pair of vector constants into a set of formatted pixels. bands can
 * be 3 while n is 1, meaning expand the constant to the number of bands. 
 * imag can be NULL, meaning all zero for the imaginary component.
 */
VipsPel *
vips__vector_to_pels( const char *domain, 
	int bands, VipsBandFormat format, VipsCoding coding, 
	double *real, double *imag, int n )
{
	/* Run our pipeline relative to this.
	 */
	VipsImage *context = vips_image_new(); 

	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( context ), 8 );

	VipsImage *in;
	double *ones;
	VipsPel *result;
	int i;

#ifdef VIPS_DEBUG
	printf( "vips__vector_to_pels: starting\n" );
#endif /*VIPS_DEBUG*/

	ones = VIPS_ARRAY( context, n, double );
	for( i = 0; i < n; i++ )
		ones[i] = 1.0;

	/* Make the real and imaginary parts.
	 */
	if( vips_black( &t[0], 1, 1, "bands", bands, NULL ) ||
		vips_linear( t[0], &t[1], ones, real, n, NULL ) ) {
		g_object_unref( context );
		return( NULL );
	}
	in = t[1];

	if( imag ) { 
		if( vips_black( &t[2], 1, 1, "bands", bands, NULL ) ||
			vips_linear( t[2], &t[3], ones, imag, n, NULL ) ||
			vips_complexform( in, t[3], &t[4], NULL ) ) {
			g_object_unref( context );
			return( NULL );
		}
		in = t[4];
	}

	/* Cast to the output type and coding. 
	 */
	if( vips_cast( in, &t[5], format, NULL ) ||
		vips_image_encode( t[5], &t[6], coding ) ) {
		g_object_unref( context );
		return( NULL );
	}
	in = t[6];

	/* Write to memory, copy to output buffer. 
	 */
	if( !(t[7] = vips_image_new_memory()) ||
		vips_image_write( in, t[7] ) ) {
		g_object_unref( context );
		return( NULL );
	}
	in = t[7];

	if( !(result = 
		VIPS_ARRAY( NULL, VIPS_IMAGE_SIZEOF_PEL( in ), VipsPel )) ) {
		g_object_unref( context );
		return( NULL );
	}

	memcpy( result, in->data, VIPS_IMAGE_SIZEOF_PEL( in ) ); 

#ifdef VIPS_DEBUG
{
	int i;

	printf( "vips__vector_to_ink:\n" );
	printf( "\t(real, imag) = " ); 
	for( i = 0; i < n; i++ )
		printf( "(%g, %g) ", real[i], imag ? imag[i] : 0 );
	printf( "\n" ); 
	printf( "\tink = " ); 
	for( i = 0; i < VIPS_IMAGE_SIZEOF_PEL( in ); i++ )
		printf( "%d ", result[i] );
	printf( "\n" ); 
}
#endif /*VIPS_DEBUG*/

	g_object_unref( context );

	return( result ); 
}