// Code generated by vipsgen. DO NOT EDIT.
package vips

// #include "generated.h"
import "C"

import (
	"runtime"
	"unsafe"
)

// Ensure imports are used.
var _ = unsafe.Pointer(nil)

// vipsGenCMC2LCh calls the vips CMC2LCh operation.
// transform LCh to CMC
func vipsGenCMC2LCh(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("CMC2LCh")

	var out_out *C.VipsImage

	ret := C.gen_vips_CMC2LCh(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenCMYK2XYZ calls the vips CMYK2XYZ operation.
// transform CMYK to XYZ
func vipsGenCMYK2XYZ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("CMYK2XYZ")

	var out_out *C.VipsImage

	ret := C.gen_vips_CMYK2XYZ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHSV2sRGB calls the vips HSV2sRGB operation.
// transform HSV to sRGB
func vipsGenHSV2sRGB(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("HSV2sRGB")

	var out_out *C.VipsImage

	ret := C.gen_vips_HSV2sRGB(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLCh2CMC calls the vips LCh2CMC operation.
// transform LCh to CMC
func vipsGenLCh2CMC(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LCh2CMC")

	var out_out *C.VipsImage

	ret := C.gen_vips_LCh2CMC(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLCh2Lab calls the vips LCh2Lab operation.
// transform LCh to Lab
func vipsGenLCh2Lab(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LCh2Lab")

	var out_out *C.VipsImage

	ret := C.gen_vips_LCh2Lab(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLab2LCh calls the vips Lab2LCh operation.
// transform Lab to LCh
func vipsGenLab2LCh(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Lab2LCh")

	var out_out *C.VipsImage

	ret := C.gen_vips_Lab2LCh(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLab2LabQ calls the vips Lab2LabQ operation.
// transform float Lab to LabQ coding
func vipsGenLab2LabQ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Lab2LabQ")

	var out_out *C.VipsImage

	ret := C.gen_vips_Lab2LabQ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLab2LabS calls the vips Lab2LabS operation.
// transform float Lab to signed short
func vipsGenLab2LabS(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Lab2LabS")

	var out_out *C.VipsImage

	ret := C.gen_vips_Lab2LabS(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// Lab2XYZOptions are optional parameters for Lab2XYZ.
type Lab2XYZOptions struct {
	Temp []float64
}

// vipsGenLab2XYZ calls the vips Lab2XYZ operation.
// transform CIELAB to XYZ
func vipsGenLab2XYZ(input *C.VipsImage, opts *Lab2XYZOptions) (*C.VipsImage, error) {
	incOpCounter("Lab2XYZ")

	var out_out *C.VipsImage

	var cOpts C.GenLab2XYZOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Temp != nil {
			cOpts.has_temp = 1
			pinner.Pin(&opts.Temp[0])
			cOpts.temp = (*C.double)(unsafe.Pointer(&opts.Temp[0]))
			cOpts.temp_n = C.int(len(opts.Temp))
		}
	}

	ret := C.gen_vips_Lab2XYZ(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabQ2Lab calls the vips LabQ2Lab operation.
// unpack a LabQ image to float Lab
func vipsGenLabQ2Lab(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LabQ2Lab")

	var out_out *C.VipsImage

	ret := C.gen_vips_LabQ2Lab(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabQ2LabS calls the vips LabQ2LabS operation.
// unpack a LabQ image to short Lab
func vipsGenLabQ2LabS(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LabQ2LabS")

	var out_out *C.VipsImage

	ret := C.gen_vips_LabQ2LabS(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabQ2sRGB calls the vips LabQ2sRGB operation.
// convert a LabQ image to sRGB
func vipsGenLabQ2sRGB(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LabQ2sRGB")

	var out_out *C.VipsImage

	ret := C.gen_vips_LabQ2sRGB(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabS2Lab calls the vips LabS2Lab operation.
// transform signed short Lab to float
func vipsGenLabS2Lab(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LabS2Lab")

	var out_out *C.VipsImage

	ret := C.gen_vips_LabS2Lab(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabS2LabQ calls the vips LabS2LabQ operation.
// transform short Lab to LabQ coding
func vipsGenLabS2LabQ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("LabS2LabQ")

	var out_out *C.VipsImage

	ret := C.gen_vips_LabS2LabQ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenOklab2Oklch calls the vips Oklab2Oklch operation.
// transform Oklab to Oklch
func vipsGenOklab2Oklch(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Oklab2Oklch")

	var out_out *C.VipsImage

	ret := C.gen_vips_Oklab2Oklch(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenOklab2XYZ calls the vips Oklab2XYZ operation.
// transform Oklab to XYZ
func vipsGenOklab2XYZ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Oklab2XYZ")

	var out_out *C.VipsImage

	ret := C.gen_vips_Oklab2XYZ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenOklch2Oklab calls the vips Oklch2Oklab operation.
// transform Oklch to Oklab
func vipsGenOklch2Oklab(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Oklch2Oklab")

	var out_out *C.VipsImage

	ret := C.gen_vips_Oklch2Oklab(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenXYZ2CMYK calls the vips XYZ2CMYK operation.
// transform XYZ to CMYK
func vipsGenXYZ2CMYK(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("XYZ2CMYK")

	var out_out *C.VipsImage

	ret := C.gen_vips_XYZ2CMYK(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// XYZ2LabOptions are optional parameters for XYZ2Lab.
type XYZ2LabOptions struct {
	Temp []float64
}

// vipsGenXYZ2Lab calls the vips XYZ2Lab operation.
// transform XYZ to Lab
func vipsGenXYZ2Lab(input *C.VipsImage, opts *XYZ2LabOptions) (*C.VipsImage, error) {
	incOpCounter("XYZ2Lab")

	var out_out *C.VipsImage

	var cOpts C.GenXYZ2LabOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Temp != nil {
			cOpts.has_temp = 1
			pinner.Pin(&opts.Temp[0])
			cOpts.temp = (*C.double)(unsafe.Pointer(&opts.Temp[0]))
			cOpts.temp_n = C.int(len(opts.Temp))
		}
	}

	ret := C.gen_vips_XYZ2Lab(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenXYZ2Oklab calls the vips XYZ2Oklab operation.
// transform XYZ to Oklab
func vipsGenXYZ2Oklab(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("XYZ2Oklab")

	var out_out *C.VipsImage

	ret := C.gen_vips_XYZ2Oklab(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenXYZ2Yxy calls the vips XYZ2Yxy operation.
// transform XYZ to Yxy
func vipsGenXYZ2Yxy(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("XYZ2Yxy")

	var out_out *C.VipsImage

	ret := C.gen_vips_XYZ2Yxy(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenXYZ2scRGB calls the vips XYZ2scRGB operation.
// transform XYZ to scRGB
func vipsGenXYZ2scRGB(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("XYZ2scRGB")

	var out_out *C.VipsImage

	ret := C.gen_vips_XYZ2scRGB(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenYxy2XYZ calls the vips Yxy2XYZ operation.
// transform Yxy to XYZ
func vipsGenYxy2XYZ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("Yxy2XYZ")

	var out_out *C.VipsImage

	ret := C.gen_vips_Yxy2XYZ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenAbs calls the vips abs operation.
// absolute value of an image
func vipsGenAbs(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("abs")

	var out_out *C.VipsImage

	ret := C.gen_vips_abs(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenAdd calls the vips add operation.
// add two images
func vipsGenAdd(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("add")

	var out_out *C.VipsImage

	ret := C.gen_vips_add(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// AffineOptions are optional parameters for affine.
type AffineOptions struct {
	Interpolate *C.VipsInterpolate
	Oarea []int
	Odx *float64
	Ody *float64
	Idx *float64
	Idy *float64
	Background []float64
	Premultiplied *bool
	Extend *ExtendStrategy
}

// vipsGenAffine calls the vips affine operation.
// affine transform of an image
func vipsGenAffine(input *C.VipsImage, matrix []float64, opts *AffineOptions) (*C.VipsImage, error) {
	incOpCounter("affine")

	var out_out *C.VipsImage

	var cOpts C.GenAffineOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
		if opts.Oarea != nil {
			cOpts.has_oarea = 1
			pinner.Pin(&opts.Oarea[0])
			cOpts.oarea = (*C.int)(unsafe.Pointer(&opts.Oarea[0]))
			cOpts.oarea_n = C.int(len(opts.Oarea))
		}
		if opts.Odx != nil {
			cOpts.has_odx = 1
			cOpts.odx = C.double(*opts.Odx)
		}
		if opts.Ody != nil {
			cOpts.has_ody = 1
			cOpts.ody = C.double(*opts.Ody)
		}
		if opts.Idx != nil {
			cOpts.has_idx = 1
			cOpts.idx = C.double(*opts.Idx)
		}
		if opts.Idy != nil {
			cOpts.has_idy = 1
			cOpts.idy = C.double(*opts.Idy)
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Premultiplied != nil {
			cOpts.has_premultiplied = 1
			cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied))
		}
		if opts.Extend != nil {
			cOpts.has_extend = 1
			cOpts.extend = C.VipsExtend(*opts.Extend)
		}
	}

	ret := C.gen_vips_affine(input, (*C.double)(unsafe.Pointer(&matrix[0])), C.int(len(matrix)), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ArrayjoinOptions are optional parameters for arrayjoin.
type ArrayjoinOptions struct {
	Across *int
	Shim *int
	Background []float64
	Halign *Align
	Valign *Align
	Hspacing *int
	Vspacing *int
}

// vipsGenArrayjoin calls the vips arrayjoin operation.
// join an array of images
func vipsGenArrayjoin(input []*C.VipsImage, opts *ArrayjoinOptions) (*C.VipsImage, error) {
	incOpCounter("arrayjoin")

	var out_out *C.VipsImage

	var cOpts C.GenArrayjoinOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Across != nil {
			cOpts.has_across = 1
			cOpts.across = C.int(*opts.Across)
		}
		if opts.Shim != nil {
			cOpts.has_shim = 1
			cOpts.shim = C.int(*opts.Shim)
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Halign != nil {
			cOpts.has_halign = 1
			cOpts.halign = C.VipsAlign(*opts.Halign)
		}
		if opts.Valign != nil {
			cOpts.has_valign = 1
			cOpts.valign = C.VipsAlign(*opts.Valign)
		}
		if opts.Hspacing != nil {
			cOpts.has_hspacing = 1
			cOpts.hspacing = C.int(*opts.Hspacing)
		}
		if opts.Vspacing != nil {
			cOpts.has_vspacing = 1
			cOpts.vspacing = C.int(*opts.Vspacing)
		}
	}

	ret := C.gen_vips_arrayjoin((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenAutorot calls the vips autorot operation.
// autorotate image by exif tag
func vipsGenAutorot(input *C.VipsImage) (*C.VipsImage, Angle, bool, error) {
	incOpCounter("autorot")

	var out_out *C.VipsImage
	var out_angle C.int
	var out_flip C.int

	ret := C.gen_vips_autorot(input, &out_out, &out_angle, &out_flip)
	if ret != 0 {
		return nil, 0, false, handleImageError(out_out)
	}

	return out_out, Angle(out_angle), out_flip != 0, nil
}

// vipsGenAvg calls the vips avg operation.
// find image average
func vipsGenAvg(input *C.VipsImage) (float64, error) {
	incOpCounter("avg")

	var out_out C.double

	ret := C.gen_vips_avg(input, &out_out)
	if ret != 0 {
		return 0, handleVipsError()
	}

	return float64(out_out), nil
}

// vipsGenBandbool calls the vips bandbool operation.
// boolean operation across image bands
func vipsGenBandbool(input *C.VipsImage, boolean OperationBoolean) (*C.VipsImage, error) {
	incOpCounter("bandbool")

	var out_out *C.VipsImage

	ret := C.gen_vips_bandbool(input, C.VipsOperationBoolean(boolean), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// BandfoldOptions are optional parameters for bandfold.
type BandfoldOptions struct {
	Factor *int
}

// vipsGenBandfold calls the vips bandfold operation.
// fold up x axis into bands
func vipsGenBandfold(input *C.VipsImage, opts *BandfoldOptions) (*C.VipsImage, error) {
	incOpCounter("bandfold")

	var out_out *C.VipsImage

	var cOpts C.GenBandfoldOpts
	if opts != nil {
		if opts.Factor != nil {
			cOpts.has_factor = 1
			cOpts.factor = C.int(*opts.Factor)
		}
	}

	ret := C.gen_vips_bandfold(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBandjoin calls the vips bandjoin operation.
// bandwise join a set of images
func vipsGenBandjoin(input []*C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("bandjoin")

	var out_out *C.VipsImage

	ret := C.gen_vips_bandjoin((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBandjoinConst calls the vips bandjoin_const operation.
// append a constant band to an image
func vipsGenBandjoinConst(input *C.VipsImage, c []float64) (*C.VipsImage, error) {
	incOpCounter("bandjoin_const")

	var out_out *C.VipsImage

	ret := C.gen_vips_bandjoin_const(input, (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBandmean calls the vips bandmean operation.
// band-wise average
func vipsGenBandmean(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("bandmean")

	var out_out *C.VipsImage

	ret := C.gen_vips_bandmean(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// BandrankOptions are optional parameters for bandrank.
type BandrankOptions struct {
	Index *int
}

// vipsGenBandrank calls the vips bandrank operation.
// band-wise rank of a set of images
func vipsGenBandrank(input []*C.VipsImage, opts *BandrankOptions) (*C.VipsImage, error) {
	incOpCounter("bandrank")

	var out_out *C.VipsImage

	var cOpts C.GenBandrankOpts
	if opts != nil {
		if opts.Index != nil {
			cOpts.has_index = 1
			cOpts.index = C.int(*opts.Index)
		}
	}

	ret := C.gen_vips_bandrank((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// BandunfoldOptions are optional parameters for bandunfold.
type BandunfoldOptions struct {
	Factor *int
}

// vipsGenBandunfold calls the vips bandunfold operation.
// unfold image bands into x axis
func vipsGenBandunfold(input *C.VipsImage, opts *BandunfoldOptions) (*C.VipsImage, error) {
	incOpCounter("bandunfold")

	var out_out *C.VipsImage

	var cOpts C.GenBandunfoldOpts
	if opts != nil {
		if opts.Factor != nil {
			cOpts.has_factor = 1
			cOpts.factor = C.int(*opts.Factor)
		}
	}

	ret := C.gen_vips_bandunfold(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// BlackOptions are optional parameters for black.
type BlackOptions struct {
	Bands *int
}

// vipsGenBlack calls the vips black operation.
// make a black image
func vipsGenBlack(width int, height int, opts *BlackOptions) (*C.VipsImage, error) {
	incOpCounter("black")

	var out_out *C.VipsImage

	var cOpts C.GenBlackOpts
	if opts != nil {
		if opts.Bands != nil {
			cOpts.has_bands = 1
			cOpts.bands = C.int(*opts.Bands)
		}
	}

	ret := C.gen_vips_black(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBoolean calls the vips boolean operation.
// boolean operation on two images
func vipsGenBoolean(left *C.VipsImage, right *C.VipsImage, boolean OperationBoolean) (*C.VipsImage, error) {
	incOpCounter("boolean")

	var out_out *C.VipsImage

	ret := C.gen_vips_boolean(left, right, C.VipsOperationBoolean(boolean), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBooleanConst calls the vips boolean_const operation.
// boolean operations against a constant
func vipsGenBooleanConst(input *C.VipsImage, boolean OperationBoolean, c []float64) (*C.VipsImage, error) {
	incOpCounter("boolean_const")

	var out_out *C.VipsImage

	ret := C.gen_vips_boolean_const(input, C.VipsOperationBoolean(boolean), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenBuildlut calls the vips buildlut operation.
// build a look-up table
func vipsGenBuildlut(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("buildlut")

	var out_out *C.VipsImage

	ret := C.gen_vips_buildlut(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenByteswap calls the vips byteswap operation.
// byteswap an image
func vipsGenByteswap(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("byteswap")

	var out_out *C.VipsImage

	ret := C.gen_vips_byteswap(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// CacheOptions are optional parameters for cache.
type CacheOptions struct {
	MaxTiles *int
	TileHeight *int
	TileWidth *int
}

// vipsGenCache calls the vips cache operation.
// cache an image
func vipsGenCache(input *C.VipsImage, opts *CacheOptions) (*C.VipsImage, error) {
	incOpCounter("cache")

	var out_out *C.VipsImage

	var cOpts C.GenCacheOpts
	if opts != nil {
		if opts.MaxTiles != nil {
			cOpts.has_maxTiles = 1
			cOpts.maxTiles = C.int(*opts.MaxTiles)
		}
		if opts.TileHeight != nil {
			cOpts.has_tileHeight = 1
			cOpts.tileHeight = C.int(*opts.TileHeight)
		}
		if opts.TileWidth != nil {
			cOpts.has_tileWidth = 1
			cOpts.tileWidth = C.int(*opts.TileWidth)
		}
	}

	ret := C.gen_vips_cache(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// CannyOptions are optional parameters for canny.
type CannyOptions struct {
	Sigma *float64
	Precision *Precision
}

// vipsGenCanny calls the vips canny operation.
// Canny edge detector
func vipsGenCanny(input *C.VipsImage, opts *CannyOptions) (*C.VipsImage, error) {
	incOpCounter("canny")

	var out_out *C.VipsImage

	var cOpts C.GenCannyOpts
	if opts != nil {
		if opts.Sigma != nil {
			cOpts.has_sigma = 1
			cOpts.sigma = C.double(*opts.Sigma)
		}
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
	}

	ret := C.gen_vips_canny(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// CastOptions are optional parameters for cast.
type CastOptions struct {
	Shift *bool
}

// vipsGenCast calls the vips cast operation.
// cast an image
func vipsGenCast(input *C.VipsImage, format BandFormat, opts *CastOptions) (*C.VipsImage, error) {
	incOpCounter("cast")

	var out_out *C.VipsImage

	var cOpts C.GenCastOpts
	if opts != nil {
		if opts.Shift != nil {
			cOpts.has_shift = 1
			cOpts.shift = C.int(boolToInt(*opts.Shift))
		}
	}

	ret := C.gen_vips_cast(input, C.VipsBandFormat(format), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ClampOptions are optional parameters for clamp.
type ClampOptions struct {
	Min *float64
	Max *float64
}

// vipsGenClamp calls the vips clamp operation.
// clamp values of an image
func vipsGenClamp(input *C.VipsImage, opts *ClampOptions) (*C.VipsImage, error) {
	incOpCounter("clamp")

	var out_out *C.VipsImage

	var cOpts C.GenClampOpts
	if opts != nil {
		if opts.Min != nil {
			cOpts.has_min = 1
			cOpts.min = C.double(*opts.Min)
		}
		if opts.Max != nil {
			cOpts.has_max = 1
			cOpts.max = C.double(*opts.Max)
		}
	}

	ret := C.gen_vips_clamp(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// CompassOptions are optional parameters for compass.
type CompassOptions struct {
	Times *int
	Angle *Angle45
	Combine *Combine
	Precision *Precision
	Layers *int
	Cluster *int
}

// vipsGenCompass calls the vips compass operation.
// convolve with rotating mask
func vipsGenCompass(input *C.VipsImage, mask *C.VipsImage, opts *CompassOptions) (*C.VipsImage, error) {
	incOpCounter("compass")

	var out_out *C.VipsImage

	var cOpts C.GenCompassOpts
	if opts != nil {
		if opts.Times != nil {
			cOpts.has_times = 1
			cOpts.times = C.int(*opts.Times)
		}
		if opts.Angle != nil {
			cOpts.has_angle = 1
			cOpts.angle = C.VipsAngle45(*opts.Angle)
		}
		if opts.Combine != nil {
			cOpts.has_combine = 1
			cOpts.combine = C.VipsCombine(*opts.Combine)
		}
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
		if opts.Layers != nil {
			cOpts.has_layers = 1
			cOpts.layers = C.int(*opts.Layers)
		}
		if opts.Cluster != nil {
			cOpts.has_cluster = 1
			cOpts.cluster = C.int(*opts.Cluster)
		}
	}

	ret := C.gen_vips_compass(input, mask, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenComplex calls the vips complex operation.
// perform a complex operation on an image
func vipsGenComplex(input *C.VipsImage, cmplx OperationComplex) (*C.VipsImage, error) {
	incOpCounter("complex")

	var out_out *C.VipsImage

	ret := C.gen_vips_complex(input, C.VipsOperationComplex(cmplx), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenComplex2 calls the vips complex2 operation.
// complex binary operations on two images
func vipsGenComplex2(left *C.VipsImage, right *C.VipsImage, cmplx OperationComplex2) (*C.VipsImage, error) {
	incOpCounter("complex2")

	var out_out *C.VipsImage

	ret := C.gen_vips_complex2(left, right, C.VipsOperationComplex2(cmplx), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenComplexform calls the vips complexform operation.
// form a complex image from two real images
func vipsGenComplexform(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("complexform")

	var out_out *C.VipsImage

	ret := C.gen_vips_complexform(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenComplexget calls the vips complexget operation.
// get a component from a complex image
func vipsGenComplexget(input *C.VipsImage, get OperationComplexget) (*C.VipsImage, error) {
	incOpCounter("complexget")

	var out_out *C.VipsImage

	ret := C.gen_vips_complexget(input, C.VipsOperationComplexget(get), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// Composite2Options are optional parameters for composite2.
type Composite2Options struct {
	X *int
	Y *int
	CompositingSpace *Interpretation
	Premultiplied *bool
}

// vipsGenComposite2 calls the vips composite2 operation.
// blend a pair of images with a blend mode
func vipsGenComposite2(base *C.VipsImage, overlay *C.VipsImage, mode BlendMode, opts *Composite2Options) (*C.VipsImage, error) {
	incOpCounter("composite2")

	var out_out *C.VipsImage

	var cOpts C.GenComposite2Opts
	if opts != nil {
		if opts.X != nil {
			cOpts.has_x = 1
			cOpts.x = C.int(*opts.X)
		}
		if opts.Y != nil {
			cOpts.has_y = 1
			cOpts.y = C.int(*opts.Y)
		}
		if opts.CompositingSpace != nil {
			cOpts.has_compositingSpace = 1
			cOpts.compositingSpace = C.VipsInterpretation(*opts.CompositingSpace)
		}
		if opts.Premultiplied != nil {
			cOpts.has_premultiplied = 1
			cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied))
		}
	}

	ret := C.gen_vips_composite2(base, overlay, C.VipsBlendMode(mode), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ConvOptions are optional parameters for conv.
type ConvOptions struct {
	Precision *Precision
	Layers *int
	Cluster *int
}

// vipsGenConv calls the vips conv operation.
// convolution operation
func vipsGenConv(input *C.VipsImage, mask *C.VipsImage, opts *ConvOptions) (*C.VipsImage, error) {
	incOpCounter("conv")

	var out_out *C.VipsImage

	var cOpts C.GenConvOpts
	if opts != nil {
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
		if opts.Layers != nil {
			cOpts.has_layers = 1
			cOpts.layers = C.int(*opts.Layers)
		}
		if opts.Cluster != nil {
			cOpts.has_cluster = 1
			cOpts.cluster = C.int(*opts.Cluster)
		}
	}

	ret := C.gen_vips_conv(input, mask, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ConvaOptions are optional parameters for conva.
type ConvaOptions struct {
	Layers *int
	Cluster *int
}

// vipsGenConva calls the vips conva operation.
// approximate integer convolution
func vipsGenConva(input *C.VipsImage, mask *C.VipsImage, opts *ConvaOptions) (*C.VipsImage, error) {
	incOpCounter("conva")

	var out_out *C.VipsImage

	var cOpts C.GenConvaOpts
	if opts != nil {
		if opts.Layers != nil {
			cOpts.has_layers = 1
			cOpts.layers = C.int(*opts.Layers)
		}
		if opts.Cluster != nil {
			cOpts.has_cluster = 1
			cOpts.cluster = C.int(*opts.Cluster)
		}
	}

	ret := C.gen_vips_conva(input, mask, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ConvasepOptions are optional parameters for convasep.
type ConvasepOptions struct {
	Layers *int
}

// vipsGenConvasep calls the vips convasep operation.
// approximate separable integer convolution
func vipsGenConvasep(input *C.VipsImage, mask *C.VipsImage, opts *ConvasepOptions) (*C.VipsImage, error) {
	incOpCounter("convasep")

	var out_out *C.VipsImage

	var cOpts C.GenConvasepOpts
	if opts != nil {
		if opts.Layers != nil {
			cOpts.has_layers = 1
			cOpts.layers = C.int(*opts.Layers)
		}
	}

	ret := C.gen_vips_convasep(input, mask, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenConvf calls the vips convf operation.
// float convolution operation
func vipsGenConvf(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("convf")

	var out_out *C.VipsImage

	ret := C.gen_vips_convf(input, mask, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenConvi calls the vips convi operation.
// int convolution operation
func vipsGenConvi(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("convi")

	var out_out *C.VipsImage

	ret := C.gen_vips_convi(input, mask, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ConvsepOptions are optional parameters for convsep.
type ConvsepOptions struct {
	Precision *Precision
	Layers *int
	Cluster *int
}

// vipsGenConvsep calls the vips convsep operation.
// separable convolution operation
func vipsGenConvsep(input *C.VipsImage, mask *C.VipsImage, opts *ConvsepOptions) (*C.VipsImage, error) {
	incOpCounter("convsep")

	var out_out *C.VipsImage

	var cOpts C.GenConvsepOpts
	if opts != nil {
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
		if opts.Layers != nil {
			cOpts.has_layers = 1
			cOpts.layers = C.int(*opts.Layers)
		}
		if opts.Cluster != nil {
			cOpts.has_cluster = 1
			cOpts.cluster = C.int(*opts.Cluster)
		}
	}

	ret := C.gen_vips_convsep(input, mask, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// CopyOptions are optional parameters for copy.
type CopyOptions struct {
	Width *int
	Height *int
	Bands *int
	Format *BandFormat
	Coding *Coding
	Interpretation *Interpretation
	Xres *float64
	Yres *float64
	Xoffset *int
	Yoffset *int
}

// vipsGenCopy calls the vips copy operation.
// copy an image
func vipsGenCopy(input *C.VipsImage, opts *CopyOptions) (*C.VipsImage, error) {
	incOpCounter("copy")

	var out_out *C.VipsImage

	var cOpts C.GenCopyOpts
	if opts != nil {
		if opts.Width != nil {
			cOpts.has_width = 1
			cOpts.width = C.int(*opts.Width)
		}
		if opts.Height != nil {
			cOpts.has_height = 1
			cOpts.height = C.int(*opts.Height)
		}
		if opts.Bands != nil {
			cOpts.has_bands = 1
			cOpts.bands = C.int(*opts.Bands)
		}
		if opts.Format != nil {
			cOpts.has_format = 1
			cOpts.format = C.VipsBandFormat(*opts.Format)
		}
		if opts.Coding != nil {
			cOpts.has_coding = 1
			cOpts.coding = C.VipsCoding(*opts.Coding)
		}
		if opts.Interpretation != nil {
			cOpts.has_interpretation = 1
			cOpts.interpretation = C.VipsInterpretation(*opts.Interpretation)
		}
		if opts.Xres != nil {
			cOpts.has_xres = 1
			cOpts.xres = C.double(*opts.Xres)
		}
		if opts.Yres != nil {
			cOpts.has_yres = 1
			cOpts.yres = C.double(*opts.Yres)
		}
		if opts.Xoffset != nil {
			cOpts.has_xoffset = 1
			cOpts.xoffset = C.int(*opts.Xoffset)
		}
		if opts.Yoffset != nil {
			cOpts.has_yoffset = 1
			cOpts.yoffset = C.int(*opts.Yoffset)
		}
	}

	ret := C.gen_vips_copy(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenCountlines calls the vips countlines operation.
// count lines in an image
func vipsGenCountlines(input *C.VipsImage, direction Direction) (float64, error) {
	incOpCounter("countlines")

	var out_nolines C.double

	ret := C.gen_vips_countlines(input, C.VipsDirection(direction), &out_nolines)
	if ret != 0 {
		return 0, handleVipsError()
	}

	return float64(out_nolines), nil
}

// vipsGenDE00 calls the vips dE00 operation.
// calculate dE00
func vipsGenDE00(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("dE00")

	var out_out *C.VipsImage

	ret := C.gen_vips_dE00(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenDE76 calls the vips dE76 operation.
// calculate dE76
func vipsGenDE76(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("dE76")

	var out_out *C.VipsImage

	ret := C.gen_vips_dE76(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenDECMC calls the vips dECMC operation.
// calculate dECMC
func vipsGenDECMC(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("dECMC")

	var out_out *C.VipsImage

	ret := C.gen_vips_dECMC(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenDeviate calls the vips deviate operation.
// find image standard deviation
func vipsGenDeviate(input *C.VipsImage) (float64, error) {
	incOpCounter("deviate")

	var out_out C.double

	ret := C.gen_vips_deviate(input, &out_out)
	if ret != 0 {
		return 0, handleVipsError()
	}

	return float64(out_out), nil
}

// vipsGenDivide calls the vips divide operation.
// divide two images
func vipsGenDivide(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("divide")

	var out_out *C.VipsImage

	ret := C.gen_vips_divide(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenExtractArea calls the vips extract_area operation.
// extract an area from an image
func vipsGenExtractArea(input *C.VipsImage, left int, top int, width int, height int) (*C.VipsImage, error) {
	incOpCounter("extract_area")

	var out_out *C.VipsImage

	ret := C.gen_vips_extract_area(input, C.int(left), C.int(top), C.int(width), C.int(height), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ExtractBandOptions are optional parameters for extract_band.
type ExtractBandOptions struct {
	N *int
}

// vipsGenExtractBand calls the vips extract_band operation.
// extract band from an image
func vipsGenExtractBand(input *C.VipsImage, band int, opts *ExtractBandOptions) (*C.VipsImage, error) {
	incOpCounter("extract_band")

	var out_out *C.VipsImage

	var cOpts C.GenExtractBandOpts
	if opts != nil {
		if opts.N != nil {
			cOpts.has_n = 1
			cOpts.n = C.int(*opts.N)
		}
	}

	ret := C.gen_vips_extract_band(input, C.int(band), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// EyeOptions are optional parameters for eye.
type EyeOptions struct {
	Uchar *bool
	Factor *float64
}

// vipsGenEye calls the vips eye operation.
// make an image showing the eye's spatial response
func vipsGenEye(width int, height int, opts *EyeOptions) (*C.VipsImage, error) {
	incOpCounter("eye")

	var out_out *C.VipsImage

	var cOpts C.GenEyeOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Factor != nil {
			cOpts.has_factor = 1
			cOpts.factor = C.double(*opts.Factor)
		}
	}

	ret := C.gen_vips_eye(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFalsecolour calls the vips falsecolour operation.
// false-color an image
func vipsGenFalsecolour(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("falsecolour")

	var out_out *C.VipsImage

	ret := C.gen_vips_falsecolour(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFastcor calls the vips fastcor operation.
// fast correlation
func vipsGenFastcor(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("fastcor")

	var out_out *C.VipsImage

	ret := C.gen_vips_fastcor(input, ref, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFillNearest calls the vips fill_nearest operation.
// fill image zeros with nearest non-zero pixel
func vipsGenFillNearest(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) {
	incOpCounter("fill_nearest")

	var out_out *C.VipsImage
	var out_distance *C.VipsImage

	ret := C.gen_vips_fill_nearest(input, &out_out, &out_distance)
	if ret != 0 {
		return nil, nil, handleImageError(out_out)
	}

	return out_out, out_distance, nil
}

// FlattenOptions are optional parameters for flatten.
type FlattenOptions struct {
	Background []float64
	MaxAlpha *float64
}

// vipsGenFlatten calls the vips flatten operation.
// flatten alpha out of an image
func vipsGenFlatten(input *C.VipsImage, opts *FlattenOptions) (*C.VipsImage, error) {
	incOpCounter("flatten")

	var out_out *C.VipsImage

	var cOpts C.GenFlattenOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.MaxAlpha != nil {
			cOpts.has_maxAlpha = 1
			cOpts.maxAlpha = C.double(*opts.MaxAlpha)
		}
	}

	ret := C.gen_vips_flatten(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFlip calls the vips flip operation.
// flip an image
func vipsGenFlip(input *C.VipsImage, direction Direction) (*C.VipsImage, error) {
	incOpCounter("flip")

	var out_out *C.VipsImage

	ret := C.gen_vips_flip(input, C.VipsDirection(direction), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFloat2rad calls the vips float2rad operation.
// transform float RGB to Radiance coding
func vipsGenFloat2rad(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("float2rad")

	var out_out *C.VipsImage

	ret := C.gen_vips_float2rad(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFractsurf calls the vips fractsurf operation.
// make a fractal surface
func vipsGenFractsurf(width int, height int, fractalDimension float64) (*C.VipsImage, error) {
	incOpCounter("fractsurf")

	var out_out *C.VipsImage

	ret := C.gen_vips_fractsurf(C.int(width), C.int(height), C.double(fractalDimension), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFreqmult calls the vips freqmult operation.
// frequency-domain filtering
func vipsGenFreqmult(input *C.VipsImage, mask *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("freqmult")

	var out_out *C.VipsImage

	ret := C.gen_vips_freqmult(input, mask, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenFwfft calls the vips fwfft operation.
// forward FFT
func vipsGenFwfft(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("fwfft")

	var out_out *C.VipsImage

	ret := C.gen_vips_fwfft(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GammaOptions are optional parameters for gamma.
type GammaOptions struct {
	Exponent *float64
}

// vipsGenGamma calls the vips gamma operation.
// gamma an image
func vipsGenGamma(input *C.VipsImage, opts *GammaOptions) (*C.VipsImage, error) {
	incOpCounter("gamma")

	var out_out *C.VipsImage

	var cOpts C.GenGammaOpts
	if opts != nil {
		if opts.Exponent != nil {
			cOpts.has_exponent = 1
			cOpts.exponent = C.double(*opts.Exponent)
		}
	}

	ret := C.gen_vips_gamma(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GaussblurOptions are optional parameters for gaussblur.
type GaussblurOptions struct {
	MinAmpl *float64
	Precision *Precision
}

// vipsGenGaussblur calls the vips gaussblur operation.
// gaussian blur
func vipsGenGaussblur(input *C.VipsImage, sigma float64, opts *GaussblurOptions) (*C.VipsImage, error) {
	incOpCounter("gaussblur")

	var out_out *C.VipsImage

	var cOpts C.GenGaussblurOpts
	if opts != nil {
		if opts.MinAmpl != nil {
			cOpts.has_minAmpl = 1
			cOpts.minAmpl = C.double(*opts.MinAmpl)
		}
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
	}

	ret := C.gen_vips_gaussblur(input, C.double(sigma), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GaussmatOptions are optional parameters for gaussmat.
type GaussmatOptions struct {
	Separable *bool
	Precision *Precision
}

// vipsGenGaussmat calls the vips gaussmat operation.
// make a gaussian image
func vipsGenGaussmat(sigma float64, minAmpl float64, opts *GaussmatOptions) (*C.VipsImage, error) {
	incOpCounter("gaussmat")

	var out_out *C.VipsImage

	var cOpts C.GenGaussmatOpts
	if opts != nil {
		if opts.Separable != nil {
			cOpts.has_separable = 1
			cOpts.separable = C.int(boolToInt(*opts.Separable))
		}
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
	}

	ret := C.gen_vips_gaussmat(C.double(sigma), C.double(minAmpl), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GaussnoiseOptions are optional parameters for gaussnoise.
type GaussnoiseOptions struct {
	Sigma *float64
	Mean *float64
	Seed *int
}

// vipsGenGaussnoise calls the vips gaussnoise operation.
// make a gaussnoise image
func vipsGenGaussnoise(width int, height int, opts *GaussnoiseOptions) (*C.VipsImage, error) {
	incOpCounter("gaussnoise")

	var out_out *C.VipsImage

	var cOpts C.GenGaussnoiseOpts
	if opts != nil {
		if opts.Sigma != nil {
			cOpts.has_sigma = 1
			cOpts.sigma = C.double(*opts.Sigma)
		}
		if opts.Mean != nil {
			cOpts.has_mean = 1
			cOpts.mean = C.double(*opts.Mean)
		}
		if opts.Seed != nil {
			cOpts.has_seed = 1
			cOpts.seed = C.int(*opts.Seed)
		}
	}

	ret := C.gen_vips_gaussnoise(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GlobalbalanceOptions are optional parameters for globalbalance.
type GlobalbalanceOptions struct {
	Gamma *float64
	IntOutput *bool
}

// vipsGenGlobalbalance calls the vips globalbalance operation.
// global balance an image mosaic
func vipsGenGlobalbalance(input *C.VipsImage, opts *GlobalbalanceOptions) (*C.VipsImage, error) {
	incOpCounter("globalbalance")

	var out_out *C.VipsImage

	var cOpts C.GenGlobalbalanceOpts
	if opts != nil {
		if opts.Gamma != nil {
			cOpts.has_gamma = 1
			cOpts.gamma = C.double(*opts.Gamma)
		}
		if opts.IntOutput != nil {
			cOpts.has_intOutput = 1
			cOpts.intOutput = C.int(boolToInt(*opts.IntOutput))
		}
	}

	ret := C.gen_vips_globalbalance(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GravityOptions are optional parameters for gravity.
type GravityOptions struct {
	Extend *ExtendStrategy
	Background []float64
}

// vipsGenGravity calls the vips gravity operation.
// place an image within a larger image with a certain gravity
func vipsGenGravity(input *C.VipsImage, direction Gravity, width int, height int, opts *GravityOptions) (*C.VipsImage, error) {
	incOpCounter("gravity")

	var out_out *C.VipsImage

	var cOpts C.GenGravityOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Extend != nil {
			cOpts.has_extend = 1
			cOpts.extend = C.VipsExtend(*opts.Extend)
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
	}

	ret := C.gen_vips_gravity(input, C.VipsCompassDirection(direction), C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// GreyOptions are optional parameters for grey.
type GreyOptions struct {
	Uchar *bool
}

// vipsGenGrey calls the vips grey operation.
// make a grey ramp image
func vipsGenGrey(width int, height int, opts *GreyOptions) (*C.VipsImage, error) {
	incOpCounter("grey")

	var out_out *C.VipsImage

	var cOpts C.GenGreyOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
	}

	ret := C.gen_vips_grey(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenGrid calls the vips grid operation.
// grid an image
func vipsGenGrid(input *C.VipsImage, tileHeight int, across int, down int) (*C.VipsImage, error) {
	incOpCounter("grid")

	var out_out *C.VipsImage

	ret := C.gen_vips_grid(input, C.int(tileHeight), C.int(across), C.int(down), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistCum calls the vips hist_cum operation.
// form cumulative histogram
func vipsGenHistCum(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("hist_cum")

	var out_out *C.VipsImage

	ret := C.gen_vips_hist_cum(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistEntropy calls the vips hist_entropy operation.
// estimate image entropy
func vipsGenHistEntropy(input *C.VipsImage) (float64, error) {
	incOpCounter("hist_entropy")

	var out_out C.double

	ret := C.gen_vips_hist_entropy(input, &out_out)
	if ret != 0 {
		return 0, handleVipsError()
	}

	return float64(out_out), nil
}

// HistEqualOptions are optional parameters for hist_equal.
type HistEqualOptions struct {
	Band *int
}

// vipsGenHistEqual calls the vips hist_equal operation.
// histogram equalisation
func vipsGenHistEqual(input *C.VipsImage, opts *HistEqualOptions) (*C.VipsImage, error) {
	incOpCounter("hist_equal")

	var out_out *C.VipsImage

	var cOpts C.GenHistEqualOpts
	if opts != nil {
		if opts.Band != nil {
			cOpts.has_band = 1
			cOpts.band = C.int(*opts.Band)
		}
	}

	ret := C.gen_vips_hist_equal(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// HistFindOptions are optional parameters for hist_find.
type HistFindOptions struct {
	Band *int
}

// vipsGenHistFind calls the vips hist_find operation.
// find image histogram
func vipsGenHistFind(input *C.VipsImage, opts *HistFindOptions) (*C.VipsImage, error) {
	incOpCounter("hist_find")

	var out_out *C.VipsImage

	var cOpts C.GenHistFindOpts
	if opts != nil {
		if opts.Band != nil {
			cOpts.has_band = 1
			cOpts.band = C.int(*opts.Band)
		}
	}

	ret := C.gen_vips_hist_find(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// HistFindIndexedOptions are optional parameters for hist_find_indexed.
type HistFindIndexedOptions struct {
	Combine *Combine
}

// vipsGenHistFindIndexed calls the vips hist_find_indexed operation.
// find indexed image histogram
func vipsGenHistFindIndexed(input *C.VipsImage, index *C.VipsImage, opts *HistFindIndexedOptions) (*C.VipsImage, error) {
	incOpCounter("hist_find_indexed")

	var out_out *C.VipsImage

	var cOpts C.GenHistFindIndexedOpts
	if opts != nil {
		if opts.Combine != nil {
			cOpts.has_combine = 1
			cOpts.combine = C.VipsCombine(*opts.Combine)
		}
	}

	ret := C.gen_vips_hist_find_indexed(input, index, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// HistFindNdimOptions are optional parameters for hist_find_ndim.
type HistFindNdimOptions struct {
	Bins *int
}

// vipsGenHistFindNdim calls the vips hist_find_ndim operation.
// find n-dimensional image histogram
func vipsGenHistFindNdim(input *C.VipsImage, opts *HistFindNdimOptions) (*C.VipsImage, error) {
	incOpCounter("hist_find_ndim")

	var out_out *C.VipsImage

	var cOpts C.GenHistFindNdimOpts
	if opts != nil {
		if opts.Bins != nil {
			cOpts.has_bins = 1
			cOpts.bins = C.int(*opts.Bins)
		}
	}

	ret := C.gen_vips_hist_find_ndim(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistIsmonotonic calls the vips hist_ismonotonic operation.
// test for monotonicity
func vipsGenHistIsmonotonic(input *C.VipsImage) (bool, error) {
	incOpCounter("hist_ismonotonic")

	var out_monotonic C.int

	ret := C.gen_vips_hist_ismonotonic(input, &out_monotonic)
	if ret != 0 {
		return false, handleVipsError()
	}

	return out_monotonic != 0, nil
}

// HistLocalOptions are optional parameters for hist_local.
type HistLocalOptions struct {
	MaxSlope *int
}

// vipsGenHistLocal calls the vips hist_local operation.
// local histogram equalisation
func vipsGenHistLocal(input *C.VipsImage, width int, height int, opts *HistLocalOptions) (*C.VipsImage, error) {
	incOpCounter("hist_local")

	var out_out *C.VipsImage

	var cOpts C.GenHistLocalOpts
	if opts != nil {
		if opts.MaxSlope != nil {
			cOpts.has_maxSlope = 1
			cOpts.maxSlope = C.int(*opts.MaxSlope)
		}
	}

	ret := C.gen_vips_hist_local(input, C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistMatch calls the vips hist_match operation.
// match two histograms
func vipsGenHistMatch(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("hist_match")

	var out_out *C.VipsImage

	ret := C.gen_vips_hist_match(input, ref, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistNorm calls the vips hist_norm operation.
// normalise histogram
func vipsGenHistNorm(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("hist_norm")

	var out_out *C.VipsImage

	ret := C.gen_vips_hist_norm(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenHistPlot calls the vips hist_plot operation.
// plot histogram
func vipsGenHistPlot(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("hist_plot")

	var out_out *C.VipsImage

	ret := C.gen_vips_hist_plot(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// HoughCircleOptions are optional parameters for hough_circle.
type HoughCircleOptions struct {
	Scale *int
	MinRadius *int
	MaxRadius *int
}

// vipsGenHoughCircle calls the vips hough_circle operation.
// find hough circle transform
func vipsGenHoughCircle(input *C.VipsImage, opts *HoughCircleOptions) (*C.VipsImage, error) {
	incOpCounter("hough_circle")

	var out_out *C.VipsImage

	var cOpts C.GenHoughCircleOpts
	if opts != nil {
		if opts.Scale != nil {
			cOpts.has_scale = 1
			cOpts.scale = C.int(*opts.Scale)
		}
		if opts.MinRadius != nil {
			cOpts.has_minRadius = 1
			cOpts.minRadius = C.int(*opts.MinRadius)
		}
		if opts.MaxRadius != nil {
			cOpts.has_maxRadius = 1
			cOpts.maxRadius = C.int(*opts.MaxRadius)
		}
	}

	ret := C.gen_vips_hough_circle(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// HoughLineOptions are optional parameters for hough_line.
type HoughLineOptions struct {
	Width *int
	Height *int
}

// vipsGenHoughLine calls the vips hough_line operation.
// find hough line transform
func vipsGenHoughLine(input *C.VipsImage, opts *HoughLineOptions) (*C.VipsImage, error) {
	incOpCounter("hough_line")

	var out_out *C.VipsImage

	var cOpts C.GenHoughLineOpts
	if opts != nil {
		if opts.Width != nil {
			cOpts.has_width = 1
			cOpts.width = C.int(*opts.Width)
		}
		if opts.Height != nil {
			cOpts.has_height = 1
			cOpts.height = C.int(*opts.Height)
		}
	}

	ret := C.gen_vips_hough_line(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// IccExportOptions are optional parameters for icc_export.
type IccExportOptions struct {
	Pcs *int
	Intent *Intent
	BlackPointCompensation *bool
	OutputProfile *string
	Depth *int
}

// vipsGenIccExport calls the vips icc_export operation.
// output to device with ICC profile
func vipsGenIccExport(input *C.VipsImage, opts *IccExportOptions) (*C.VipsImage, error) {
	incOpCounter("icc_export")

	var out_out *C.VipsImage

	var cOpts C.GenIccExportOpts
	if opts != nil {
		if opts.Pcs != nil {
			cOpts.has_pcs = 1
			cOpts.pcs = C.VipsPCS(*opts.Pcs)
		}
		if opts.Intent != nil {
			cOpts.has_intent = 1
			cOpts.intent = C.VipsIntent(*opts.Intent)
		}
		if opts.BlackPointCompensation != nil {
			cOpts.has_blackPointCompensation = 1
			cOpts.blackPointCompensation = C.int(boolToInt(*opts.BlackPointCompensation))
		}
		if opts.OutputProfile != nil {
			cOpts.has_outputProfile = 1
			tmp_outputProfile := C.CString(*opts.OutputProfile)
			defer C.free(unsafe.Pointer(tmp_outputProfile))
			cOpts.outputProfile = tmp_outputProfile
		}
		if opts.Depth != nil {
			cOpts.has_depth = 1
			cOpts.depth = C.int(*opts.Depth)
		}
	}

	ret := C.gen_vips_icc_export(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// IccImportOptions are optional parameters for icc_import.
type IccImportOptions struct {
	Pcs *int
	Intent *Intent
	BlackPointCompensation *bool
	Embedded *bool
	InputProfile *string
}

// vipsGenIccImport calls the vips icc_import operation.
// import from device with ICC profile
func vipsGenIccImport(input *C.VipsImage, opts *IccImportOptions) (*C.VipsImage, error) {
	incOpCounter("icc_import")

	var out_out *C.VipsImage

	var cOpts C.GenIccImportOpts
	if opts != nil {
		if opts.Pcs != nil {
			cOpts.has_pcs = 1
			cOpts.pcs = C.VipsPCS(*opts.Pcs)
		}
		if opts.Intent != nil {
			cOpts.has_intent = 1
			cOpts.intent = C.VipsIntent(*opts.Intent)
		}
		if opts.BlackPointCompensation != nil {
			cOpts.has_blackPointCompensation = 1
			cOpts.blackPointCompensation = C.int(boolToInt(*opts.BlackPointCompensation))
		}
		if opts.Embedded != nil {
			cOpts.has_embedded = 1
			cOpts.embedded = C.int(boolToInt(*opts.Embedded))
		}
		if opts.InputProfile != nil {
			cOpts.has_inputProfile = 1
			tmp_inputProfile := C.CString(*opts.InputProfile)
			defer C.free(unsafe.Pointer(tmp_inputProfile))
			cOpts.inputProfile = tmp_inputProfile
		}
	}

	ret := C.gen_vips_icc_import(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// IdentityOptions are optional parameters for identity.
type IdentityOptions struct {
	Bands *int
	Ushort *bool
	Size *int
}

// vipsGenIdentity calls the vips identity operation.
// make a 1D image where pixel values are indexes
func vipsGenIdentity(opts *IdentityOptions) (*C.VipsImage, error) {
	incOpCounter("identity")

	var out_out *C.VipsImage

	var cOpts C.GenIdentityOpts
	if opts != nil {
		if opts.Bands != nil {
			cOpts.has_bands = 1
			cOpts.bands = C.int(*opts.Bands)
		}
		if opts.Ushort != nil {
			cOpts.has_ushort = 1
			cOpts.ushort = C.int(boolToInt(*opts.Ushort))
		}
		if opts.Size != nil {
			cOpts.has_size = 1
			cOpts.size = C.int(*opts.Size)
		}
	}

	ret := C.gen_vips_identity(&out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// IfthenelseOptions are optional parameters for ifthenelse.
type IfthenelseOptions struct {
	Blend *bool
}

// vipsGenIfthenelse calls the vips ifthenelse operation.
// ifthenelse an image
func vipsGenIfthenelse(cond *C.VipsImage, in1 *C.VipsImage, in2 *C.VipsImage, opts *IfthenelseOptions) (*C.VipsImage, error) {
	incOpCounter("ifthenelse")

	var out_out *C.VipsImage

	var cOpts C.GenIfthenelseOpts
	if opts != nil {
		if opts.Blend != nil {
			cOpts.has_blend = 1
			cOpts.blend = C.int(boolToInt(*opts.Blend))
		}
	}

	ret := C.gen_vips_ifthenelse(cond, in1, in2, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// InsertOptions are optional parameters for insert.
type InsertOptions struct {
	Expand *bool
	Background []float64
}

// vipsGenInsert calls the vips insert operation.
// insert image @sub into @main at @x, @y
func vipsGenInsert(main *C.VipsImage, sub *C.VipsImage, x int, y int, opts *InsertOptions) (*C.VipsImage, error) {
	incOpCounter("insert")

	var out_out *C.VipsImage

	var cOpts C.GenInsertOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Expand != nil {
			cOpts.has_expand = 1
			cOpts.expand = C.int(boolToInt(*opts.Expand))
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
	}

	ret := C.gen_vips_insert(main, sub, C.int(x), C.int(y), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenInvert calls the vips invert operation.
// invert an image
func vipsGenInvert(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("invert")

	var out_out *C.VipsImage

	ret := C.gen_vips_invert(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// InvertlutOptions are optional parameters for invertlut.
type InvertlutOptions struct {
	Size *int
}

// vipsGenInvertlut calls the vips invertlut operation.
// build an inverted look-up table
func vipsGenInvertlut(input *C.VipsImage, opts *InvertlutOptions) (*C.VipsImage, error) {
	incOpCounter("invertlut")

	var out_out *C.VipsImage

	var cOpts C.GenInvertlutOpts
	if opts != nil {
		if opts.Size != nil {
			cOpts.has_size = 1
			cOpts.size = C.int(*opts.Size)
		}
	}

	ret := C.gen_vips_invertlut(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// InvfftOptions are optional parameters for invfft.
type InvfftOptions struct {
	Real *bool
}

// vipsGenInvfft calls the vips invfft operation.
// inverse FFT
func vipsGenInvfft(input *C.VipsImage, opts *InvfftOptions) (*C.VipsImage, error) {
	incOpCounter("invfft")

	var out_out *C.VipsImage

	var cOpts C.GenInvfftOpts
	if opts != nil {
		if opts.Real != nil {
			cOpts.has_real = 1
			cOpts.real = C.int(boolToInt(*opts.Real))
		}
	}

	ret := C.gen_vips_invfft(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// JoinOptions are optional parameters for join.
type JoinOptions struct {
	Expand *bool
	Shim *int
	Background []float64
	Align *Align
}

// vipsGenJoin calls the vips join operation.
// join a pair of images
func vipsGenJoin(in1 *C.VipsImage, in2 *C.VipsImage, direction Direction, opts *JoinOptions) (*C.VipsImage, error) {
	incOpCounter("join")

	var out_out *C.VipsImage

	var cOpts C.GenJoinOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Expand != nil {
			cOpts.has_expand = 1
			cOpts.expand = C.int(boolToInt(*opts.Expand))
		}
		if opts.Shim != nil {
			cOpts.has_shim = 1
			cOpts.shim = C.int(*opts.Shim)
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Align != nil {
			cOpts.has_align = 1
			cOpts.align = C.VipsAlign(*opts.Align)
		}
	}

	ret := C.gen_vips_join(in1, in2, C.VipsDirection(direction), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenLabelregions calls the vips labelregions operation.
// label regions in an image
func vipsGenLabelregions(input *C.VipsImage) (*C.VipsImage, int, error) {
	incOpCounter("labelregions")

	var out_mask *C.VipsImage
	var out_segments C.int

	ret := C.gen_vips_labelregions(input, &out_mask, &out_segments)
	if ret != 0 {
		return nil, 0, handleImageError(out_mask)
	}

	return out_mask, int(out_segments), nil
}

// LinearOptions are optional parameters for linear.
type LinearOptions struct {
	Uchar *bool
}

// vipsGenLinear calls the vips linear operation.
// calculate (a * in + b)
func vipsGenLinear(input *C.VipsImage, a []float64, b []float64, opts *LinearOptions) (*C.VipsImage, error) {
	incOpCounter("linear")

	var out_out *C.VipsImage

	var cOpts C.GenLinearOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
	}

	ret := C.gen_vips_linear(input, (*C.double)(unsafe.Pointer(&a[0])), C.int(len(a)), (*C.double)(unsafe.Pointer(&b[0])), C.int(len(b)), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// LinecacheOptions are optional parameters for linecache.
type LinecacheOptions struct {
	TileHeight *int
	Access *int
	Threaded *bool
	Persistent *bool
}

// vipsGenLinecache calls the vips linecache operation.
// cache an image as a set of lines
func vipsGenLinecache(input *C.VipsImage, opts *LinecacheOptions) (*C.VipsImage, error) {
	incOpCounter("linecache")

	var out_out *C.VipsImage

	var cOpts C.GenLinecacheOpts
	if opts != nil {
		if opts.TileHeight != nil {
			cOpts.has_tileHeight = 1
			cOpts.tileHeight = C.int(*opts.TileHeight)
		}
		if opts.Access != nil {
			cOpts.has_access = 1
			cOpts.access = C.VipsAccess(*opts.Access)
		}
		if opts.Threaded != nil {
			cOpts.has_threaded = 1
			cOpts.threaded = C.int(boolToInt(*opts.Threaded))
		}
		if opts.Persistent != nil {
			cOpts.has_persistent = 1
			cOpts.persistent = C.int(boolToInt(*opts.Persistent))
		}
	}

	ret := C.gen_vips_linecache(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// LogmatOptions are optional parameters for logmat.
type LogmatOptions struct {
	Separable *bool
	Precision *Precision
}

// vipsGenLogmat calls the vips logmat operation.
// make a Laplacian of Gaussian image
func vipsGenLogmat(sigma float64, minAmpl float64, opts *LogmatOptions) (*C.VipsImage, error) {
	incOpCounter("logmat")

	var out_out *C.VipsImage

	var cOpts C.GenLogmatOpts
	if opts != nil {
		if opts.Separable != nil {
			cOpts.has_separable = 1
			cOpts.separable = C.int(boolToInt(*opts.Separable))
		}
		if opts.Precision != nil {
			cOpts.has_precision = 1
			cOpts.precision = C.VipsPrecision(*opts.Precision)
		}
	}

	ret := C.gen_vips_logmat(C.double(sigma), C.double(minAmpl), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MapimOptions are optional parameters for mapim.
type MapimOptions struct {
	Interpolate *C.VipsInterpolate
	Background []float64
	Premultiplied *bool
	Extend *ExtendStrategy
}

// vipsGenMapim calls the vips mapim operation.
// resample with a map image
func vipsGenMapim(input *C.VipsImage, index *C.VipsImage, opts *MapimOptions) (*C.VipsImage, error) {
	incOpCounter("mapim")

	var out_out *C.VipsImage

	var cOpts C.GenMapimOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Premultiplied != nil {
			cOpts.has_premultiplied = 1
			cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied))
		}
		if opts.Extend != nil {
			cOpts.has_extend = 1
			cOpts.extend = C.VipsExtend(*opts.Extend)
		}
	}

	ret := C.gen_vips_mapim(input, index, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaplutOptions are optional parameters for maplut.
type MaplutOptions struct {
	Band *int
}

// vipsGenMaplut calls the vips maplut operation.
// map an image though a lut
func vipsGenMaplut(input *C.VipsImage, lut *C.VipsImage, opts *MaplutOptions) (*C.VipsImage, error) {
	incOpCounter("maplut")

	var out_out *C.VipsImage

	var cOpts C.GenMaplutOpts
	if opts != nil {
		if opts.Band != nil {
			cOpts.has_band = 1
			cOpts.band = C.int(*opts.Band)
		}
	}

	ret := C.gen_vips_maplut(input, lut, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskButterworthOptions are optional parameters for mask_butterworth.
type MaskButterworthOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskButterworth calls the vips mask_butterworth operation.
// make a butterworth filter
func vipsGenMaskButterworth(width int, height int, order float64, frequencyCutoff float64, amplitudeCutoff float64, opts *MaskButterworthOptions) (*C.VipsImage, error) {
	incOpCounter("mask_butterworth")

	var out_out *C.VipsImage

	var cOpts C.GenMaskButterworthOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_butterworth(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoff), C.double(amplitudeCutoff), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskButterworthBandOptions are optional parameters for mask_butterworth_band.
type MaskButterworthBandOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskButterworthBand calls the vips mask_butterworth_band operation.
// make a butterworth_band filter
func vipsGenMaskButterworthBand(width int, height int, order float64, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, amplitudeCutoff float64, opts *MaskButterworthBandOptions) (*C.VipsImage, error) {
	incOpCounter("mask_butterworth_band")

	var out_out *C.VipsImage

	var cOpts C.GenMaskButterworthBandOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_butterworth_band(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), C.double(amplitudeCutoff), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskButterworthRingOptions are optional parameters for mask_butterworth_ring.
type MaskButterworthRingOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskButterworthRing calls the vips mask_butterworth_ring operation.
// make a butterworth ring filter
func vipsGenMaskButterworthRing(width int, height int, order float64, frequencyCutoff float64, amplitudeCutoff float64, ringwidth float64, opts *MaskButterworthRingOptions) (*C.VipsImage, error) {
	incOpCounter("mask_butterworth_ring")

	var out_out *C.VipsImage

	var cOpts C.GenMaskButterworthRingOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_butterworth_ring(C.int(width), C.int(height), C.double(order), C.double(frequencyCutoff), C.double(amplitudeCutoff), C.double(ringwidth), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskFractalOptions are optional parameters for mask_fractal.
type MaskFractalOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskFractal calls the vips mask_fractal operation.
// make fractal filter
func vipsGenMaskFractal(width int, height int, fractalDimension float64, opts *MaskFractalOptions) (*C.VipsImage, error) {
	incOpCounter("mask_fractal")

	var out_out *C.VipsImage

	var cOpts C.GenMaskFractalOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_fractal(C.int(width), C.int(height), C.double(fractalDimension), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskGaussianOptions are optional parameters for mask_gaussian.
type MaskGaussianOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskGaussian calls the vips mask_gaussian operation.
// make a gaussian filter
func vipsGenMaskGaussian(width int, height int, frequencyCutoff float64, amplitudeCutoff float64, opts *MaskGaussianOptions) (*C.VipsImage, error) {
	incOpCounter("mask_gaussian")

	var out_out *C.VipsImage

	var cOpts C.GenMaskGaussianOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_gaussian(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(amplitudeCutoff), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskGaussianBandOptions are optional parameters for mask_gaussian_band.
type MaskGaussianBandOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskGaussianBand calls the vips mask_gaussian_band operation.
// make a gaussian filter
func vipsGenMaskGaussianBand(width int, height int, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, amplitudeCutoff float64, opts *MaskGaussianBandOptions) (*C.VipsImage, error) {
	incOpCounter("mask_gaussian_band")

	var out_out *C.VipsImage

	var cOpts C.GenMaskGaussianBandOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_gaussian_band(C.int(width), C.int(height), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), C.double(amplitudeCutoff), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskGaussianRingOptions are optional parameters for mask_gaussian_ring.
type MaskGaussianRingOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskGaussianRing calls the vips mask_gaussian_ring operation.
// make a gaussian ring filter
func vipsGenMaskGaussianRing(width int, height int, frequencyCutoff float64, amplitudeCutoff float64, ringwidth float64, opts *MaskGaussianRingOptions) (*C.VipsImage, error) {
	incOpCounter("mask_gaussian_ring")

	var out_out *C.VipsImage

	var cOpts C.GenMaskGaussianRingOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_gaussian_ring(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(amplitudeCutoff), C.double(ringwidth), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskIdealOptions are optional parameters for mask_ideal.
type MaskIdealOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskIdeal calls the vips mask_ideal operation.
// make an ideal filter
func vipsGenMaskIdeal(width int, height int, frequencyCutoff float64, opts *MaskIdealOptions) (*C.VipsImage, error) {
	incOpCounter("mask_ideal")

	var out_out *C.VipsImage

	var cOpts C.GenMaskIdealOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_ideal(C.int(width), C.int(height), C.double(frequencyCutoff), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskIdealBandOptions are optional parameters for mask_ideal_band.
type MaskIdealBandOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskIdealBand calls the vips mask_ideal_band operation.
// make an ideal band filter
func vipsGenMaskIdealBand(width int, height int, frequencyCutoffX float64, frequencyCutoffY float64, radius float64, opts *MaskIdealBandOptions) (*C.VipsImage, error) {
	incOpCounter("mask_ideal_band")

	var out_out *C.VipsImage

	var cOpts C.GenMaskIdealBandOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_ideal_band(C.int(width), C.int(height), C.double(frequencyCutoffX), C.double(frequencyCutoffY), C.double(radius), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MaskIdealRingOptions are optional parameters for mask_ideal_ring.
type MaskIdealRingOptions struct {
	Uchar *bool
	Nodc *bool
	Reject *bool
	Optical *bool
}

// vipsGenMaskIdealRing calls the vips mask_ideal_ring operation.
// make an ideal ring filter
func vipsGenMaskIdealRing(width int, height int, frequencyCutoff float64, ringwidth float64, opts *MaskIdealRingOptions) (*C.VipsImage, error) {
	incOpCounter("mask_ideal_ring")

	var out_out *C.VipsImage

	var cOpts C.GenMaskIdealRingOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Nodc != nil {
			cOpts.has_nodc = 1
			cOpts.nodc = C.int(boolToInt(*opts.Nodc))
		}
		if opts.Reject != nil {
			cOpts.has_reject = 1
			cOpts.reject = C.int(boolToInt(*opts.Reject))
		}
		if opts.Optical != nil {
			cOpts.has_optical = 1
			cOpts.optical = C.int(boolToInt(*opts.Optical))
		}
	}

	ret := C.gen_vips_mask_ideal_ring(C.int(width), C.int(height), C.double(frequencyCutoff), C.double(ringwidth), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MatchOptions are optional parameters for match.
type MatchOptions struct {
	Hwindow *int
	Harea *int
	Search *bool
	Interpolate *C.VipsInterpolate
}

// vipsGenMatch calls the vips match operation.
// first-order match of two images
func vipsGenMatch(ref *C.VipsImage, sec *C.VipsImage, xr1 int, yr1 int, xs1 int, ys1 int, xr2 int, yr2 int, xs2 int, ys2 int, opts *MatchOptions) (*C.VipsImage, error) {
	incOpCounter("match")

	var out_out *C.VipsImage

	var cOpts C.GenMatchOpts
	if opts != nil {
		if opts.Hwindow != nil {
			cOpts.has_hwindow = 1
			cOpts.hwindow = C.int(*opts.Hwindow)
		}
		if opts.Harea != nil {
			cOpts.has_harea = 1
			cOpts.harea = C.int(*opts.Harea)
		}
		if opts.Search != nil {
			cOpts.has_search = 1
			cOpts.search = C.int(boolToInt(*opts.Search))
		}
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
	}

	ret := C.gen_vips_match(ref, sec, C.int(xr1), C.int(yr1), C.int(xs1), C.int(ys1), C.int(xr2), C.int(yr2), C.int(xs2), C.int(ys2), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMath calls the vips math operation.
// apply a math operation to an image
func vipsGenMath(input *C.VipsImage, math OperationMath) (*C.VipsImage, error) {
	incOpCounter("math")

	var out_out *C.VipsImage

	ret := C.gen_vips_math(input, C.VipsOperationMath(math), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMath2 calls the vips math2 operation.
// binary math operations
func vipsGenMath2(left *C.VipsImage, right *C.VipsImage, math2 OperationMath2) (*C.VipsImage, error) {
	incOpCounter("math2")

	var out_out *C.VipsImage

	ret := C.gen_vips_math2(left, right, C.VipsOperationMath2(math2), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMath2Const calls the vips math2_const operation.
// binary math operations with a constant
func vipsGenMath2Const(input *C.VipsImage, math2 OperationMath2, c []float64) (*C.VipsImage, error) {
	incOpCounter("math2_const")

	var out_out *C.VipsImage

	ret := C.gen_vips_math2_const(input, C.VipsOperationMath2(math2), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMatrixinvert calls the vips matrixinvert operation.
// invert a matrix
func vipsGenMatrixinvert(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("matrixinvert")

	var out_out *C.VipsImage

	ret := C.gen_vips_matrixinvert(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMatrixmultiply calls the vips matrixmultiply operation.
// multiply two matrices
func vipsGenMatrixmultiply(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("matrixmultiply")

	var out_out *C.VipsImage

	ret := C.gen_vips_matrixmultiply(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMaxpair calls the vips maxpair operation.
// maximum of a pair of images
func vipsGenMaxpair(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("maxpair")

	var out_out *C.VipsImage

	ret := C.gen_vips_maxpair(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MergeOptions are optional parameters for merge.
type MergeOptions struct {
	Mblend *int
}

// vipsGenMerge calls the vips merge operation.
// merge two images
func vipsGenMerge(ref *C.VipsImage, sec *C.VipsImage, direction Direction, dx int, dy int, opts *MergeOptions) (*C.VipsImage, error) {
	incOpCounter("merge")

	var out_out *C.VipsImage

	var cOpts C.GenMergeOpts
	if opts != nil {
		if opts.Mblend != nil {
			cOpts.has_mblend = 1
			cOpts.mblend = C.int(*opts.Mblend)
		}
	}

	ret := C.gen_vips_merge(ref, sec, C.VipsDirection(direction), C.int(dx), C.int(dy), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMinpair calls the vips minpair operation.
// minimum of a pair of images
func vipsGenMinpair(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("minpair")

	var out_out *C.VipsImage

	ret := C.gen_vips_minpair(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMorph calls the vips morph operation.
// morphology operation
func vipsGenMorph(input *C.VipsImage, mask *C.VipsImage, morph OperationMorphology) (*C.VipsImage, error) {
	incOpCounter("morph")

	var out_out *C.VipsImage

	ret := C.gen_vips_morph(input, mask, C.VipsOperationMorphology(morph), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MosaicOptions are optional parameters for mosaic.
type MosaicOptions struct {
	Hwindow *int
	Harea *int
	Mblend *int
	Bandno *int
}

// vipsGenMosaic calls the vips mosaic operation.
// mosaic two images
func vipsGenMosaic(ref *C.VipsImage, sec *C.VipsImage, direction Direction, xref int, yref int, xsec int, ysec int, opts *MosaicOptions) (*C.VipsImage, int, int, float64, float64, float64, float64, error) {
	incOpCounter("mosaic")

	var out_out *C.VipsImage
	var out_dx0 C.int
	var out_dy0 C.int
	var out_scale1 C.double
	var out_angle1 C.double
	var out_dy1 C.double
	var out_dx1 C.double

	var cOpts C.GenMosaicOpts
	if opts != nil {
		if opts.Hwindow != nil {
			cOpts.has_hwindow = 1
			cOpts.hwindow = C.int(*opts.Hwindow)
		}
		if opts.Harea != nil {
			cOpts.has_harea = 1
			cOpts.harea = C.int(*opts.Harea)
		}
		if opts.Mblend != nil {
			cOpts.has_mblend = 1
			cOpts.mblend = C.int(*opts.Mblend)
		}
		if opts.Bandno != nil {
			cOpts.has_bandno = 1
			cOpts.bandno = C.int(*opts.Bandno)
		}
	}

	ret := C.gen_vips_mosaic(ref, sec, C.VipsDirection(direction), C.int(xref), C.int(yref), C.int(xsec), C.int(ysec), &out_out, &out_dx0, &out_dy0, &out_scale1, &out_angle1, &out_dy1, &out_dx1, &cOpts)
	if ret != 0 {
		return nil, 0, 0, 0, 0, 0, 0, handleImageError(out_out)
	}

	return out_out, int(out_dx0), int(out_dy0), float64(out_scale1), float64(out_angle1), float64(out_dy1), float64(out_dx1), nil
}

// Mosaic1Options are optional parameters for mosaic1.
type Mosaic1Options struct {
	Hwindow *int
	Harea *int
	Search *bool
	Interpolate *C.VipsInterpolate
	Mblend *int
}

// vipsGenMosaic1 calls the vips mosaic1 operation.
// first-order mosaic of two images
func vipsGenMosaic1(ref *C.VipsImage, sec *C.VipsImage, direction Direction, xr1 int, yr1 int, xs1 int, ys1 int, xr2 int, yr2 int, xs2 int, ys2 int, opts *Mosaic1Options) (*C.VipsImage, error) {
	incOpCounter("mosaic1")

	var out_out *C.VipsImage

	var cOpts C.GenMosaic1Opts
	if opts != nil {
		if opts.Hwindow != nil {
			cOpts.has_hwindow = 1
			cOpts.hwindow = C.int(*opts.Hwindow)
		}
		if opts.Harea != nil {
			cOpts.has_harea = 1
			cOpts.harea = C.int(*opts.Harea)
		}
		if opts.Search != nil {
			cOpts.has_search = 1
			cOpts.search = C.int(boolToInt(*opts.Search))
		}
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
		if opts.Mblend != nil {
			cOpts.has_mblend = 1
			cOpts.mblend = C.int(*opts.Mblend)
		}
	}

	ret := C.gen_vips_mosaic1(ref, sec, C.VipsDirection(direction), C.int(xr1), C.int(yr1), C.int(xs1), C.int(ys1), C.int(xr2), C.int(yr2), C.int(xs2), C.int(ys2), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// MsbOptions are optional parameters for msb.
type MsbOptions struct {
	Band *int
}

// vipsGenMsb calls the vips msb operation.
// pick most-significant byte from an image
func vipsGenMsb(input *C.VipsImage, opts *MsbOptions) (*C.VipsImage, error) {
	incOpCounter("msb")

	var out_out *C.VipsImage

	var cOpts C.GenMsbOpts
	if opts != nil {
		if opts.Band != nil {
			cOpts.has_band = 1
			cOpts.band = C.int(*opts.Band)
		}
	}

	ret := C.gen_vips_msb(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenMultiply calls the vips multiply operation.
// multiply two images
func vipsGenMultiply(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("multiply")

	var out_out *C.VipsImage

	ret := C.gen_vips_multiply(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenPercent calls the vips percent operation.
// find threshold for percent of pixels
func vipsGenPercent(input *C.VipsImage, percent float64) (int, error) {
	incOpCounter("percent")

	var out_threshold C.int

	ret := C.gen_vips_percent(input, C.double(percent), &out_threshold)
	if ret != 0 {
		return 0, handleVipsError()
	}

	return int(out_threshold), nil
}

// PerlinOptions are optional parameters for perlin.
type PerlinOptions struct {
	CellSize *int
	Uchar *bool
	Seed *int
}

// vipsGenPerlin calls the vips perlin operation.
// make a perlin noise image
func vipsGenPerlin(width int, height int, opts *PerlinOptions) (*C.VipsImage, error) {
	incOpCounter("perlin")

	var out_out *C.VipsImage

	var cOpts C.GenPerlinOpts
	if opts != nil {
		if opts.CellSize != nil {
			cOpts.has_cellSize = 1
			cOpts.cellSize = C.int(*opts.CellSize)
		}
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Seed != nil {
			cOpts.has_seed = 1
			cOpts.seed = C.int(*opts.Seed)
		}
	}

	ret := C.gen_vips_perlin(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenPhasecor calls the vips phasecor operation.
// calculate phase correlation
func vipsGenPhasecor(input *C.VipsImage, in2 *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("phasecor")

	var out_out *C.VipsImage

	ret := C.gen_vips_phasecor(input, in2, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// PremultiplyOptions are optional parameters for premultiply.
type PremultiplyOptions struct {
	MaxAlpha *float64
}

// vipsGenPremultiply calls the vips premultiply operation.
// premultiply image alpha
func vipsGenPremultiply(input *C.VipsImage, opts *PremultiplyOptions) (*C.VipsImage, error) {
	incOpCounter("premultiply")

	var out_out *C.VipsImage

	var cOpts C.GenPremultiplyOpts
	if opts != nil {
		if opts.MaxAlpha != nil {
			cOpts.has_maxAlpha = 1
			cOpts.maxAlpha = C.double(*opts.MaxAlpha)
		}
	}

	ret := C.gen_vips_premultiply(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenPrewitt calls the vips prewitt operation.
// Prewitt edge detector
func vipsGenPrewitt(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("prewitt")

	var out_out *C.VipsImage

	ret := C.gen_vips_prewitt(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenProfile calls the vips profile operation.
// find image profiles
func vipsGenProfile(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) {
	incOpCounter("profile")

	var out_columns *C.VipsImage
	var out_rows *C.VipsImage

	ret := C.gen_vips_profile(input, &out_columns, &out_rows)
	if ret != 0 {
		return nil, nil, handleImageError(out_columns)
	}

	return out_columns, out_rows, nil
}

// vipsGenProject calls the vips project operation.
// find image projections
func vipsGenProject(input *C.VipsImage) (*C.VipsImage, *C.VipsImage, error) {
	incOpCounter("project")

	var out_columns *C.VipsImage
	var out_rows *C.VipsImage

	ret := C.gen_vips_project(input, &out_columns, &out_rows)
	if ret != 0 {
		return nil, nil, handleImageError(out_columns)
	}

	return out_columns, out_rows, nil
}

// QuadraticOptions are optional parameters for quadratic.
type QuadraticOptions struct {
	Interpolate *C.VipsInterpolate
}

// vipsGenQuadratic calls the vips quadratic operation.
// resample an image with a quadratic transform
func vipsGenQuadratic(input *C.VipsImage, coeff *C.VipsImage, opts *QuadraticOptions) (*C.VipsImage, error) {
	incOpCounter("quadratic")

	var out_out *C.VipsImage

	var cOpts C.GenQuadraticOpts
	if opts != nil {
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
	}

	ret := C.gen_vips_quadratic(input, coeff, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRad2float calls the vips rad2float operation.
// unpack Radiance coding to float RGB
func vipsGenRad2float(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("rad2float")

	var out_out *C.VipsImage

	ret := C.gen_vips_rad2float(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRank calls the vips rank operation.
// rank filter
func vipsGenRank(input *C.VipsImage, width int, height int, index int) (*C.VipsImage, error) {
	incOpCounter("rank")

	var out_out *C.VipsImage

	ret := C.gen_vips_rank(input, C.int(width), C.int(height), C.int(index), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRecomb calls the vips recomb operation.
// linear recombination with matrix
func vipsGenRecomb(input *C.VipsImage, m *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("recomb")

	var out_out *C.VipsImage

	ret := C.gen_vips_recomb(input, m, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ReduceOptions are optional parameters for reduce.
type ReduceOptions struct {
	Kernel *Kernel
	Gap *float64
}

// vipsGenReduce calls the vips reduce operation.
// reduce an image
func vipsGenReduce(input *C.VipsImage, hshrink float64, vshrink float64, opts *ReduceOptions) (*C.VipsImage, error) {
	incOpCounter("reduce")

	var out_out *C.VipsImage

	var cOpts C.GenReduceOpts
	if opts != nil {
		if opts.Kernel != nil {
			cOpts.has_kernel = 1
			cOpts.kernel = C.VipsKernel(*opts.Kernel)
		}
		if opts.Gap != nil {
			cOpts.has_gap = 1
			cOpts.gap = C.double(*opts.Gap)
		}
	}

	ret := C.gen_vips_reduce(input, C.double(hshrink), C.double(vshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ReducehOptions are optional parameters for reduceh.
type ReducehOptions struct {
	Kernel *Kernel
	Gap *float64
}

// vipsGenReduceh calls the vips reduceh operation.
// shrink an image horizontally
func vipsGenReduceh(input *C.VipsImage, hshrink float64, opts *ReducehOptions) (*C.VipsImage, error) {
	incOpCounter("reduceh")

	var out_out *C.VipsImage

	var cOpts C.GenReducehOpts
	if opts != nil {
		if opts.Kernel != nil {
			cOpts.has_kernel = 1
			cOpts.kernel = C.VipsKernel(*opts.Kernel)
		}
		if opts.Gap != nil {
			cOpts.has_gap = 1
			cOpts.gap = C.double(*opts.Gap)
		}
	}

	ret := C.gen_vips_reduceh(input, C.double(hshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ReducevOptions are optional parameters for reducev.
type ReducevOptions struct {
	Kernel *Kernel
	Gap *float64
}

// vipsGenReducev calls the vips reducev operation.
// shrink an image vertically
func vipsGenReducev(input *C.VipsImage, vshrink float64, opts *ReducevOptions) (*C.VipsImage, error) {
	incOpCounter("reducev")

	var out_out *C.VipsImage

	var cOpts C.GenReducevOpts
	if opts != nil {
		if opts.Kernel != nil {
			cOpts.has_kernel = 1
			cOpts.kernel = C.VipsKernel(*opts.Kernel)
		}
		if opts.Gap != nil {
			cOpts.has_gap = 1
			cOpts.gap = C.double(*opts.Gap)
		}
	}

	ret := C.gen_vips_reducev(input, C.double(vshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRelational calls the vips relational operation.
// relational operation on two images
func vipsGenRelational(left *C.VipsImage, right *C.VipsImage, relational OperationRelational) (*C.VipsImage, error) {
	incOpCounter("relational")

	var out_out *C.VipsImage

	ret := C.gen_vips_relational(left, right, C.VipsOperationRelational(relational), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRelationalConst calls the vips relational_const operation.
// relational operations against a constant
func vipsGenRelationalConst(input *C.VipsImage, relational OperationRelational, c []float64) (*C.VipsImage, error) {
	incOpCounter("relational_const")

	var out_out *C.VipsImage

	ret := C.gen_vips_relational_const(input, C.VipsOperationRelational(relational), (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRemainder calls the vips remainder operation.
// remainder after integer division of two images
func vipsGenRemainder(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("remainder")

	var out_out *C.VipsImage

	ret := C.gen_vips_remainder(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRemainderConst calls the vips remainder_const operation.
// remainder after integer division of an image and a constant
func vipsGenRemainderConst(input *C.VipsImage, c []float64) (*C.VipsImage, error) {
	incOpCounter("remainder_const")

	var out_out *C.VipsImage

	ret := C.gen_vips_remainder_const(input, (*C.double)(unsafe.Pointer(&c[0])), C.int(len(c)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRemosaic calls the vips remosaic operation.
// rebuild an mosaiced image
func vipsGenRemosaic(input *C.VipsImage, oldStr string, newStr string) (*C.VipsImage, error) {
	incOpCounter("remosaic")

	cStr_oldStr := C.CString(oldStr)
	defer C.free(unsafe.Pointer(cStr_oldStr))
	cStr_newStr := C.CString(newStr)
	defer C.free(unsafe.Pointer(cStr_newStr))
	var out_out *C.VipsImage

	ret := C.gen_vips_remosaic(input, cStr_oldStr, cStr_newStr, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenReplicate calls the vips replicate operation.
// replicate an image
func vipsGenReplicate(input *C.VipsImage, across int, down int) (*C.VipsImage, error) {
	incOpCounter("replicate")

	var out_out *C.VipsImage

	ret := C.gen_vips_replicate(input, C.int(across), C.int(down), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRot calls the vips rot operation.
// rotate an image
func vipsGenRot(input *C.VipsImage, angle Angle) (*C.VipsImage, error) {
	incOpCounter("rot")

	var out_out *C.VipsImage

	ret := C.gen_vips_rot(input, C.VipsAngle(angle), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// Rot45Options are optional parameters for rot45.
type Rot45Options struct {
	Angle *Angle45
}

// vipsGenRot45 calls the vips rot45 operation.
// rotate an image
func vipsGenRot45(input *C.VipsImage, opts *Rot45Options) (*C.VipsImage, error) {
	incOpCounter("rot45")

	var out_out *C.VipsImage

	var cOpts C.GenRot45Opts
	if opts != nil {
		if opts.Angle != nil {
			cOpts.has_angle = 1
			cOpts.angle = C.VipsAngle45(*opts.Angle)
		}
	}

	ret := C.gen_vips_rot45(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// RotateOptions are optional parameters for rotate.
type RotateOptions struct {
	Interpolate *C.VipsInterpolate
	Background []float64
	Odx *float64
	Ody *float64
	Idx *float64
	Idy *float64
}

// vipsGenRotate calls the vips rotate operation.
// rotate an image by a number of degrees
func vipsGenRotate(input *C.VipsImage, angle float64, opts *RotateOptions) (*C.VipsImage, error) {
	incOpCounter("rotate")

	var out_out *C.VipsImage

	var cOpts C.GenRotateOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Odx != nil {
			cOpts.has_odx = 1
			cOpts.odx = C.double(*opts.Odx)
		}
		if opts.Ody != nil {
			cOpts.has_ody = 1
			cOpts.ody = C.double(*opts.Ody)
		}
		if opts.Idx != nil {
			cOpts.has_idx = 1
			cOpts.idx = C.double(*opts.Idx)
		}
		if opts.Idy != nil {
			cOpts.has_idy = 1
			cOpts.idy = C.double(*opts.Idy)
		}
	}

	ret := C.gen_vips_rotate(input, C.double(angle), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenRound calls the vips round operation.
// perform a round function on an image
func vipsGenRound(input *C.VipsImage, round OperationRound) (*C.VipsImage, error) {
	incOpCounter("round")

	var out_out *C.VipsImage

	ret := C.gen_vips_round(input, C.VipsOperationRound(round), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSRGB2HSV calls the vips sRGB2HSV operation.
// transform sRGB to HSV
func vipsGenSRGB2HSV(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("sRGB2HSV")

	var out_out *C.VipsImage

	ret := C.gen_vips_sRGB2HSV(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSRGB2scRGB calls the vips sRGB2scRGB operation.
// convert an sRGB image to scRGB
func vipsGenSRGB2scRGB(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("sRGB2scRGB")

	var out_out *C.VipsImage

	ret := C.gen_vips_sRGB2scRGB(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ScRGB2BWOptions are optional parameters for scRGB2BW.
type ScRGB2BWOptions struct {
	Depth *int
}

// vipsGenScRGB2BW calls the vips scRGB2BW operation.
// convert scRGB to BW
func vipsGenScRGB2BW(input *C.VipsImage, opts *ScRGB2BWOptions) (*C.VipsImage, error) {
	incOpCounter("scRGB2BW")

	var out_out *C.VipsImage

	var cOpts C.GenScRGB2BWOpts
	if opts != nil {
		if opts.Depth != nil {
			cOpts.has_depth = 1
			cOpts.depth = C.int(*opts.Depth)
		}
	}

	ret := C.gen_vips_scRGB2BW(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenScRGB2XYZ calls the vips scRGB2XYZ operation.
// transform scRGB to XYZ
func vipsGenScRGB2XYZ(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("scRGB2XYZ")

	var out_out *C.VipsImage

	ret := C.gen_vips_scRGB2XYZ(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ScRGB2sRGBOptions are optional parameters for scRGB2sRGB.
type ScRGB2sRGBOptions struct {
	Depth *int
}

// vipsGenScRGB2sRGB calls the vips scRGB2sRGB operation.
// convert scRGB to sRGB
func vipsGenScRGB2sRGB(input *C.VipsImage, opts *ScRGB2sRGBOptions) (*C.VipsImage, error) {
	incOpCounter("scRGB2sRGB")

	var out_out *C.VipsImage

	var cOpts C.GenScRGB2sRGBOpts
	if opts != nil {
		if opts.Depth != nil {
			cOpts.has_depth = 1
			cOpts.depth = C.int(*opts.Depth)
		}
	}

	ret := C.gen_vips_scRGB2sRGB(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ScaleOptions are optional parameters for scale.
type ScaleOptions struct {
	Exp *float64
	Log *bool
}

// vipsGenScale calls the vips scale operation.
// scale an image to uchar
func vipsGenScale(input *C.VipsImage, opts *ScaleOptions) (*C.VipsImage, error) {
	incOpCounter("scale")

	var out_out *C.VipsImage

	var cOpts C.GenScaleOpts
	if opts != nil {
		if opts.Exp != nil {
			cOpts.has_exp = 1
			cOpts.exp = C.double(*opts.Exp)
		}
		if opts.Log != nil {
			cOpts.has_log = 1
			cOpts.log = C.int(boolToInt(*opts.Log))
		}
	}

	ret := C.gen_vips_scale(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenScharr calls the vips scharr operation.
// Scharr edge detector
func vipsGenScharr(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("scharr")

	var out_out *C.VipsImage

	ret := C.gen_vips_scharr(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SequentialOptions are optional parameters for sequential.
type SequentialOptions struct {
	TileHeight *int
}

// vipsGenSequential calls the vips sequential operation.
// check sequential access
func vipsGenSequential(input *C.VipsImage, opts *SequentialOptions) (*C.VipsImage, error) {
	incOpCounter("sequential")

	var out_out *C.VipsImage

	var cOpts C.GenSequentialOpts
	if opts != nil {
		if opts.TileHeight != nil {
			cOpts.has_tileHeight = 1
			cOpts.tileHeight = C.int(*opts.TileHeight)
		}
	}

	ret := C.gen_vips_sequential(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SharpenOptions are optional parameters for sharpen.
type SharpenOptions struct {
	Sigma *float64
	X1 *float64
	Y2 *float64
	Y3 *float64
	M1 *float64
	M2 *float64
}

// vipsGenSharpen calls the vips sharpen operation.
// unsharp masking for print
func vipsGenSharpen(input *C.VipsImage, opts *SharpenOptions) (*C.VipsImage, error) {
	incOpCounter("sharpen")

	var out_out *C.VipsImage

	var cOpts C.GenSharpenOpts
	if opts != nil {
		if opts.Sigma != nil {
			cOpts.has_sigma = 1
			cOpts.sigma = C.double(*opts.Sigma)
		}
		if opts.X1 != nil {
			cOpts.has_x1 = 1
			cOpts.x1 = C.double(*opts.X1)
		}
		if opts.Y2 != nil {
			cOpts.has_y2 = 1
			cOpts.y2 = C.double(*opts.Y2)
		}
		if opts.Y3 != nil {
			cOpts.has_y3 = 1
			cOpts.y3 = C.double(*opts.Y3)
		}
		if opts.M1 != nil {
			cOpts.has_m1 = 1
			cOpts.m1 = C.double(*opts.M1)
		}
		if opts.M2 != nil {
			cOpts.has_m2 = 1
			cOpts.m2 = C.double(*opts.M2)
		}
	}

	ret := C.gen_vips_sharpen(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ShrinkOptions are optional parameters for shrink.
type ShrinkOptions struct {
	Ceil *bool
}

// vipsGenShrink calls the vips shrink operation.
// shrink an image
func vipsGenShrink(input *C.VipsImage, hshrink float64, vshrink float64, opts *ShrinkOptions) (*C.VipsImage, error) {
	incOpCounter("shrink")

	var out_out *C.VipsImage

	var cOpts C.GenShrinkOpts
	if opts != nil {
		if opts.Ceil != nil {
			cOpts.has_ceil = 1
			cOpts.ceil = C.int(boolToInt(*opts.Ceil))
		}
	}

	ret := C.gen_vips_shrink(input, C.double(hshrink), C.double(vshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ShrinkhOptions are optional parameters for shrinkh.
type ShrinkhOptions struct {
	Ceil *bool
}

// vipsGenShrinkh calls the vips shrinkh operation.
// shrink an image horizontally
func vipsGenShrinkh(input *C.VipsImage, hshrink int, opts *ShrinkhOptions) (*C.VipsImage, error) {
	incOpCounter("shrinkh")

	var out_out *C.VipsImage

	var cOpts C.GenShrinkhOpts
	if opts != nil {
		if opts.Ceil != nil {
			cOpts.has_ceil = 1
			cOpts.ceil = C.int(boolToInt(*opts.Ceil))
		}
	}

	ret := C.gen_vips_shrinkh(input, C.int(hshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ShrinkvOptions are optional parameters for shrinkv.
type ShrinkvOptions struct {
	Ceil *bool
}

// vipsGenShrinkv calls the vips shrinkv operation.
// shrink an image vertically
func vipsGenShrinkv(input *C.VipsImage, vshrink int, opts *ShrinkvOptions) (*C.VipsImage, error) {
	incOpCounter("shrinkv")

	var out_out *C.VipsImage

	var cOpts C.GenShrinkvOpts
	if opts != nil {
		if opts.Ceil != nil {
			cOpts.has_ceil = 1
			cOpts.ceil = C.int(boolToInt(*opts.Ceil))
		}
	}

	ret := C.gen_vips_shrinkv(input, C.int(vshrink), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSign calls the vips sign operation.
// unit vector of pixel
func vipsGenSign(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("sign")

	var out_out *C.VipsImage

	ret := C.gen_vips_sign(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SimilarityOptions are optional parameters for similarity.
type SimilarityOptions struct {
	Scale *float64
	Angle *float64
	Interpolate *C.VipsInterpolate
	Background []float64
	Odx *float64
	Ody *float64
	Idx *float64
	Idy *float64
}

// vipsGenSimilarity calls the vips similarity operation.
// similarity transform of an image
func vipsGenSimilarity(input *C.VipsImage, opts *SimilarityOptions) (*C.VipsImage, error) {
	incOpCounter("similarity")

	var out_out *C.VipsImage

	var cOpts C.GenSimilarityOpts
	var pinner runtime.Pinner
	defer pinner.Unpin()
	if opts != nil {
		if opts.Scale != nil {
			cOpts.has_scale = 1
			cOpts.scale = C.double(*opts.Scale)
		}
		if opts.Angle != nil {
			cOpts.has_angle = 1
			cOpts.angle = C.double(*opts.Angle)
		}
		if opts.Interpolate != nil {
			cOpts.has_interpolate = 1
			cOpts.interpolate = opts.Interpolate
		}
		if opts.Background != nil {
			cOpts.has_background = 1
			pinner.Pin(&opts.Background[0])
			cOpts.background = (*C.double)(unsafe.Pointer(&opts.Background[0]))
			cOpts.background_n = C.int(len(opts.Background))
		}
		if opts.Odx != nil {
			cOpts.has_odx = 1
			cOpts.odx = C.double(*opts.Odx)
		}
		if opts.Ody != nil {
			cOpts.has_ody = 1
			cOpts.ody = C.double(*opts.Ody)
		}
		if opts.Idx != nil {
			cOpts.has_idx = 1
			cOpts.idx = C.double(*opts.Idx)
		}
		if opts.Idy != nil {
			cOpts.has_idy = 1
			cOpts.idy = C.double(*opts.Idy)
		}
	}

	ret := C.gen_vips_similarity(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SinesOptions are optional parameters for sines.
type SinesOptions struct {
	Uchar *bool
	Hfreq *float64
	Vfreq *float64
}

// vipsGenSines calls the vips sines operation.
// make a 2D sine wave
func vipsGenSines(width int, height int, opts *SinesOptions) (*C.VipsImage, error) {
	incOpCounter("sines")

	var out_out *C.VipsImage

	var cOpts C.GenSinesOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
		if opts.Hfreq != nil {
			cOpts.has_hfreq = 1
			cOpts.hfreq = C.double(*opts.Hfreq)
		}
		if opts.Vfreq != nil {
			cOpts.has_vfreq = 1
			cOpts.vfreq = C.double(*opts.Vfreq)
		}
	}

	ret := C.gen_vips_sines(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SmartcropOptions are optional parameters for smartcrop.
type SmartcropOptions struct {
	Interesting *Interesting
	Premultiplied *bool
}

// vipsGenSmartcrop calls the vips smartcrop operation.
// extract an area from an image
func vipsGenSmartcrop(input *C.VipsImage, width int, height int, opts *SmartcropOptions) (int, *C.VipsImage, int, error) {
	incOpCounter("smartcrop")

	var out_attentionX C.int
	var out_out *C.VipsImage
	var out_attentionY C.int

	var cOpts C.GenSmartcropOpts
	if opts != nil {
		if opts.Interesting != nil {
			cOpts.has_interesting = 1
			cOpts.interesting = C.VipsInteresting(*opts.Interesting)
		}
		if opts.Premultiplied != nil {
			cOpts.has_premultiplied = 1
			cOpts.premultiplied = C.int(boolToInt(*opts.Premultiplied))
		}
	}

	ret := C.gen_vips_smartcrop(input, C.int(width), C.int(height), &out_attentionX, &out_out, &out_attentionY, &cOpts)
	if ret != 0 {
		return 0, nil, 0, handleImageError(out_out)
	}

	return int(out_attentionX), out_out, int(out_attentionY), nil
}

// vipsGenSobel calls the vips sobel operation.
// Sobel edge detector
func vipsGenSobel(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("sobel")

	var out_out *C.VipsImage

	ret := C.gen_vips_sobel(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSpcor calls the vips spcor operation.
// spatial correlation
func vipsGenSpcor(input *C.VipsImage, ref *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("spcor")

	var out_out *C.VipsImage

	ret := C.gen_vips_spcor(input, ref, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSpectrum calls the vips spectrum operation.
// make displayable power spectrum
func vipsGenSpectrum(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("spectrum")

	var out_out *C.VipsImage

	ret := C.gen_vips_spectrum(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenStats calls the vips stats operation.
// find many image stats
func vipsGenStats(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("stats")

	var out_out *C.VipsImage

	ret := C.gen_vips_stats(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// StdifOptions are optional parameters for stdif.
type StdifOptions struct {
	S0 *float64
	B *float64
	M0 *float64
	A *float64
}

// vipsGenStdif calls the vips stdif operation.
// statistical difference
func vipsGenStdif(input *C.VipsImage, width int, height int, opts *StdifOptions) (*C.VipsImage, error) {
	incOpCounter("stdif")

	var out_out *C.VipsImage

	var cOpts C.GenStdifOpts
	if opts != nil {
		if opts.S0 != nil {
			cOpts.has_s0 = 1
			cOpts.s0 = C.double(*opts.S0)
		}
		if opts.B != nil {
			cOpts.has_b = 1
			cOpts.b = C.double(*opts.B)
		}
		if opts.M0 != nil {
			cOpts.has_m0 = 1
			cOpts.m0 = C.double(*opts.M0)
		}
		if opts.A != nil {
			cOpts.has_a = 1
			cOpts.a = C.double(*opts.A)
		}
	}

	ret := C.gen_vips_stdif(input, C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// SubsampleOptions are optional parameters for subsample.
type SubsampleOptions struct {
	Point *bool
}

// vipsGenSubsample calls the vips subsample operation.
// subsample an image
func vipsGenSubsample(input *C.VipsImage, xfac int, yfac int, opts *SubsampleOptions) (*C.VipsImage, error) {
	incOpCounter("subsample")

	var out_out *C.VipsImage

	var cOpts C.GenSubsampleOpts
	if opts != nil {
		if opts.Point != nil {
			cOpts.has_point = 1
			cOpts.point = C.int(boolToInt(*opts.Point))
		}
	}

	ret := C.gen_vips_subsample(input, C.int(xfac), C.int(yfac), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSubtract calls the vips subtract operation.
// subtract two images
func vipsGenSubtract(left *C.VipsImage, right *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("subtract")

	var out_out *C.VipsImage

	ret := C.gen_vips_subtract(left, right, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenSum calls the vips sum operation.
// sum an array of images
func vipsGenSum(input []*C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("sum")

	var out_out *C.VipsImage

	ret := C.gen_vips_sum((**C.VipsImage)(unsafe.Pointer(&input[0])), C.int(len(input)), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// TilecacheOptions are optional parameters for tilecache.
type TilecacheOptions struct {
	TileWidth *int
	TileHeight *int
	MaxTiles *int
	Access *int
	Threaded *bool
	Persistent *bool
}

// vipsGenTilecache calls the vips tilecache operation.
// cache an image as a set of tiles
func vipsGenTilecache(input *C.VipsImage, opts *TilecacheOptions) (*C.VipsImage, error) {
	incOpCounter("tilecache")

	var out_out *C.VipsImage

	var cOpts C.GenTilecacheOpts
	if opts != nil {
		if opts.TileWidth != nil {
			cOpts.has_tileWidth = 1
			cOpts.tileWidth = C.int(*opts.TileWidth)
		}
		if opts.TileHeight != nil {
			cOpts.has_tileHeight = 1
			cOpts.tileHeight = C.int(*opts.TileHeight)
		}
		if opts.MaxTiles != nil {
			cOpts.has_maxTiles = 1
			cOpts.maxTiles = C.int(*opts.MaxTiles)
		}
		if opts.Access != nil {
			cOpts.has_access = 1
			cOpts.access = C.VipsAccess(*opts.Access)
		}
		if opts.Threaded != nil {
			cOpts.has_threaded = 1
			cOpts.threaded = C.int(boolToInt(*opts.Threaded))
		}
		if opts.Persistent != nil {
			cOpts.has_persistent = 1
			cOpts.persistent = C.int(boolToInt(*opts.Persistent))
		}
	}

	ret := C.gen_vips_tilecache(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// TonelutOptions are optional parameters for tonelut.
type TonelutOptions struct {
	InMax *int
	OutMax *int
	Lb *float64
	Lw *float64
	Ps *float64
	Pm *float64
	Ph *float64
	S *float64
	M *float64
	H *float64
}

// vipsGenTonelut calls the vips tonelut operation.
// build a look-up table
func vipsGenTonelut(opts *TonelutOptions) (*C.VipsImage, error) {
	incOpCounter("tonelut")

	var out_out *C.VipsImage

	var cOpts C.GenTonelutOpts
	if opts != nil {
		if opts.InMax != nil {
			cOpts.has_inMax = 1
			cOpts.inMax = C.int(*opts.InMax)
		}
		if opts.OutMax != nil {
			cOpts.has_outMax = 1
			cOpts.outMax = C.int(*opts.OutMax)
		}
		if opts.Lb != nil {
			cOpts.has_Lb = 1
			cOpts.Lb = C.double(*opts.Lb)
		}
		if opts.Lw != nil {
			cOpts.has_Lw = 1
			cOpts.Lw = C.double(*opts.Lw)
		}
		if opts.Ps != nil {
			cOpts.has_Ps = 1
			cOpts.Ps = C.double(*opts.Ps)
		}
		if opts.Pm != nil {
			cOpts.has_Pm = 1
			cOpts.Pm = C.double(*opts.Pm)
		}
		if opts.Ph != nil {
			cOpts.has_Ph = 1
			cOpts.Ph = C.double(*opts.Ph)
		}
		if opts.S != nil {
			cOpts.has_S = 1
			cOpts.S = C.double(*opts.S)
		}
		if opts.M != nil {
			cOpts.has_M = 1
			cOpts.M = C.double(*opts.M)
		}
		if opts.H != nil {
			cOpts.has_H = 1
			cOpts.H = C.double(*opts.H)
		}
	}

	ret := C.gen_vips_tonelut(&out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// Transpose3dOptions are optional parameters for transpose3d.
type Transpose3dOptions struct {
	PageHeight *int
}

// vipsGenTranspose3d calls the vips transpose3d operation.
// transpose3d an image
func vipsGenTranspose3d(input *C.VipsImage, opts *Transpose3dOptions) (*C.VipsImage, error) {
	incOpCounter("transpose3d")

	var out_out *C.VipsImage

	var cOpts C.GenTranspose3dOpts
	if opts != nil {
		if opts.PageHeight != nil {
			cOpts.has_pageHeight = 1
			cOpts.pageHeight = C.int(*opts.PageHeight)
		}
	}

	ret := C.gen_vips_transpose3d(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenUhdr2scRGB calls the vips uhdr2scRGB operation.
// transform uhdr to scRGB
func vipsGenUhdr2scRGB(input *C.VipsImage) (*C.VipsImage, error) {
	incOpCounter("uhdr2scRGB")

	var out_out *C.VipsImage

	ret := C.gen_vips_uhdr2scRGB(input, &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// UnpremultiplyOptions are optional parameters for unpremultiply.
type UnpremultiplyOptions struct {
	MaxAlpha *float64
	AlphaBand *int
}

// vipsGenUnpremultiply calls the vips unpremultiply operation.
// unpremultiply image alpha
func vipsGenUnpremultiply(input *C.VipsImage, opts *UnpremultiplyOptions) (*C.VipsImage, error) {
	incOpCounter("unpremultiply")

	var out_out *C.VipsImage

	var cOpts C.GenUnpremultiplyOpts
	if opts != nil {
		if opts.MaxAlpha != nil {
			cOpts.has_maxAlpha = 1
			cOpts.maxAlpha = C.double(*opts.MaxAlpha)
		}
		if opts.AlphaBand != nil {
			cOpts.has_alphaBand = 1
			cOpts.alphaBand = C.int(*opts.AlphaBand)
		}
	}

	ret := C.gen_vips_unpremultiply(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// WorleyOptions are optional parameters for worley.
type WorleyOptions struct {
	CellSize *int
	Seed *int
}

// vipsGenWorley calls the vips worley operation.
// make a worley noise image
func vipsGenWorley(width int, height int, opts *WorleyOptions) (*C.VipsImage, error) {
	incOpCounter("worley")

	var out_out *C.VipsImage

	var cOpts C.GenWorleyOpts
	if opts != nil {
		if opts.CellSize != nil {
			cOpts.has_cellSize = 1
			cOpts.cellSize = C.int(*opts.CellSize)
		}
		if opts.Seed != nil {
			cOpts.has_seed = 1
			cOpts.seed = C.int(*opts.Seed)
		}
	}

	ret := C.gen_vips_worley(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// WrapOptions are optional parameters for wrap.
type WrapOptions struct {
	X *int
	Y *int
}

// vipsGenWrap calls the vips wrap operation.
// wrap image origin
func vipsGenWrap(input *C.VipsImage, opts *WrapOptions) (*C.VipsImage, error) {
	incOpCounter("wrap")

	var out_out *C.VipsImage

	var cOpts C.GenWrapOpts
	if opts != nil {
		if opts.X != nil {
			cOpts.has_x = 1
			cOpts.x = C.int(*opts.X)
		}
		if opts.Y != nil {
			cOpts.has_y = 1
			cOpts.y = C.int(*opts.Y)
		}
	}

	ret := C.gen_vips_wrap(input, &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// XyzOptions are optional parameters for xyz.
type XyzOptions struct {
	Csize *int
	Dsize *int
	Esize *int
}

// vipsGenXyz calls the vips xyz operation.
// make an image where pixel values are coordinates
func vipsGenXyz(width int, height int, opts *XyzOptions) (*C.VipsImage, error) {
	incOpCounter("xyz")

	var out_out *C.VipsImage

	var cOpts C.GenXyzOpts
	if opts != nil {
		if opts.Csize != nil {
			cOpts.has_csize = 1
			cOpts.csize = C.int(*opts.Csize)
		}
		if opts.Dsize != nil {
			cOpts.has_dsize = 1
			cOpts.dsize = C.int(*opts.Dsize)
		}
		if opts.Esize != nil {
			cOpts.has_esize = 1
			cOpts.esize = C.int(*opts.Esize)
		}
	}

	ret := C.gen_vips_xyz(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// ZoneOptions are optional parameters for zone.
type ZoneOptions struct {
	Uchar *bool
}

// vipsGenZone calls the vips zone operation.
// make a zone plate
func vipsGenZone(width int, height int, opts *ZoneOptions) (*C.VipsImage, error) {
	incOpCounter("zone")

	var out_out *C.VipsImage

	var cOpts C.GenZoneOpts
	if opts != nil {
		if opts.Uchar != nil {
			cOpts.has_uchar = 1
			cOpts.uchar = C.int(boolToInt(*opts.Uchar))
		}
	}

	ret := C.gen_vips_zone(C.int(width), C.int(height), &out_out, &cOpts)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

// vipsGenZoom calls the vips zoom operation.
// zoom an image
func vipsGenZoom(input *C.VipsImage, xfac int, yfac int) (*C.VipsImage, error) {
	incOpCounter("zoom")

	var out_out *C.VipsImage

	ret := C.gen_vips_zoom(input, C.int(xfac), C.int(yfac), &out_out)
	if ret != 0 {
		return nil, handleImageError(out_out)
	}

	return out_out, nil
}

