diff --git a/ChangeLog b/ChangeLog index 4adf4d6f..e7ea1879 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,7 +28,7 @@ - vips_image_write() severs all links between images, when it can ... thanks Warren and Nakilon - vector path for convolution is more accurate and can handle larger masks -- linear and cubic kernels for reduce are higer quality +- linear and cubic kernels for reduce are higher quality - added vips_value_set_blob_free() - "--size Nx" to vipsthumbnail was broken, thanks jrochkind - fix build with gcc 7 @@ -41,6 +41,8 @@ - add dispose handling to gifload - dzsave outputs extra right and bottom overlap-only tiles, for closer spec adherence +- deprecate the "centre" option for vips_resize(): it's now always on +- setting the EXIF data block automatically sets other image tags 29/8/17 started 8.5.9 - make --fail stop jpeg read on any libjpeg warning, thanks @mceachen diff --git a/cplusplus/include/vips/vips-operators.h b/cplusplus/include/vips/vips-operators.h index 76adb9e8..913a1547 100644 --- a/cplusplus/include/vips/vips-operators.h +++ b/cplusplus/include/vips/vips-operators.h @@ -1,5 +1,5 @@ // headers for vips operations -// Fri 6 Oct 16:31:27 BST 2017 +// Sun 26 Nov 17:44:41 GMT 2017 // this file is generated automatically, do not edit! static void system( char * cmd_format , VOption *options = 0 ); @@ -47,6 +47,7 @@ VImage linecache( VOption *options = 0 ); VImage sequential( VOption *options = 0 ); VImage cache( VOption *options = 0 ); VImage embed( int x , int y , int width , int height , VOption *options = 0 ); +VImage gravity( VipsCompassDirection direction , int width , int height , VOption *options = 0 ); VImage flip( VipsDirection direction , VOption *options = 0 ); VImage insert( VImage sub , int x , int y , VOption *options = 0 ); VImage join( VImage in2 , VipsDirection direction , VOption *options = 0 ); @@ -232,6 +233,7 @@ VImage morph( VImage mask , VipsOperationMorphology morph , VOption *options = 0 VImage rank( int width , int height , int index , VOption *options = 0 ); double countlines( VipsDirection direction , VOption *options = 0 ); VImage labelregions( VOption *options = 0 ); +VImage fill_nearest( VOption *options = 0 ); void draw_rect( std::vector ink , int left , int top , int width , int height , VOption *options = 0 ); void draw_mask( std::vector ink , VImage mask , int x , int y , VOption *options = 0 ); void draw_line( std::vector ink , int x1 , int y1 , int x2 , int y2 , VOption *options = 0 ); diff --git a/cplusplus/vips-operators.cpp b/cplusplus/vips-operators.cpp index b0fdc783..02097139 100644 --- a/cplusplus/vips-operators.cpp +++ b/cplusplus/vips-operators.cpp @@ -1,5 +1,5 @@ // bodies for vips operations -// Fri 6 Oct 16:30:42 BST 2017 +// Sun 26 Nov 17:44:23 GMT 2017 // this file is generated automatically, do not edit! void VImage::system( char * cmd_format , VOption *options ) @@ -578,6 +578,21 @@ VImage VImage::embed( int x , int y , int width , int height , VOption *options return( out ); } +VImage VImage::gravity( VipsCompassDirection direction , int width , int height , VOption *options ) +{ + VImage out; + + call( "gravity" , + (options ? options : VImage::option()) -> + set( "in", *this ) -> + set( "out", &out ) -> + set( "direction", direction ) -> + set( "width", width ) -> + set( "height", height ) ); + + return( out ); +} + VImage VImage::flip( VipsDirection direction , VOption *options ) { VImage out; @@ -2863,6 +2878,18 @@ VImage VImage::labelregions( VOption *options ) return( mask ); } +VImage VImage::fill_nearest( VOption *options ) +{ + VImage out; + + call( "fill_nearest" , + (options ? options : VImage::option()) -> + set( "in", *this ) -> + set( "out", &out ) ); + + return( out ); +} + void VImage::draw_rect( std::vector ink , int left , int top , int width , int height , VOption *options ) { call( "draw_rect" , diff --git a/doc/Examples.xml b/doc/Examples.xml index aba6cdee..adb75910 100644 --- a/doc/Examples.xml +++ b/doc/Examples.xml @@ -22,16 +22,14 @@ #!/usr/bin/env python import sys -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips +import pyvips left = 10 top = 10 width = 64 height = 64 -image = Vips.Image.new_from_file(sys.argv[1]) +image = pyvips.Image.new_from_file(sys.argv[1]) roi = image.crop(left, top, width, height) print 'average:', roi.avg() @@ -39,146 +37,80 @@ print 'average:', roi.avg() libvips and numpy - You can use Vips.Image.new_from_memory_copy() to make a vips image from an area of memory. The memory array needs to be laid out band-interleaved, as a set of scanlines, with no padding between lines. - - - This example moves an image from numpy to vips, but it’s simple to move the other way (use Vips.Image.write_to_memory()) to to move images into or out of PIL. + You can use pyvips.Image.new_from_memory() to make a vips image from an area of memory. The memory array needs to be laid out band-interleaved, as a set of scanlines, with no padding between lines. -#!/usr/bin/python +#!/usr/bin/env python -import numpy -import scipy.ndimage -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips - -def np_dtype_to_vips_format(np_dtype): - ''' - Map numpy data types to VIPS data formats. - - Parameters - ---------- - np_dtype: numpy.dtype - - Returns - ------- - gi.overrides.Vips.BandFormat - ''' - lookup = { - numpy.dtype('int8'): Vips.BandFormat.CHAR, - numpy.dtype('uint8'): Vips.BandFormat.UCHAR, - numpy.dtype('int16'): Vips.BandFormat.SHORT, - numpy.dtype('uint16'): Vips.BandFormat.USHORT, - numpy.dtype('int32'): Vips.BandFormat.INT, - numpy.dtype('float32'): Vips.BandFormat.FLOAT, - numpy.dtype('float64'): Vips.BandFormat.DOUBLE - } - return lookup[np_dtype] - -def np_array_to_vips_image(array): - ''' - Convert a `numpy` array to a `Vips` image object. - - Parameters - ---------- - nparray: numpy.ndarray - - Returns - ------- - gi.overrides.Vips.image - ''' - # Look up what VIPS format corresponds to the type of this np array - vips_format = np_dtype_to_vips_format(array.dtype) - dims = array.shape - height = dims[0] - width = 1 - bands = 1 - if len(dims) > 1: - width = dims[1] - if len(dims) > 2: - bands = dims[2] - img = Vips.Image.new_from_memory_copy(array.data, - width, height, bands, vips_format) - - return img - -array = numpy.random.random((10,10)) -vips_image = np_array_to_vips_image(array) -print 'avg =', vips_image.avg() - -array = scipy.ndimage.imread("test.jpg") -vips_image = np_array_to_vips_image(array) -print 'avg =', vips_image.avg() -vips_image.write_to_file("test2.jpg") - - - - Watermarking - - This example renders a simple watermark on an image. Use it like this: - - -./watermark.py somefile.png output.jpg "hello <i>world</i>" - - - The text is rendered in transparent red pixels all over the image. It knows about transparency, CMYK, and 16-bit images. - - -#!/usr/bin/python - import sys -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips - -im = Vips.Image.new_from_file(sys.argv[1], access = Vips.Access.SEQUENTIAL) - -text = Vips.Image.text(sys.argv[3], width = 500, dpi = 300) -text = (text * 0.3).cast("uchar") -text = text.embed(100, 100, text.width + 200, text.width + 200) -text = text.replicate(1 + im.width / text.width, 1 + im.height / text.height) -text = text.crop(0, 0, im.width, im.height) +import time -# we want to blend into the visible part of the image and leave any alpha -# channels untouched ... we need to split im into two parts +import pyvips +from PIL import Image +import numpy as np -# 16-bit images have 65535 as white -if im.format == Vips.BandFormat.USHORT: - white = 65535 -else: - white = 255 +if len(sys.argv) != 3: + print('usage: {0} input-filename output-filename'.format(sys.argv[0])) + sys.exit(-1) -# guess how many bands from the start of im contain visible colour information -if im.bands >= 4 and im.interpretation == Vips.Interpretation.CMYK: - # cmyk image ... put the white into the magenta channel - n_visible_bands = 4 - text_colour = [0, white, 0, 0] -elif im.bands >= 3: - # colour image ... put the white into the red channel - n_visible_bands = 3 - text_colour = [white, 0, 0] -else: - # mono image - n_visible_bands = 1 - text_colour = white +# map vips formats to np dtypes +format_to_dtype = { + 'uchar': np.uint8, + 'char': np.int8, + 'ushort': np.uint16, + 'short': np.int16, + 'uint': np.uint32, + 'int': np.int32, + 'float': np.float32, + 'double': np.float64, + 'complex': np.complex64, + 'dpcomplex': np.complex128, +} -# split into image and alpha -if im.bands - n_visible_bands > 0: - alpha = im.extract_band(n_visible_bands, n = im.bands - n_visible_bands) - im = im.extract_band(0, n = n_visible_bands) -else: - alpha = None +# map np dtypes to vips +dtype_to_format = { + 'uint8': 'uchar', + 'int8': 'char', + 'uint16': 'ushort', + 'int16': 'short', + 'uint32': 'uint', + 'int32': 'int', + 'float32': 'float', + 'float64': 'double', + 'complex64': 'complex', + 'complex128': 'dpcomplex', +} -# blend means do a smooth fade using the 0 - 255 values in the condition channel -# (test in this case) ... this will render the anit-aliasing -im = text.ifthenelse(text_colour, im, blend = True) +# load with PIL +start_pillow = time.time() +pillow_img = np.asarray(Image.open(sys.argv[1])) +print('Pillow Time:', time.time()-start_pillow) +print('original shape', pillow_img.shape) -# reattach alpha -if alpha: - im = im.bandjoin(alpha) - -im.write_to_file(sys.argv[2]) +# load with vips to a memory array +start_vips = time.time() +img = pyvips.Image.new_from_file(sys.argv[1], access='sequential') +mem_img = img.write_to_memory() + +# then make a numpy array from that buffer object +np_3d = np.ndarray(buffer=mem_img, + dtype=format_to_dtype[img.format], + shape=[img.height, img.width, img.bands]) + +print('Vips Time:', time.time()-start_vips) +print('final shape', np_3d.shape) + +# verify we have the same result +print('Sum of the Differences:', np.sum(np_3d-pillow_img)) + +# make a vips image from the numpy array +height, width, bands = np_3d.shape +linear = np_3d.reshape(width * height * bands) +vi = pyvips.Image.new_from_memory(linear.data, width, height, bands, + dtype_to_format[str(np_3d.dtype)]) + +# and write back to disc for checking +vi.write_to_file(sys.argv[2]) @@ -219,19 +151,13 @@ sys 0m8.936s import sys import random - -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips - -# turn on progress reporting -Vips.progress_set(True) +import pyvips # this makes a 8-bit, mono image of 100,000 x 100,000 pixels, each pixel zero -im = Vips.Image.black(100000, 100000) +im = pyvips.Image.black(100000, 100000) for filename in sys.argv[2:]: - tile = Vips.Image.new_from_file(filename, access = Vips.Access.SEQUENTIAL) + tile = pyvips.Image.new_from_file(filename, access='sequential') im = im.insert(tile, random.randint(0, im.width - tile.width), @@ -240,82 +166,6 @@ for filename in sys.argv[2:]: im.write_to_file(sys.argv[1]) - - Rename DICOM images using header fields - - DICOM images commonly come in an awful directory hierarchy named as something like images/a/b/e/z04. There can be thousands of files and it can be very hard to find the one you want. - - - This utility copies files to a single flat directory, naming them using fields from the DICOM header. You can actually find stuff! Useful. - - -#!/usr/bin/env python - -import sys -import re -import os -import shutil - -import gi -gi.require_version('Vips', '8.0') -from gi.repository import Vips - -if len(sys.argv) != 3: - print 'rename DICOM files using tags from the header' - sys.exit(1) - -srcdir = sys.argv[1] -destdir = sys.argv[2] - -if not os.access(destdir, os.F_OK | os.R_OK | os.W_OK | os.X_OK): - os.mkdir(destdir) - -def get_field(vim, field): - result = vim.get_value(field) - - # remove any \n etc. - result = re.sub("\n", "", result) - - # remove any leading or trailing spaces - result = re.sub(" $", "", result) - result = re.sub("^ ", "", result) - - return result - -modality_name = "magick-dcm:Modality" -series_name = "magick-dcm:SeriesNumber" -instance_name = "magick-dcm:Instance(formerlyImage)Number" -date_name = "magick-dcm:ImageDate" - -for(dirpath, dirnames, filenames) in os.walk(srcdir): - for file in filenames: - path = os.path.join(dirpath, file) - - try: - vim = Vips.Image.new_from_file(path) - except Vips.Error, e: - print 'unable to open', path - print e - continue - - try: - modality = get_field(vim, modality_name) - series = get_field(vim, series_name) - instance = get_field(vim, instance_name) - date = get_field(vim, date_name) - except Vips.Error, e: - print 'unable to get fields from header', path - print e - continue - - match = re.match("(\d\d\d\d)(\d\d)(\d\d)", date) - date = match.group(1) + "." + match.group(2) + "." + match.group(3) - - newname = "lan." + modality + "." + instance + "." + date + ".IMA" - - shutil.copyfile(path, os.path.join(destdir, newname)) - - diff --git a/libvips/arithmetic/hist_find_indexed.c b/libvips/arithmetic/hist_find_indexed.c index bb5e6a89..03268562 100644 --- a/libvips/arithmetic/hist_find_indexed.c +++ b/libvips/arithmetic/hist_find_indexed.c @@ -62,6 +62,7 @@ typedef struct { int size; /* Length of bins */ int mx; /* Maximum value we have seen */ double *bins; /* All the bins! */ + int *init; /* TRUE for bin has been initialised */ } Histogram; typedef struct _VipsHistFindIndexed { @@ -108,12 +109,15 @@ histogram_new( VipsHistFindIndexed *indexed ) 256 : 65536; hist->mx = 0; hist->bins = NULL; + hist->init = NULL; if( !(hist->bins = VIPS_ARRAY( indexed, bands * hist->size, double )) || + !(hist->init = VIPS_ARRAY( indexed, hist->size, int )) || !(hist->reg = vips_region_new( indexed->index_ready )) ) return( NULL ); memset( hist->bins, 0, bands * hist->size * sizeof( double ) ); + memset( hist->init, 0, hist->size * sizeof( int ) ); return( hist ); } @@ -233,13 +237,34 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq ) Histogram *hist = indexed->hist; int bands = statistic->ready->Bands; - int i; + int i, j; + double *bins; + double *sub_bins; + int *init; + int *sub_init; - /* Add on sub-data. - */ hist->mx = VIPS_MAX( hist->mx, sub_hist->mx ); - for( i = 0; i < bands * hist->size; i++ ) - COMBINE( indexed->combine, hist->bins[i], sub_hist->bins[i] ); + + bins = hist->bins; + sub_bins = sub_hist->bins; + init = hist->init; + sub_init = sub_hist->init; + for( i = 0; i <= sub_hist->mx; i++ ) { + if( sub_init[i] ) { + if( init[i] ) + for( j = 0; j < bands; j++ ) + COMBINE( indexed->combine, + bins[j], sub_bins[j] ); + else { + for( j = 0; j < bands; j++ ) + bins[j] = sub_bins[j]; + init[i] = TRUE; + } + } + + bins += bands; + sub_bins += bands; + } VIPS_UNREF( sub_hist->reg ); @@ -253,10 +278,17 @@ vips_hist_find_indexed_stop( VipsStatistic *statistic, void *seq ) TYPE *tv = (TYPE *) in; \ \ for( x = 0; x < n; x++ ) { \ - double *bin = hist->bins + i[x] * bands; \ + int ix = i[x]; \ + double *bin = hist->bins + ix * bands; \ \ - for( z = 0; z < bands; z++ ) \ - COMBINE( indexed->combine, bin[z], tv[z] ); \ + if( hist->init[ix] ) \ + for( z = 0; z < bands; z++ ) \ + COMBINE( indexed->combine, bin[z], tv[z] ); \ + else { \ + for( z = 0; z < bands; z++ ) \ + bin[z] = tv[z]; \ + hist->init[ix] = TRUE; \ + } \ \ tv += bands; \ } \ @@ -312,8 +344,14 @@ vips_hist_find_indexed_uchar_scan( VipsHistFindIndexed *indexed, if( ix > mx ) \ mx = ix; \ \ - for( z = 0; z < bands; z++ ) \ - COMBINE( indexed->combine, bin[z], tv[z] ); \ + if( hist->init[ix] ) \ + for( z = 0; z < bands; z++ ) \ + COMBINE( indexed->combine, bin[z], tv[z] ); \ + else { \ + for( z = 0; z < bands; z++ ) \ + bin[z] = tv[z]; \ + hist->init[ix] = TRUE; \ + } \ \ tv += bands; \ } \ diff --git a/libvips/colour/LabQ2sRGB.c b/libvips/colour/LabQ2sRGB.c index f53e409a..80cfa49d 100644 --- a/libvips/colour/LabQ2sRGB.c +++ b/libvips/colour/LabQ2sRGB.c @@ -75,21 +75,21 @@ G_DEFINE_TYPE( VipsLabQ2sRGB, vips_LabQ2sRGB, VIPS_TYPE_COLOUR_CODE ); * * There's an extra element at the end to let us do a +1 for interpolation. */ -static int vips_Y2v_8[256 + 1]; +int vips_Y2v_8[256 + 1]; /* 8-bit sRGB -> linear lut. */ -static float vips_v2Y_8[256]; +float vips_v2Y_8[256]; /* 16-bit linear -> sRGB lut. * * There's an extra element at the end to let us do a +1 for interpolation. */ -static int vips_Y2v_16[65536 + 1]; +int vips_Y2v_16[65536 + 1]; /* 16-bit sRGB -> linear lut. */ -static float vips_v2Y_16[65536]; +float vips_v2Y_16[65536]; /* Do our own indexing of the arrays below to make sure we get efficient mults. */ @@ -166,7 +166,7 @@ calcul_tables_8( void *client ) return( NULL ); } -static void +void vips_col_make_tables_RGB_8( void ) { static GOnce once = G_ONCE_INIT; @@ -190,7 +190,7 @@ calcul_tables_16( void *client ) return( NULL ); } -static void +void vips_col_make_tables_RGB_16( void ) { static GOnce once = G_ONCE_INIT; diff --git a/libvips/colour/pcolour.h b/libvips/colour/pcolour.h index 07b14967..876a2305 100644 --- a/libvips/colour/pcolour.h +++ b/libvips/colour/pcolour.h @@ -205,6 +205,17 @@ GType vips_colour_difference_get_type( void ); void vips__pythagoras_line( VipsColour *colour, VipsPel *out, VipsPel **in, int width ); +/* Colour tables for Y<->v conversion. Call vips_col_make_tables_RGB_8() and + * vips_col_make_tables_RGB_16() before use to initialize. + */ +extern int vips_Y2v_8[256 + 1]; +extern float vips_v2Y_8[256]; +extern int vips_Y2v_16[65536 + 1]; +extern float vips_v2Y_16[65536]; + +void vips_col_make_tables_RGB_8( void ); +void vips_col_make_tables_RGB_16( void ); + #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/colour/sRGB2scRGB.c b/libvips/colour/sRGB2scRGB.c index 0b0e877e..8d025319 100644 --- a/libvips/colour/sRGB2scRGB.c +++ b/libvips/colour/sRGB2scRGB.c @@ -17,6 +17,8 @@ * - add 16-bit alpha handling * 26/2/16 * - look for RGB16 tag, not just ushort, for the 16-bit path + * 24/11/17 lovell + * - special path for 3 and 4 band images */ /* @@ -81,27 +83,41 @@ vips_sRGB2scRGB_line_8( float * restrict q, VipsPel * restrict p, { int i, j; - for( i = 0; i < width; i++ ) { - int r = p[0]; - int g = p[1]; - int b = p[2]; + if( extra_bands == 0 ) { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_8[p[0]]; + q[1] = vips_v2Y_8[p[1]]; + q[2] = vips_v2Y_8[p[2]]; - float R, G, B; + p += 3; + q += 3; + } + } + else if( extra_bands == 1 ) { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_8[p[0]]; + q[1] = vips_v2Y_8[p[1]]; + q[2] = vips_v2Y_8[p[2]]; + q[3] = p[3]; - p += 3; + p += 4; + q += 4; + } + } + else { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_8[p[0]]; + q[1] = vips_v2Y_8[p[1]]; + q[2] = vips_v2Y_8[p[2]]; - vips_col_sRGB2scRGB_8( r, g, b, &R, &G, &B ); + p += 3; + q += 3; - q[0] = R; - q[1] = G; - q[2] = B; - - q += 3; - - for( j = 0; j < extra_bands; j++ ) - q[j] = p[j]; - p += extra_bands; - q += extra_bands; + for( j = 0; j < extra_bands; j++ ) + q[j] = p[j]; + p += extra_bands; + q += extra_bands; + } } } @@ -113,27 +129,41 @@ vips_sRGB2scRGB_line_16( float * restrict q, unsigned short * restrict p, { int i, j; - for( i = 0; i < width; i++ ) { - int r = p[0]; - int g = p[1]; - int b = p[2]; + if( extra_bands == 0 ) { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_16[p[0]]; + q[1] = vips_v2Y_16[p[1]]; + q[2] = vips_v2Y_16[p[2]]; - float R, G, B; + p += 3; + q += 3; + } + } + else if( extra_bands == 1 ) { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_16[p[0]]; + q[1] = vips_v2Y_16[p[1]]; + q[2] = vips_v2Y_16[p[2]]; + q[3] = p[3] / 256.0; - p += 3; + p += 4; + q += 4; + } + } + else { + for( i = 0; i < width; i++ ) { + q[0] = vips_v2Y_16[p[0]]; + q[1] = vips_v2Y_16[p[1]]; + q[2] = vips_v2Y_16[p[2]]; - vips_col_sRGB2scRGB_16( r, g, b, &R, &G, &B ); + p += 3; + q += 3; - q[0] = R; - q[1] = G; - q[2] = B; - - q += 3; - - for( j = 0; j < extra_bands; j++ ) - q[j] = p[j] / 256.0; - p += extra_bands; - q += extra_bands; + for( j = 0; j < extra_bands; j++ ) + q[j] = p[j] / 256.0; + p += extra_bands; + q += extra_bands; + } } } @@ -152,17 +182,28 @@ vips_sRGB2scRGB_gen( VipsRegion *or, VIPS_GATE_START( "vips_sRGB2scRGB_gen: work" ); - for( y = 0; y < r->height; y++ ) { - VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y ); - float *q = (float *) - VIPS_REGION_ADDR( or, r->left, r->top + y ); + if( in->BandFmt == VIPS_FORMAT_UCHAR ) { + vips_col_make_tables_RGB_8(); + + for( y = 0; y < r->height; y++ ) { + VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y ); + float *q = (float *) + VIPS_REGION_ADDR( or, r->left, r->top + y ); + + vips_sRGB2scRGB_line_8( q, p, in->Bands - 3, r->width ); + } + } + else { + vips_col_make_tables_RGB_16(); + + for( y = 0; y < r->height; y++ ) { + VipsPel *p = VIPS_REGION_ADDR( ir, r->left, r->top + y ); + float *q = (float *) + VIPS_REGION_ADDR( or, r->left, r->top + y ); - if( in->BandFmt == VIPS_FORMAT_UCHAR ) - vips_sRGB2scRGB_line_8( q, p, - in->Bands - 3, r->width ); - else vips_sRGB2scRGB_line_16( q, (unsigned short *) p, in->Bands - 3, r->width ); + } } VIPS_GATE_STOP( "vips_sRGB2scRGB_gen: work" ); diff --git a/libvips/conversion/premultiply.c b/libvips/conversion/premultiply.c index 897c97c3..d233de58 100644 --- a/libvips/conversion/premultiply.c +++ b/libvips/conversion/premultiply.c @@ -7,6 +7,8 @@ * - fix RGBA path * 25/5/16 * - max_alpha defaults to 65535 for RGB16/GREY16 + * 24/11/17 lovell + * - match normalised alpha to output type */ /* @@ -78,7 +80,7 @@ G_DEFINE_TYPE( VipsPremultiply, vips_premultiply, VIPS_TYPE_CONVERSION ); for( x = 0; x < width; x++ ) { \ IN alpha = p[bands - 1]; \ IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ - double nalpha = (double) clip_alpha / max_alpha; \ + OUT nalpha = (OUT) clip_alpha / max_alpha; \ \ for( i = 0; i < bands - 1; i++ ) \ q[i] = p[i] * nalpha; \ @@ -98,7 +100,7 @@ G_DEFINE_TYPE( VipsPremultiply, vips_premultiply, VIPS_TYPE_CONVERSION ); for( x = 0; x < width; x++ ) { \ IN alpha = p[3]; \ IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ - double nalpha = (double) clip_alpha / max_alpha; \ + OUT nalpha = (OUT) clip_alpha / max_alpha; \ \ q[0] = p[0] * nalpha; \ q[1] = p[1] * nalpha; \ diff --git a/libvips/conversion/unpremultiply.c b/libvips/conversion/unpremultiply.c index db118c1a..f994809b 100644 --- a/libvips/conversion/unpremultiply.c +++ b/libvips/conversion/unpremultiply.c @@ -5,6 +5,8 @@ * * 25/5/16 * - max_alpha defaults to 65535 for RGB16/GREY16 + * 24/11/17 lovell + * - match normalised alpha to output type */ /* @@ -75,8 +77,8 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION ); \ for( x = 0; x < width; x++ ) { \ IN alpha = p[bands - 1]; \ - int clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ - double nalpha = (double) clip_alpha / max_alpha; \ + IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ + OUT nalpha = (OUT) clip_alpha / max_alpha; \ \ if( clip_alpha == 0 ) \ for( i = 0; i < bands - 1; i++ ) \ @@ -99,8 +101,8 @@ G_DEFINE_TYPE( VipsUnpremultiply, vips_unpremultiply, VIPS_TYPE_CONVERSION ); \ for( x = 0; x < width; x++ ) { \ IN alpha = p[3]; \ - int clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ - double nalpha = (double) clip_alpha / max_alpha; \ + IN clip_alpha = VIPS_CLIP( 0, alpha, max_alpha ); \ + OUT nalpha = (OUT) clip_alpha / max_alpha; \ \ if( clip_alpha == 0 ) { \ q[0] = 0; \ diff --git a/libvips/foreign/exif.c b/libvips/foreign/exif.c index 138362a8..c36de7e5 100644 --- a/libvips/foreign/exif.c +++ b/libvips/foreign/exif.c @@ -484,7 +484,7 @@ vips__exif_parse( VipsImage *image ) return( -1 ); } - /* Make sure all required fields are there before we attach to vips + /* Make sure all required fields are there before we attach the vips * metadata. */ exif_data_fix( ed ); @@ -1002,19 +1002,22 @@ vips_exif_update( ExifData *ed, VipsImage *image ) VIPS_DEBUG_MSG( "vips_exif_update: \n" ); - /* Walk the image and update any stuff that's been changed in image - * metadata. + /* Walk the image and add any exif- that's set in image metadata. */ vips_image_map( image, vips_exif_image_field, ed ); - /* Walk the exif and look for any fields which are NOT in image - * metadata. They must have been removed ... remove them from exif as - * well. + /* If this exif came from the image (rather than being an exif block we + * have made afresh), then any fields which are in the block but not on + * the image must have been deliberately removed. Remove them from the + * block as well. */ - ve.image = image; - ve.ed = ed; - exif_data_foreach_content( ed, - (ExifDataForeachContentFunc) vips_exif_exif_content, &ve ); + if( vips_image_get_typeof( image, VIPS_META_EXIF_NAME ) ) { + ve.image = image; + ve.ed = ed; + exif_data_foreach_content( ed, + (ExifDataForeachContentFunc) vips_exif_exif_content, + &ve ); + } } /* Examine the metadata tags on the image and update the EXIF block. diff --git a/libvips/foreign/jpeg2vips.c b/libvips/foreign/jpeg2vips.c index ecb583c6..1bca9fb7 100644 --- a/libvips/foreign/jpeg2vips.c +++ b/libvips/foreign/jpeg2vips.c @@ -514,9 +514,6 @@ read_jpeg_header( ReadJpeg *jpeg, VipsImage *out ) (VipsCallbackFn) vips_free, data, data_length ); } - if( vips__exif_parse( out ) ) - return( -1 ); - /* Tell downstream we are reading sequentially. */ vips_image_set_area( out, VIPS_META_SEQUENTIAL, NULL, NULL ); diff --git a/libvips/foreign/pforeign.h b/libvips/foreign/pforeign.h index 2b0f207f..08973569 100644 --- a/libvips/foreign/pforeign.h +++ b/libvips/foreign/pforeign.h @@ -239,9 +239,6 @@ int vips__openslide_read( const char *filename, VipsImage *out, int vips__openslide_read_associated( const char *filename, VipsImage *out, const char *associated ); -int vips__exif_parse( VipsImage *image ); -int vips__exif_update( VipsImage *image ); - #ifdef __cplusplus } #endif /*__cplusplus*/ diff --git a/libvips/foreign/vips2webp.c b/libvips/foreign/vips2webp.c index 5119c94e..3725e100 100644 --- a/libvips/foreign/vips2webp.c +++ b/libvips/foreign/vips2webp.c @@ -53,6 +53,7 @@ #include #include +#include #include "pforeign.h" diff --git a/libvips/foreign/webp2vips.c b/libvips/foreign/webp2vips.c index ee542c40..971f9238 100644 --- a/libvips/foreign/webp2vips.c +++ b/libvips/foreign/webp2vips.c @@ -269,11 +269,6 @@ read_header( Read *read, VipsImage *out ) } WebPMuxDelete( mux ); - - /* We may have read some exif ... parse into the header. - */ - if( vips__exif_parse( out ) ) - return( -1 ); } #endif /*HAVE_LIBWEBPMUX*/ diff --git a/libvips/include/vips/colour.h b/libvips/include/vips/colour.h index e3cd57f4..77404b9c 100644 --- a/libvips/include/vips/colour.h +++ b/libvips/include/vips/colour.h @@ -204,6 +204,10 @@ float vips_col_Chcmc2h( float C, float hcmc ); int vips_col_sRGB2scRGB_8( int r, int g, int b, float *R, float *G, float *B ); int vips_col_sRGB2scRGB_16( int r, int g, int b, float *R, float *G, float *B ); +int vips_col_sRGB2scRGB_8_noclip( int r, int g, int b, + float *R, float *G, float *B ); +int vips_col_sRGB2scRGB_16_noclip( int r, int g, int b, + float *R, float *G, float *B ); int vips_col_scRGB2XYZ( float R, float G, float B, float *X, float *Y, float *Z ); diff --git a/libvips/include/vips/internal.h b/libvips/include/vips/internal.h index 1fa988a9..1b9ae9de 100644 --- a/libvips/include/vips/internal.h +++ b/libvips/include/vips/internal.h @@ -52,6 +52,9 @@ typedef struct _VipsMeta { GValue value; /* copy of value */ } VipsMeta; +int vips__exif_parse( VipsImage *image ); +int vips__exif_update( VipsImage *image ); + void vips_check_init( void ); void vips__meta_init_types( void ); diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 7c3b2184..1f6c60ff 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -962,6 +962,16 @@ vips_image_set( VipsImage *image, const char *name, GValue *value ) meta_init( image ); (void) meta_new( image, name, value ); + /* If we're setting an EXIF data block, we need to automatically expand + * out all the tags. This will set things like xres/yres too. + * + * We do this herfe rather than in meta_new() since we don't want to + * trigger on copy_fields. + */ + if( strcmp( name, VIPS_META_EXIF_NAME ) == 0 ) + if( vips__exif_parse( image ) ) + g_warning( "image_set: bad exif data" ); + #ifdef DEBUG meta_sanity( image ); #endif /*DEBUG*/ diff --git a/libvips/resample/resize.c b/libvips/resample/resize.c index 64a849ab..5865d484 100644 --- a/libvips/resample/resize.c +++ b/libvips/resample/resize.c @@ -26,6 +26,8 @@ * - moved the cache to shrinkv * 15/10/17 * - make LINEAR and CUBIC adaptive + * 25/11/17 + * - deprecate --centre ... it's now always on, thanks tback */ /* @@ -84,13 +86,13 @@ typedef struct _VipsResize { double scale; double vscale; VipsKernel kernel; - gboolean centre; /* Deprecated. */ VipsInterpolate *interpolate; double idx; double idy; + gboolean centre; } VipsResize; @@ -213,7 +215,7 @@ vips_resize_build( VipsObject *object ) g_info( "residual reducev by %g", vscale ); if( vips_reducev( in, &t[2], 1.0 / vscale, "kernel", resize->kernel, - "centre", resize->centre, + "centre", TRUE, NULL ) ) return( -1 ); in = t[2]; @@ -224,7 +226,7 @@ vips_resize_build( VipsObject *object ) hscale ); if( vips_reduceh( in, &t[3], 1.0 / hscale, "kernel", resize->kernel, - "centre", resize->centre, + "centre", TRUE, NULL ) ) return( -1 ); in = t[3]; @@ -235,6 +237,12 @@ vips_resize_build( VipsObject *object ) if( hscale > 1.0 || vscale > 1.0 ) { const char *nickname = vips_resize_interpolate( resize->kernel ); + + /* Input displacement. For centre sampling, shift by 0.5 down + * and right. + */ + const double id = 0.5; + VipsInterpolate *interpolate; if( !(interpolate = vips_interpolate_new( nickname )) ) @@ -257,6 +265,8 @@ vips_resize_build( VipsObject *object ) if( vips_affine( in, &t[4], hscale, 0.0, 0.0, vscale, "interpolate", interpolate, + "idx", id, + "idy", id, NULL ) ) return( -1 ); in = t[4]; @@ -265,6 +275,8 @@ vips_resize_build( VipsObject *object ) g_info( "residual scale %g", hscale ); if( vips_affine( in, &t[4], hscale, 0.0, 0.0, 1.0, "interpolate", interpolate, + "idx", id, + "idy", id, NULL ) ) return( -1 ); in = t[4]; @@ -273,6 +285,8 @@ vips_resize_build( VipsObject *object ) g_info( "residual scale %g", vscale ); if( vips_affine( in, &t[4], 1.0, 0.0, 0.0, vscale, "interpolate", interpolate, + "idx", id, + "idy", id, NULL ) ) return( -1 ); in = t[4]; @@ -324,13 +338,6 @@ vips_resize_class_init( VipsResizeClass *class ) G_STRUCT_OFFSET( VipsResize, kernel ), VIPS_TYPE_KERNEL, VIPS_KERNEL_LANCZOS3 ); - VIPS_ARG_BOOL( class, "centre", 7, - _( "Centre" ), - _( "Use centre sampling convention" ), - VIPS_ARGUMENT_OPTIONAL_INPUT, - G_STRUCT_OFFSET( VipsResize, centre ), - FALSE ); - /* We used to let people set the input offset so you could pick centre * or corner interpolation, but it's not clear this was useful. */ @@ -356,6 +363,15 @@ vips_resize_class_init( VipsResizeClass *class ) VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, G_STRUCT_OFFSET( VipsResize, interpolate ) ); + /* We used to let people pick centre or corner, but it's automatic now. + */ + VIPS_ARG_BOOL( class, "centre", 7, + _( "Centre" ), + _( "Use centre sampling convention" ), + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET( VipsResize, centre ), + FALSE ); + } static void @@ -375,7 +391,6 @@ vips_resize_init( VipsResize *resize ) * * * @vscale: %gdouble vertical scale factor * * @kernel: #VipsKernel to reduce with - * * @centre: %gboolean use centre rather than corner sampling convention * * Resize an image. * @@ -383,17 +398,16 @@ vips_resize_init( VipsResize *resize ) * image is block-shrunk with vips_shrink(), * then the image is shrunk again to the * target size with vips_reduce(). How much is done by vips_shrink() vs. - * vips_reduce() varies with the @kernel setting. + * vips_reduce() varies with the @kernel setting. Downsizing is done with + * centre convention. * * vips_resize() normally uses #VIPS_KERNEL_LANCZOS3 for the final reduce, you * can change this with @kernel. * - * Set @centre to use centre rather than corner sampling convention. Centre - * convention can be useful to match the behaviour of other systems. - * * When upsizing (@scale > 1), the operation uses vips_affine() with * a #VipsInterpolate selected depending on @kernel. It will use - * #VipsInterpolateBicubic for #VIPS_KERNEL_CUBIC and above. + * #VipsInterpolateBicubic for #VIPS_KERNEL_CUBIC and above. It adds a + * 0.5 pixel displacement to the input pixels to get centre convention scaling. * * vips_resize() normally maintains the image aspect ratio. If you set * @vscale, that factor is used for the vertical scale and @scale for the diff --git a/libvips/resample/thumbnail.c b/libvips/resample/thumbnail.c index 211d09d1..babf8233 100644 --- a/libvips/resample/thumbnail.c +++ b/libvips/resample/thumbnail.c @@ -416,11 +416,8 @@ vips_thumbnail_build( VipsObject *object ) vips_thumbnail_calculate_shrink( thumbnail, in->Xsize, in->Ysize, &hshrink, &vshrink ); - /* Use centre convention to better match imagemagick. - */ if( vips_resize( in, &t[4], 1.0 / hshrink, "vscale", 1.0 / vshrink, - "centre", TRUE, NULL ) ) return( -1 ); in = t[4]; diff --git a/libvipsCC/include/vips/vipsc++.h b/libvipsCC/include/vips/vipsc++.h index 9b8ca94c..aa9fc70e 100644 --- a/libvipsCC/include/vips/vipsc++.h +++ b/libvipsCC/include/vips/vipsc++.h @@ -1,7 +1,7 @@ // headers for package arithmetic // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage abs(); VImage acos(); VImage add( VImage add_in2 ); @@ -49,13 +49,13 @@ VImage tan(); // headers for package cimg // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage greyc( int greyc_iterations, double greyc_amplitude, double greyc_sharpness, double greyc_anisotropy, double greyc_alpha, double greyc_sigma, double greyc_dl, double greyc_da, double greyc_gauss_prec, int greyc_interpolation, int greyc_fast_approx ); VImage greyc_mask( VImage greyc_mask_mask, int greyc_mask_iterations, double greyc_mask_amplitude, double greyc_mask_sharpness, double greyc_mask_anisotropy, double greyc_mask_alpha, double greyc_mask_sigma, double greyc_mask_dl, double greyc_mask_da, double greyc_mask_gauss_prec, int greyc_mask_interpolation, int greyc_mask_fast_approx ); // headers for package colour // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage LCh2Lab(); VImage LCh2UCS(); VImage Lab2LCh(); @@ -101,7 +101,7 @@ VImage sRGB2XYZ(); // headers for package conversion // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 static VImage gaussnoise( int gaussnoise_xsize, int gaussnoise_ysize, double gaussnoise_mean, double gaussnoise_sigma ); VImage bandjoin( VImage bandjoin_in2 ); static VImage black( int black_x_size, int black_y_size, int black_bands ); @@ -149,7 +149,7 @@ VImage zoom( int zoom_xfac, int zoom_yfac ); // headers for package convolution // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage aconvsep( VDMask aconvsep_matrix, int aconvsep_n_layers ); VImage aconv( VDMask aconv_matrix, int aconv_n_layers, int aconv_cluster ); VImage addgnoise( double addgnoise_sigma ); @@ -170,7 +170,7 @@ VImage spcor( VImage spcor_in2 ); // headers for package deprecated // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage argb2rgba(); VImage flood_copy( int flood_copy_start_x, int flood_copy_start_y, std::vector flood_copy_ink ); VImage flood_blob_copy( int flood_blob_copy_start_x, int flood_blob_copy_start_y, std::vector flood_blob_copy_ink ); @@ -257,7 +257,7 @@ VImage quadratic( VImage quadratic_coeff ); // headers for package format // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 static VImage csv2vips( char* csv2vips_filename ); static VImage fits2vips( char* fits2vips_in ); static VImage jpeg2vips( char* jpeg2vips_in ); @@ -277,7 +277,7 @@ void vips2tiff( char* vips2tiff_out ); // headers for package freq_filt // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 static VImage create_fmask( int create_fmask_width, int create_fmask_height, int create_fmask_type, double create_fmask_p1, double create_fmask_p2, double create_fmask_p3, double create_fmask_p4, double create_fmask_p5 ); VImage disp_ps(); VImage flt_image_freq( int flt_image_freq_type, double flt_image_freq_p1, double flt_image_freq_p2, double flt_image_freq_p3, double flt_image_freq_p4, double flt_image_freq_p5 ); @@ -291,7 +291,7 @@ VImage invfftr(); // headers for package histograms_lut // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage gammacorrect( double gammacorrect_exponent ); VImage heq( int heq_band_number ); VImage hist( int hist_band_number ); @@ -321,7 +321,7 @@ VImage tone_map( VImage tone_map_lut ); // headers for package inplace // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 void draw_circle( int draw_circle_cx, int draw_circle_cy, int draw_circle_radius, int draw_circle_fill, std::vector draw_circle_ink ); void draw_rect( int draw_rect_left, int draw_rect_top, int draw_rect_width, int draw_rect_height, int draw_rect_fill, std::vector draw_rect_ink ); void draw_line( int draw_line_x1, int draw_line_y1, int draw_line_x2, int draw_line_y2, std::vector draw_line_ink ); @@ -336,9 +336,10 @@ VImage line( VImage line_mask, VImage line_ink, std::vector line_x1, std::v // headers for package iofuncs // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 static VImage binfile( char* binfile_filename, int binfile_width, int binfile_height, int binfile_bands, int binfile_offset ); VImage cache( int cache_tile_width, int cache_tile_height, int cache_max_tiles ); +VImage tile_cache_random( int tile_cache_random_tile_width, int tile_cache_random_tile_height, int tile_cache_random_max_tiles ); char* getext(); int header_get_typeof( char* header_get_typeof_field ); int header_int( char* header_int_field ); @@ -349,11 +350,11 @@ void printdesc(); // headers for package mask // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // headers for package morphology // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 double cntlines( int cntlines_direction ); VImage dilate( VIMask dilate_mask ); VImage rank( int rank_xsize, int rank_ysize, int rank_n ); @@ -366,7 +367,7 @@ VImage profile( int profile_direction ); // headers for package mosaicing // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage align_bands(); double correl( VImage correl_sec, int correl_xref, int correl_yref, int correl_xsec, int correl_ysec, int correl_hwindowsize, int correl_hsearchsize, int& correl_x, int& correl_y ); int _find_lroverlap( VImage _find_lroverlap_sec, int _find_lroverlap_bandno, int _find_lroverlap_xr, int _find_lroverlap_yr, int _find_lroverlap_xs, int _find_lroverlap_ys, int _find_lroverlap_halfcorrelation, int _find_lroverlap_halfarea, int& _find_lroverlap_dy0, double& _find_lroverlap_scale1, double& _find_lroverlap_angle1, double& _find_lroverlap_dx1, double& _find_lroverlap_dy1 ); @@ -388,7 +389,7 @@ VImage tbmosaic1( VImage tbmosaic1_sec, int tbmosaic1_bandno, int tbmosaic1_xr1, // headers for package other // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage benchmark(); double benchmark2(); VImage benchmarkn( int benchmarkn_n ); @@ -403,7 +404,7 @@ static VImage zone( int zone_size ); // headers for package resample // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 VImage rightshift_size( int rightshift_size_xshift, int rightshift_size_yshift, int rightshift_size_band_fmt ); VImage shrink( double shrink_xfac, double shrink_yfac ); VImage stretch3( double stretch3_xdisp, double stretch3_ydisp ); @@ -412,7 +413,7 @@ VImage affinei_all( char* affinei_all_interpolate, double affinei_all_a, double // headers for package video // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 static VImage video_test( int video_test_brightness, int video_test_error ); static VImage video_v4l1( char* video_v4l1_device, int video_v4l1_channel, int video_v4l1_brightness, int video_v4l1_colour, int video_v4l1_contrast, int video_v4l1_hue, int video_v4l1_ngrabs ); diff --git a/libvipsCC/vipsc++.cc b/libvipsCC/vipsc++.cc index d35ebb04..37f52e1d 100644 --- a/libvipsCC/vipsc++.cc +++ b/libvipsCC/vipsc++.cc @@ -1,7 +1,7 @@ // bodies for package arithmetic // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_abs: absolute value VImage VImage::abs() { @@ -761,7 +761,7 @@ VImage VImage::tan() // bodies for package cimg // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_greyc: noise-removing filter VImage VImage::greyc( int iterations, double amplitude, double sharpness, double anisotropy, double alpha, double sigma, double dl, double da, double gauss_prec, int interpolation, int fast_approx ) { @@ -821,7 +821,7 @@ VImage VImage::greyc_mask( VImage mask, int iterations, double amplitude, double // bodies for package colour // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_LCh2Lab: convert LCh to Lab VImage VImage::LCh2Lab() { @@ -1537,7 +1537,7 @@ VImage VImage::sRGB2XYZ() // bodies for package conversion // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_gaussnoise: generate image of gaussian noise with specified statistics VImage VImage::gaussnoise( int xsize, int ysize, double mean, double sigma ) { @@ -2321,7 +2321,7 @@ VImage VImage::zoom( int xfac, int yfac ) // bodies for package convolution // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_aconvsep: approximate separable convolution VImage VImage::aconvsep( VDMask matrix, int n_layers ) { @@ -2624,7 +2624,7 @@ VImage VImage::spcor( VImage in2 ) // bodies for package deprecated // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_argb2rgba: convert pre-multipled argb to png-style rgba VImage VImage::argb2rgba() { @@ -4116,7 +4116,7 @@ VImage VImage::quadratic( VImage coeff ) // bodies for package format // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_csv2vips: read a file in csv format VImage VImage::csv2vips( char* filename ) { @@ -4323,7 +4323,7 @@ void VImage::vips2tiff( char* out ) // bodies for package freq_filt // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_create_fmask: create frequency domain filter mask VImage VImage::create_fmask( int width, int height, int type, double p1, double p2, double p3, double p4, double p5 ) { @@ -4491,7 +4491,7 @@ VImage VImage::invfftr() // bodies for package histograms_lut // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_gammacorrect: gamma-correct image VImage VImage::gammacorrect( double exponent ) { @@ -4938,7 +4938,7 @@ VImage VImage::tone_map( VImage lut ) // bodies for package inplace // this file automatically generated from -// VIPS library 7.34.0-Tue Jun 11 11:18:24 BST 2013 +// VIPS library 8.6.0-Sun Nov 26 17:45:39 GMT 2017 // im_draw_circle: draw circle on image void VImage::draw_circle( int cx, int cy, int radius, int fill, std::vector ink ) { @@ -5136,7 +5136,7 @@ VImage VImage::line( VImage mask, VImage ink, std::vector x1, std::vector