Exemplo n.º 1
0
/**
 * vips_image_get_data:
 * @image: image to get data for
 *
 * Return a pointer to the image's pixel data, if possible. This can involve
 * allocating large amounts of memory and performing a long computation. Image
 * pixels are laid out in band-packed rows.
 *
 * Since this function modifies @image, it is not threadsafe. Only call it on
 * images which you are sure have not been shared with another thread. 
 *
 * See also: vips_image_wio_input(), vips_image_copy_memory().
 *
 * Returns: (transfer none): a pointer to pixel data, if possible.
 */
const void *
vips_image_get_data( VipsImage *image )
{
	if( vips_image_wio_input( image ) )
		return( NULL );

	return( image->data ); 
}
Exemplo n.º 2
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 );
}
Exemplo n.º 3
0
int
vips__csv_write( VipsImage *in, const char *filename, const char *separator )
{
	FILE *fp;

	if( vips_check_mono( "vips2csv", in ) ||
		vips_check_uncoded( "vips2csv", in ) ||
		vips_image_wio_input( in ) )
		return( -1 );

	if( !(fp = vips__file_open_write( filename, TRUE )) ) 
		return( -1 );
	if( vips2csv( in, fp, separator ) ) {
		fclose( fp );
		return( -1 );
	}
	fclose( fp );

	return( 0 );
}
Exemplo n.º 4
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 );
}
Exemplo n.º 5
0
int
vips__webp_write_buffer( VipsImage *in, void **obuf, size_t *olen,
                         int Q, gboolean lossless )
{
    webp_encoder encoder;

    if( vips_image_wio_input( in ) )
        return( -1 );

    if( in->Bands == 4 )
        encoder = WebPEncodeRGBA;
    else
        encoder = WebPEncodeRGB;

    if( !(*olen = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ),
                           in->Xsize, in->Ysize,
                           VIPS_IMAGE_SIZEOF_LINE( in ),
                           Q, (uint8_t **) obuf )) ) {
        vips_error( "vips2webp", "%s", _( "unable to encode" ) );
        return( -1 );
    }

    return( 0 );
}
Exemplo n.º 6
0
int
vips__webp_write_file( VipsImage *in, const char *filename,
                       int Q, gboolean lossless )
{
    size_t len;
    uint8_t *buffer;
    FILE *fp;

    if( vips_image_wio_input( in ) )
        return( -1 );

    if( lossless ) {
        webp_encoder_lossless encoder;

        if( in->Bands == 4 )
            encoder = WebPEncodeLosslessRGBA;
        else
            encoder = WebPEncodeLosslessRGB;

        if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ),
                             in->Xsize, in->Ysize,
                             VIPS_IMAGE_SIZEOF_LINE( in ),
                             &buffer )) ) {
            vips_error( "vips2webp",
                        "%s", _( "unable to encode" ) );
            return( -1 );
        }
    }
    else {
        webp_encoder encoder;

        if( in->Bands == 4 )
            encoder = WebPEncodeRGBA;
        else
            encoder = WebPEncodeRGB;

        if( !(len = encoder( VIPS_IMAGE_ADDR( in, 0, 0 ),
                             in->Xsize, in->Ysize,
                             VIPS_IMAGE_SIZEOF_LINE( in ),
                             Q, &buffer )) ) {
            vips_error( "vips2webp",
                        "%s", _( "unable to encode" ) );
            return( -1 );
        }
    }

    if( !(fp = vips__file_open_write( filename, FALSE )) ) {
        free( buffer );
        return( -1 );
    }

    if( vips__file_write( buffer, len, 1, fp ) ) {
        fclose( fp );
        free( buffer );
        return( -1 );
    }

    fclose( fp );
    free( buffer );

    return( 0 );
}
Exemplo n.º 7
0
/* Write a VIPS image to PNG.
 */
static int
write_vips( Write *write, int compress, int interlace, const char *profile,
	VipsForeignPngFilter filter )
{
	VipsImage *in = write->in;

	int bit_depth;
	int color_type;
	int interlace_type;
	int i, nb_passes;

        g_assert( in->BandFmt == VIPS_FORMAT_UCHAR || 
		in->BandFmt == VIPS_FORMAT_USHORT );
	g_assert( in->Coding == VIPS_CODING_NONE );
        g_assert( in->Bands > 0 && in->Bands < 5 );

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

	/* Check input image. If we are writing interlaced, we need to make 7
	 * passes over the image. We advertise ourselves as seq, so to ensure
	 * we only suck once from upstream, switch to WIO. 
	 */
	if( interlace ) {
		if( vips_image_wio_input( in ) )
			return( -1 );
	}
	else {
		if( vips_image_pio_input( in ) )
			return( -1 );
	}
	if( compress < 0 || compress > 9 ) {
		vips_error( "vips2png", 
			"%s", _( "compress should be in [0,9]" ) );
		return( -1 );
	}

	/* Set compression parameters.
	 */
	png_set_compression_level( write->pPng, compress );

	/* Set row filter.
	 */
	png_set_filter( write->pPng, 0, filter );

	bit_depth = in->BandFmt == VIPS_FORMAT_UCHAR ? 8 : 16;

	switch( in->Bands ) {
	case 1: color_type = PNG_COLOR_TYPE_GRAY; break;
	case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
	case 3: color_type = PNG_COLOR_TYPE_RGB; break;
	case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; break;

	default:
		vips_error( "vips2png", 
			_( "can't save %d band image as png" ), in->Bands );
		return( -1 );
	}

	interlace_type = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;

	png_set_IHDR( write->pPng, write->pInfo, 
		in->Xsize, in->Ysize, bit_depth, color_type, interlace_type, 
		PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );

	/* Set resolution. libpng uses pixels per meter.
	 */
	png_set_pHYs( write->pPng, write->pInfo, 
		VIPS_RINT( in->Xres * 1000 ), VIPS_RINT( in->Yres * 1000 ), 
		PNG_RESOLUTION_METER );

	/* Set ICC Profile.
	 */
	if( profile ) {
		if( strcmp( profile, "none" ) != 0 ) { 
			void *data;
			size_t length;

			if( !(data = vips__file_read_name( profile, 
				VIPS_ICC_DIR, &length )) ) 
				return( -1 );

#ifdef DEBUG
			printf( "write_vips: "
				"attaching %zd bytes of ICC profile\n",
				length );
#endif /*DEBUG*/

			png_set_iCCP( write->pPng, write->pInfo, "icc", 
				PNG_COMPRESSION_TYPE_BASE, data, length );
		}
	}
	else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
		void *data;
		size_t length;

		if( vips_image_get_blob( in, VIPS_META_ICC_NAME, 
			&data, &length ) ) 
			return( -1 ); 

#ifdef DEBUG
		printf( "write_vips: attaching %zd bytes of ICC profile\n",
			length );
#endif /*DEBUG*/

		png_set_iCCP( write->pPng, write->pInfo, "icc", 
			PNG_COMPRESSION_TYPE_BASE, data, length );
	}

	png_write_info( write->pPng, write->pInfo ); 

	/* If we're an intel byte order CPU and this is a 16bit image, we need
	 * to swap bytes.
	 */
	if( bit_depth > 8 && !vips_amiMSBfirst() ) 
		png_set_swap( write->pPng ); 

	if( interlace )	
		nb_passes = png_set_interlace_handling( write->pPng );
	else
		nb_passes = 1;

	/* Write data.
	 */
	for( i = 0; i < nb_passes; i++ ) 
		if( vips_sink_disc( in, write_png_block, write ) )
			return( -1 );

	/* The setjmp() was held by our background writer: reset it.
	 */
	if( setjmp( png_jmpbuf( write->pPng ) ) ) 
		return( -1 );

	png_write_end( write->pPng, write->pInfo );

	return( 0 );
}