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 ); }
static int read_free( Read *read ) { VIPS_FREEF( WebPIDelete, read->idec ); WebPFreeDecBuffer( &read->config.output ); if( read->fd > 0 && read->data && read->length > 0 ) { vips__munmap( read->data, read->length ); read->data = NULL; read->length = 0; } VIPS_FREEF( vips_tracked_close, read->fd ); VIPS_FREE( read->filename ); VIPS_FREE( read ); return( 0 ); }
static int vips_window_unmap( VipsWindow *window ) { /* unmap the old window */ if( window->baseaddr ) { if( vips__munmap( window->baseaddr, window->length ) ) return( -1 ); #ifdef DEBUG_TOTAL g_mutex_lock( vips__global_lock ); total_mmap_usage -= window->length; assert( total_mmap_usage >= 0 ); g_mutex_unlock( vips__global_lock ); #endif /*DEBUG_TOTAL*/ window->data = NULL; window->baseaddr = NULL; window->length = 0; } return( 0 ); }