static int read_image( Read *read, VipsImage *out ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( out ), 3 ); t[0] = vips_image_new_memory(); if( read_header( read, t[0] ) ) return( -1 ); if( vips_image_write_prepare( t[0] ) ) return( -1 ); read->config.output.u.RGBA.rgba = VIPS_IMAGE_ADDR( t[0], 0, 0 ); read->config.output.u.RGBA.stride = VIPS_IMAGE_SIZEOF_LINE( t[0] ); read->config.output.u.RGBA.size = VIPS_IMAGE_SIZEOF_IMAGE( t[0] ); read->config.output.is_external_memory = 1; if( WebPDecode( (uint8_t *) read->data, read->length, &read->config) != VP8_STATUS_OK ) { vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); return( -1 ); } if( vips_image_write( t[0], out ) ) return( -1 ); return( 0 ); }
static int read_image( Read *read, VipsImage *out ) { VipsImage **t = (VipsImage **) vips_object_local_array( VIPS_OBJECT( out ), 3 ); webp_decoder decoder; t[0] = vips_image_new_memory(); if( read_header( read, t[0] ) ) return( -1 ); if( vips_image_write_prepare( t[0] ) ) return( -1 ); if( t[0]->Bands == 3 ) decoder = WebPDecodeRGBInto; else decoder = WebPDecodeRGBAInto; if( !decoder( (uint8_t *) read->data, read->length, VIPS_IMAGE_ADDR( t[0], 0, 0 ), VIPS_IMAGE_SIZEOF_IMAGE( t[0] ), VIPS_IMAGE_SIZEOF_LINE( t[0] ) ) ) { vips_error( "webp2vips", "%s", _( "unable to read pixels" ) ); return( -1 ); } if( vips_image_write( t[0], out ) ) return( -1 ); return( 0 ); }
/* Auto-rotate, if rotate_image is set. */ static VipsImage * read_jpeg_rotate( VipsObject *process, VipsImage *im ) { VipsImage **t = (VipsImage **) vips_object_local_array( process, 2 ); VipsAngle angle = vips_autorot_get_angle( im ); if( angle != VIPS_ANGLE_D0 ) { /* Need to copy to memory or disc, we have to stay seq. */ const guint64 image_size = VIPS_IMAGE_SIZEOF_IMAGE( im ); const guint64 disc_threshold = vips_get_disc_threshold(); if( image_size > disc_threshold ) t[0] = vips_image_new_temp_file( "%s.v" ); else t[0] = vips_image_new_memory(); if( vips_image_write( im, t[0] ) || vips_rot( t[0], &t[1], angle, NULL ) ) return( NULL ); im = t[1]; (void) vips_image_remove( im, ORIENTATION ); } return( im ); }
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 ); }
/* Predict the size of the header plus pixel data. Don't use off_t, * it's sometimes only 32 bits (eg. on many windows build environments) and we * want to always be 64 bit. */ static gint64 image_pixel_length( VipsImage *image ) { gint64 psize; switch( image->Coding ) { case VIPS_CODING_LABQ: case VIPS_CODING_RAD: case VIPS_CODING_NONE: psize = VIPS_IMAGE_SIZEOF_IMAGE( image ); break; default: psize = image->Length; break; } return( psize + image->sizeof_header ); }