Esempio n. 1
0
/* The inverse: take ink to a vec of double. Used in the vips7 compat
 * wrappers. Result valid while im is valid. 
 */
double *
vips__ink_to_vector( const char *domain, VipsImage *im, VipsPel *ink, int *n )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( im ), 6 );

	double *result;

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

	/* Wrap a VipsImage around ink.
	 */
	t[0] = vips_image_new_from_memory( ink, 
		1, 1, VIPS_IMAGE_SIZEOF_PEL( im ), VIPS_FORMAT_UCHAR );
	if( vips_copy( t[0], &t[1], 
		"bands", im->Bands, 
		"format", im->BandFmt, 
		"coding", im->Coding, 
		"interpretation", im->Type, 
		NULL ) )
		return( NULL ); 

	/* The image may be coded .. unpack to double.
	 */
	if( vips_image_decode( t[1], &t[2] ) ||
		vips_cast( t[2], &t[3], VIPS_FORMAT_DOUBLE, NULL ) )
		return( NULL );

	/* To a mem buffer, then copy to out. 
	 */
	if( !(t[4] = vips_image_new_memory()) ||
		vips_image_write( t[3], t[4] ) )
		return( NULL ); 

	if( !(result = VIPS_ARRAY( im, t[4]->Bands, double )) )
		return( NULL ); 
	memcpy( result, t[4]->data, VIPS_IMAGE_SIZEOF_PEL( t[4] ) ); 
	*n = t[4]->Bands; 

#ifdef VIPS_DEBUG
{
	int i;

	printf( "vips__ink_to_vector:\n" );
	printf( "\tink = " ); 
	for( i = 0; i < n; i++ )
		printf( "%d ", ink[i] );
	printf( "\n" ); 

	printf( "\tvec = " ); 
	for( i = 0; i < *n; i++ )
		printf( "%d ", result[i] );
	printf( "\n" ); 
}
#endif /*VIPS_DEBUG*/

	return( result ); 
}
Esempio n. 2
0
static int
vips_RGB162sRGB( VipsImage *in, VipsImage **out, ... )
{
	if( vips_cast( in, out, VIPS_FORMAT_UCHAR,
		"shift", TRUE,
		NULL ) )
		return( -1 );
	(*out)->Type = VIPS_INTERPRETATION_sRGB;

	return( 0 ); 
}
Esempio n. 3
0
static int
vips_ifthenelse_build( VipsObject *object )
{
	VipsConversion *conversion = VIPS_CONVERSION( object );
	VipsIfthenelse *ifthenelse = (VipsIfthenelse *) object;

	VipsImage *all[3];
	VipsImage **band = (VipsImage **) vips_object_local_array( object, 3 );
	VipsImage **size = (VipsImage **) vips_object_local_array( object, 3 );
	VipsImage **format = 
		(VipsImage **) vips_object_local_array( object, 3 );

	if( VIPS_OBJECT_CLASS( vips_ifthenelse_parent_class )->build( object ) )
		return( -1 );

	/* We have to have the condition image last since we want the output
	 * image to inherit its properties from the then/else parts.
	 */
	all[0] = ifthenelse->in1;
	all[1] = ifthenelse->in2;
	all[2] = ifthenelse->cond;

	/* No need to check input images, sizealike and friends will do this
	 * for us.
	 */

	/* Cast our input images up to a common bands and size.
	 */
	if( vips__bandalike_vec( "VipsIfthenelse", all, band, 3, 0 ) ||
		vips__sizealike_vec( band, size, 3 ) )
		return( -1 );

	/* Condition is cast to uchar, then/else to a common type.
	 */
	if( vips_cast( size[2], &format[2], VIPS_FORMAT_UCHAR, NULL ) )
		return( -1 );
	if( vips__formatalike_vec( size, format, 2 ) ) 
		return( -1 ); 

	if( vips_image_copy_fields_array( conversion->out, format ) )
		return( -1 );
        vips_demand_hint_array( conversion->out, 
		VIPS_DEMAND_STYLE_SMALLTILE, format );

	if( vips_image_generate( conversion->out,
		vips_start_many, vips_ifthenelse_gen, vips_stop_many, 
		format, ifthenelse ) )
		return( -1 );

	return( 0 );
}
Esempio n. 4
0
static int
vips_labelregions_build( VipsObject *object )
{
	VipsMorphology *morphology = VIPS_MORPHOLOGY( object );
	VipsImage *in = morphology->in;
	VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );
	VipsImage *mask;

	int segments;
	int *m;
	int x, y;

	if( VIPS_OBJECT_CLASS( vips_labelregions_parent_class )->
		build( object ) )
		return( -1 );

	/* Create the zero mask image in memory.
	 */
	mask = vips_image_new_memory();
	g_object_set( object,
		"mask", mask,
		NULL ); 
	if( vips_black( &t[0], in->Xsize, in->Ysize, NULL ) ||
		vips_cast( t[0], &t[1], VIPS_FORMAT_INT, NULL ) || 
		vips_image_write( t[1], mask ) )
		return( -1 );

	segments = 1;
	m = (int *) mask->data;
	for( y = 0; y < mask->Ysize; y++ ) {
		for( x = 0; x < mask->Xsize; x++ ) {
			if( !m[x] ) {
				/* Use a direct path for speed.
				 */
				if( vips__draw_flood_direct( mask, in, 
					segments, x, y ) )
					return( -1 ); 

				segments += 1;
			}
		}

		m += mask->Xsize;
	}

	g_object_set( object,
		"segments", segments,
		NULL ); 

	return( 0 );
}
Esempio n. 5
0
static int
vips_freqmult_build( VipsObject *object )
{
	VipsFreqfilt *freqfilt = VIPS_FREQFILT( object );
	VipsFreqmult *freqmult = (VipsFreqmult *) object;
	VipsImage **t = (VipsImage **) vips_object_local_array( object, 5 );

	VipsImage *in;

	if( VIPS_OBJECT_CLASS( vips_freqmult_parent_class )->
		build( object ) )
		return( -1 );

	in = freqfilt->in;

	if( vips_band_format_iscomplex( in->BandFmt ) ) {
		if( vips_multiply( in, freqmult->mask, &t[0], NULL ) ||
			vips_invfft( t[0], &t[1], "real", TRUE, NULL ) ) 
			return( -1 );

		in = t[1];
	}
	else {
		/* Optimisation: output of vips_invfft() is double, we 
		 * will usually cast to char, so rather than keeping a
		 * large double buffer and partial to char from that, 
		 * cast to a memory buffer and copy to out from that.
		 *
		 * FIXME does this actually work now we're a class? test
		 * perhaps we need a temporary object
		 */
		t[4] = vips_image_new_memory();

		if( vips_fwfft( in, &t[0], NULL ) ||
			vips_multiply( t[0], freqmult->mask, &t[1], NULL ) ||
			vips_invfft( t[1], &t[2], "real", TRUE, NULL ) ||
			vips_cast( t[2], &t[3], in->BandFmt, NULL ) ||
			vips_image_write( t[3], t[4] ) )
			return( -1 );

		in = t[4]; 
	}

	if( vips_image_write( in, freqfilt->out ) )
		return( -1 );

	return( 0 );
}
Esempio n. 6
0
static int
vips_recomb_build( VipsObject *object )
{
	VipsConversion *conversion = (VipsConversion *) object;
	VipsRecomb *recomb = (VipsRecomb *) object;
	VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );

	if( VIPS_OBJECT_CLASS( vips_recomb_parent_class )->build( object ) )
		return( -1 );

	if( vips_image_pio_input( recomb->in ) || 
		vips_check_uncoded( "VipsRecomb", recomb->in ) ||
		vips_check_noncomplex( "VipsRecomb", recomb->in ) )
		return( -1 );
	if( vips_image_pio_input( recomb->m ) || 
		vips_check_uncoded( "VipsRecomb", recomb->m ) ||
		vips_check_noncomplex( "VipsRecomb", recomb->m ) ||
		vips_check_mono( "VipsRecomb", recomb->m ) )
		return( -1 );
	if( recomb->in->Bands != recomb->m->Xsize ) {
		vips_error( "VipsRecomb", 
			"%s", _( "bands in must equal matrix width" ) );
		return( -1 );
	}

	if( vips_cast( recomb->m, &t[0], VIPS_FORMAT_DOUBLE, NULL ) ||
		vips_image_wio_input( t[0] ) )
		return( -1 );
	recomb->coeff = (double *) VIPS_IMAGE_ADDR( t[0], 0, 0 );

	if( vips_image_copy_fields( conversion->out, recomb->in ) )
		return( -1 );
        vips_demand_hint( conversion->out, 
		VIPS_DEMAND_STYLE_THINSTRIP, recomb->in, NULL );

	conversion->out->Bands = recomb->m->Ysize;
	if( vips_bandfmt_isint( recomb->in->BandFmt ) ) 
		conversion->out->BandFmt = VIPS_FORMAT_FLOAT;

	if( vips_image_generate( conversion->out,
		vips_start_one, vips_recomb_gen, vips_stop_one, 
		recomb->in, recomb ) )
		return( -1 );

	return( 0 );
}
Esempio n. 7
0
int
vips__formatalike_vec( VipsImage **in, VipsImage **out, int n )
{
    int i;
    VipsBandFormat format;

    g_assert( n >= 1 );

    format = in[0]->BandFmt;
    for( i = 1; i < n; i++ )
        format = vips_format_common( format, in[i]->BandFmt );

    for( i = 0; i < n; i++ )
        if( vips_cast( in[i], &out[i], format, NULL ) )
            return( -1 );

    return( 0 );
}
Esempio n. 8
0
/** 
 * vips_check_matrix: 
 * @domain: the originating domain for the error message
 * @im: image to check 
 * @out: put image as in-memory doubles here
 *
 * Matrix images must have width and height less than 1000 and have 1 band.
 *
 * Return 0 if the image will pass as a matrix, or -1 and set an error 
 * message otherwise.
 *
 * @out is set to be @im cast to double and stored in memory. Use
 * VIPS_IMAGE_ADDR() to address values in @out. @out is unreffed for you 
 * when @im is unreffed.
 *
 * See also: vips_error().
 *
 * Returns: 0 if OK, -1 otherwise.
 */
int
vips_check_matrix( const char *domain, VipsImage *im, VipsImage **out )
{
	if( im->Xsize > 1000 || im->Ysize > 1000 ) {
		vips_error( domain, "%s", _( "matrix image too large" ) );
		return( -1 );
	}
	if( im->Bands != 1 ) {
		vips_error( domain, 
			"%s", _( "matrix image must have one band" ) ); 
		return( -1 );
	}

	if( vips_cast( im, out, VIPS_FORMAT_DOUBLE, NULL ) )
                return( -1 );
	vips_object_local( im, *out );
        if( vips_image_wio_input( *out ) )
                return( -1 );

	return( 0 );
}
Esempio n. 9
0
static int
vips_statistic_build( VipsObject *object )
{
	VipsStatistic *statistic = VIPS_STATISTIC( object );
	VipsStatisticClass *sclass = VIPS_STATISTIC_GET_CLASS( statistic );
	VipsImage **t = (VipsImage **) vips_object_local_array( object, 2 );

#ifdef DEBUG
	printf( "vips_statistic_build: " );
	vips_object_print_name( object );
	printf( "\n" );
#endif /*DEBUG*/

	if( VIPS_OBJECT_CLASS( vips_statistic_parent_class )->build( object ) )
		return( -1 );

	statistic->ready = statistic->in;

	if( vips_image_decode( statistic->ready, &t[0] ) )
		return( -1 );
	statistic->ready = t[0];

	/* If there's a format table, cast the input.
	 */
	if( sclass->format_table ) {
		if( vips_cast( statistic->ready, &t[1], 
			sclass->format_table[statistic->in->BandFmt], NULL ) )
			return( -1 );
		statistic->ready = t[1];
	}

	if( vips_sink( statistic->ready, 
		vips_statistic_scan_start, 
		vips_statistic_scan, 
		vips_statistic_scan_stop, 
		statistic, NULL ) )
		return( -1 );

	return( 0 );
}
Esempio n. 10
0
/* Process the first @n bands with @fn, detach and reattach remaining bands.
 */
static int
vips_process_n( const char *domain, VipsImage *in, VipsImage **out, 
	int n, VipsColourTransformFn fn )
{
	if( in->Bands > n ) {
		VipsImage *scope = vips_image_new();
		VipsImage **t = (VipsImage **) 
			vips_object_local_array( VIPS_OBJECT( scope ), 4 );

		if( vips_extract_band( in, &t[0], 0,
			"n", n, 
			NULL ) ||
			vips_extract_band( in, &t[1], n,
				"n", in->Bands - n, 
				NULL ) ||
			fn( t[0], &t[2], NULL ) ||
			vips_cast( t[1], &t[3], t[2]->BandFmt, 
				NULL ) ||
			vips_bandjoin2( t[2], t[3], out, NULL ) ) {
			g_object_unref( scope );
			return( -1 );
		}

		g_object_unref( scope );
	}
	else if( in->Bands == n ) {
		if( fn( in, out, NULL ) )
			return( -1 );
	}
	else {
		vips_error( domain, "%s", _( "too few bands for operation" ) ); 
		return( -1 );
	}

	return( 0 );
}
Esempio n. 11
0
static VipsImage *
thumbnail_shrink( VipsObject *process, VipsImage *in )
{
	VipsImage **t = (VipsImage **) vips_object_local_array( process, 10 );
	VipsInterpretation interpretation = linear_processing ?
		VIPS_INTERPRETATION_XYZ : VIPS_INTERPRETATION_sRGB; 

	/* TRUE if we've done the import of an ICC transform and still need to
	 * export.
	 */
	gboolean have_imported;

	/* TRUE if we've premultiplied and need to unpremultiply.
	 */
	gboolean have_premultiplied;
	VipsBandFormat unpremultiplied_format;

	/* Sniff the incoming image and try to guess what the alpha max is.
	 */
	double max_alpha;

	double shrink; 

	/* RAD needs special unpacking.
	 */
	if( in->Coding == VIPS_CODING_RAD ) {
		vips_info( "vipsthumbnail", "unpacking Rad to float" );

		/* rad is scrgb.
		 */
		if( vips_rad2float( in, &t[0], NULL ) )
			return( NULL );
		in = t[0];
	}

	/* Try to guess what the maximum alpha might be.
	 */
	max_alpha = 255;
	if( in->BandFmt == VIPS_FORMAT_USHORT )
		max_alpha = 65535;

	/* In linear mode, we import right at the start. 
	 *
	 * We also have to import the whole image if it's CMYK, since
	 * vips_colourspace() (see below) doesn't know about CMYK.
	 *
	 * This is only going to work for images in device space. If you have
	 * an image in PCS which also has an attached profile, strange things
	 * will happen. 
	 */
	have_imported = FALSE;
	if( (linear_processing ||
		in->Type == VIPS_INTERPRETATION_CMYK) &&
		in->Coding == VIPS_CODING_NONE &&
		(in->BandFmt == VIPS_FORMAT_UCHAR ||
		 in->BandFmt == VIPS_FORMAT_USHORT) &&
		(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) || 
		 import_profile) ) {
		if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) )
			vips_info( "vipsthumbnail", 
				"importing with embedded profile" );
		else
			vips_info( "vipsthumbnail", 
				"importing with profile %s", import_profile );

		if( vips_icc_import( in, &t[1], 
			"input_profile", import_profile,
			"embedded", TRUE,
			"pcs", VIPS_PCS_XYZ,
			NULL ) )  
			return( NULL );

		in = t[1];

		have_imported = TRUE;
	}

	/* To the processing colourspace. This will unpack LABQ as well.
	 */
	vips_info( "vipsthumbnail", "converting to processing space %s",
		vips_enum_nick( VIPS_TYPE_INTERPRETATION, interpretation ) ); 
	if( vips_colourspace( in, &t[2], interpretation, NULL ) ) 
		return( NULL ); 
	in = t[2];

	/* If there's an alpha, we have to premultiply before shrinking. See
	 * https://github.com/jcupitt/libvips/issues/291
	 */
	have_premultiplied = FALSE;
	if( in->Bands == 2 ||
		(in->Bands == 4 && in->Type != VIPS_INTERPRETATION_CMYK) ||
		in->Bands == 5 ) {
		vips_info( "vipsthumbnail", "premultiplying alpha" ); 
		if( vips_premultiply( in, &t[3], 
			"max_alpha", max_alpha,
			NULL ) ) 
			return( NULL );
		have_premultiplied = TRUE;

		/* vips_premultiply() makes a float image. When we
		 * vips_unpremultiply() below, we need to cast back to the
		 * pre-premultiply format.
		 */
		unpremultiplied_format = in->BandFmt;
		in = t[3];
	}

	shrink = calculate_shrink( in );

	if( vips_resize( in, &t[4], 1.0 / shrink, NULL ) ) 
		return( NULL );
	in = t[4];

	if( have_premultiplied ) {
		vips_info( "vipsthumbnail", "unpremultiplying alpha" ); 
		if( vips_unpremultiply( in, &t[5], 
			"max_alpha", max_alpha,
			NULL ) || 
			vips_cast( t[5], &t[6], unpremultiplied_format, NULL ) )
			return( NULL );
		in = t[6];
	}

	/* Colour management.
	 *
	 * If we've already imported, just export. Otherwise, we're in 
	 * device space and we need a combined import/export to transform to 
	 * the target space.
	 */
	if( have_imported ) { 
		if( export_profile ||
			vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
			vips_info( "vipsthumbnail", 
				"exporting to device space with a profile" );
			if( vips_icc_export( in, &t[7], 
				"output_profile", export_profile,
				NULL ) )  
				return( NULL );
			in = t[7];
		}
		else {
			vips_info( "vipsthumbnail", "converting to sRGB" );
			if( vips_colourspace( in, &t[7], 
				VIPS_INTERPRETATION_sRGB, NULL ) ) 
				return( NULL ); 
			in = t[7];
		}
	}
	else if( export_profile &&
		(vips_image_get_typeof( in, VIPS_META_ICC_NAME ) || 
		 import_profile) ) {
		VipsImage *out;

		vips_info( "vipsthumbnail", 
			"exporting with profile %s", export_profile );

		/* We first try with the embedded profile, if any, then if
		 * that fails try again with the supplied fallback profile.
		 */
		out = NULL; 
		if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
			vips_info( "vipsthumbnail", 
				"importing with embedded profile" );

			if( vips_icc_transform( in, &t[7], export_profile,
				"embedded", TRUE,
				NULL ) ) {
				vips_warn( "vipsthumbnail", 
					_( "unable to import with "
						"embedded profile: %s" ),
					vips_error_buffer() );

				vips_error_clear();
			}
			else
				out = t[7];
		}

		if( !out &&
			import_profile ) { 
			vips_info( "vipsthumbnail", 
				"importing with fallback profile" );

			if( vips_icc_transform( in, &t[7], export_profile,
				"input_profile", import_profile,
				"embedded", FALSE,
				NULL ) )  
				return( NULL );

			out = t[7];
		}

		/* If the embedded profile failed and there's no fallback or
		 * the fallback failed, out will still be NULL.
		 */
		if( out )
			in = out;
	}

	if( delete_profile &&
		vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
		vips_info( "vipsthumbnail", 
			"deleting profile from output image" );
		if( !vips_image_remove( in, VIPS_META_ICC_NAME ) ) 
			return( NULL );
	}

	return( in );
}
Esempio n. 12
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 ); 
}
Esempio n. 13
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 ); 
}
Esempio n. 14
0
static int
vips_histogram_build( VipsObject *object )
{
	VipsHistogram *histogram = VIPS_HISTOGRAM( object );
	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( object );
	VipsHistogramClass *hclass = VIPS_HISTOGRAM_GET_CLASS( histogram );

	VipsImage **decode;
	VipsImage **format;
	VipsImage **band;
	VipsImage **size;
	VipsImage **memory;

	VipsPel *outbuf;		
	VipsPel **inbuf;		
	int i;

#ifdef DEBUG
	printf( "vips_histogram_build: " );
	vips_object_print_name( object );
	printf( "\n" );
#endif /*DEBUG*/

	if( VIPS_OBJECT_CLASS( vips_histogram_parent_class )->build( object ) )
		return( -1 );

	g_assert( histogram->n > 0 ); 

	/* Must be NULL-terminated.
	 */
	g_assert( !histogram->in[histogram->n] ); 

	decode = (VipsImage **) vips_object_local_array( object, histogram->n );
	format = (VipsImage **) vips_object_local_array( object, histogram->n );
	band = (VipsImage **) vips_object_local_array( object, histogram->n );
	size = (VipsImage **) vips_object_local_array( object, histogram->n );
	memory = (VipsImage **) vips_object_local_array( object, histogram->n );

	g_object_set( histogram, "out", vips_image_new(), NULL ); 

	for( i = 0; i < histogram->n; i++ ) 
		if( vips_image_decode( histogram->in[i], &decode[i] ) ||
			vips_check_hist( class->nickname, decode[i] ) )
			return( -1 ); 

	/* Cast our input images up to a common format, bands and size. If
	 * input_format is set, cast to a fixed input type.
	 */
	if( hclass->input_format != VIPS_FORMAT_NOTSET ) {
		for( i = 0; i < histogram->n; i++ ) 
			if( vips_cast( decode[i], &format[i],
				hclass->input_format, NULL ) )
				return( -1 ); 
	}
	else {
		if( vips__formatalike_vec( decode, format, histogram->n ) )
			return( -1 );
	}
		
	if( vips__bandalike_vec( class->nickname, 
		format, band, histogram->n, 1 ) ||
		vips__hist_sizealike_vec( band, size, histogram->n ) ) 
		return( -1 );

	if( vips_image_pipeline_array( histogram->out, 
		VIPS_DEMAND_STYLE_THINSTRIP, size ) ) 
		return( -1 );

	/* Need a copy of the inputs in memory.
	 */
	if( !(inbuf = VIPS_ARRAY( object, histogram->n + 1, VipsPel * )) )
                return( -1 );
	for( i = 0; i < histogram->n; i++ ) {
		if( !(memory[i] = vips_image_copy_memory( size[i] )) )
			return( -1 ); 
		inbuf[i] = VIPS_IMAGE_ADDR( memory[i], 0, 0 );
	}
	inbuf[i] = NULL; 

	/* Keep a copy of the memory images here for subclasses.
	 */
	histogram->ready = memory;

	histogram->out->Xsize = VIPS_IMAGE_N_PELS( histogram->ready[0] );
	histogram->out->Ysize = 1;
	if( hclass->format_table ) 
		histogram->out->BandFmt = 
			hclass->format_table[histogram->ready[0]->BandFmt];
	histogram->out->Type = VIPS_INTERPRETATION_HISTOGRAM;

	if( !(outbuf = vips_malloc( object, 
		VIPS_IMAGE_SIZEOF_LINE( histogram->out ))) )
                return( -1 );

	hclass->process( histogram, outbuf, inbuf, histogram->ready[0]->Xsize );

	if( vips_image_write_line( histogram->out, 0, outbuf ) )
		return( -1 ); 

	return( 0 );
}