Пример #1
0
static int
read_image( Read *read, VipsImage *out )
{
	VipsImage **t = (VipsImage **) 
		vips_object_local_array( VIPS_OBJECT( out ), 3 );
	guint64 length;
	void *data; 
	int fd;
	webp_decoder decoder;

	/* libwebp makes streaming very hard. We have to read to a full memory
	 * buffer, then copy to out.
	 *
	 * mmap the input file, it's slightly quicker.
	 */
	t[0] = vips_image_new_buffer();
	if( read_header( read, t[0] ) )
		return( -1 );
	if( vips_image_write_prepare( t[0] ) ) 
		return( -1 );

	if( !(fd = vips__open_image_read( read->filename )) )
		return( -1 );
	if( (length = vips_file_length( fd )) < 0 ) {
		vips_tracked_close( fd ); 
		return( -1 );
	}
	if( !(data = vips__mmap( fd, FALSE, length, 0 )) ) {
		vips_tracked_close( fd ); 
		return( -1 );
	}

	if( t[0]->Bands == 3 )
		decoder = WebPDecodeRGBInto;
	else
		decoder = WebPDecodeRGBAInto;

	if( !decoder( (uint8_t *) data, length, 
		VIPS_IMAGE_ADDR( t[0], 0, 0 ), 
		VIPS_IMAGE_SIZEOF_IMAGE( t[0] ),
		VIPS_IMAGE_SIZEOF_LINE( t[0] ) ) ) { 
		vips__munmap( data, length ); 
		vips_tracked_close( fd ); 
		vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); 
		return( -1 );
	}

	vips__munmap( data, length ); 
	vips_tracked_close( fd ); 

	if( vips_image_write( t[0], out ) )
		return( -1 );

	return( 0 );
}
Пример #2
0
static Read *
read_new( const char *filename, void *data, size_t length )
{
	Read *read;

	if( !(read = VIPS_NEW( NULL, Read )) )
		return( NULL );

	read->filename = g_strdup( filename );
	read->data = data;
	read->length = length;
	read->fd = 0;
	read->idec = NULL;

	if( read->filename ) { 
		/* libwebp makes streaming from a file source very hard. We 
		 * have to read to a full memory buffer, then copy to out.
		 *
		 * mmap the input file, it's slightly quicker.
		 */
		if( (read->fd = vips__open_image_read( read->filename )) < 0 ||
			(read->length = vips_file_length( read->fd )) < 0 ||
			!(read->data = vips__mmap( read->fd, 
				FALSE, read->length, 0 )) ) {
			read_free( read );
			return( NULL );
		}
	}

	WebPInitDecoderConfig( &read->config );
	if( WebPGetFeatures( read->data, MINIMAL_HEADER, 
		&read->config.input ) != VP8_STATUS_OK ) {
		read_free( read );
		return( NULL );
	}

	if( read->config.input.has_alpha )
		read->config.output.colorspace = MODE_RGBA;
	else
		read->config.output.colorspace = MODE_RGB;
	read->config.options.use_threads = TRUE;

	return( read );
}
Пример #3
0
static Read *
read_new( const char *filename, const void *data, size_t length, int shrink )
{
	Read *read;

	if( !(read = VIPS_NEW( NULL, Read )) )
		return( NULL );

	read->filename = g_strdup( filename );
	read->data = data;
	read->length = length;
	read->shrink = shrink;
	read->fd = 0;
	read->idec = NULL;

	if( read->filename ) { 
		/* libwebp makes streaming from a file source very hard. We 
		 * have to read to a full memory buffer, then copy to out.
		 *
		 * mmap the input file, it's slightly quicker.
		 */
		if( (read->fd = vips__open_image_read( read->filename )) < 0 ||
			(read->length = vips_file_length( read->fd )) < 0 ||
			!(read->data = vips__mmap( read->fd, 
				FALSE, read->length, 0 )) ) {
			read_free( read );
			return( NULL );
		}
	}

	WebPInitDecoderConfig( &read->config );
	if( WebPGetFeatures( read->data, MINIMAL_HEADER, 
		&read->config.input ) != VP8_STATUS_OK ) {
		read_free( read );
		return( NULL );
	}

	if( read->config.input.has_alpha )
		read->config.output.colorspace = MODE_RGBA;
	else
		read->config.output.colorspace = MODE_RGB;

	read->config.options.use_threads = 1;

	read->width = read->config.input.width / read->shrink;
	read->height = read->config.input.height / read->shrink;

	if( read->width == 0 ||
		read->height == 0 ) {
		vips_error( "webp", "%s", _( "bad setting for shrink" ) ); 
		return( NULL ); 
	}

	if( read->shrink > 1 ) { 
		read->config.options.use_scaling = 1;
		read->config.options.scaled_width = read->width;
		read->config.options.scaled_height = read->height; 
	}

	return( read );
}