// Code generated by vipsgen. DO NOT EDIT.
#include "generated.h"

int gen_vips_CMC2LCh(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("CMC2LCh");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_CMYK2XYZ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("CMYK2XYZ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_HSV2sRGB(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("HSV2sRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LCh2CMC(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LCh2CMC");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LCh2Lab(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LCh2Lab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Lab2LCh(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Lab2LCh");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Lab2LabQ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Lab2LabQ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Lab2LabS(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Lab2LabS");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Lab2XYZ(VipsImage * input, VipsImage ** out_out, GenLab2XYZOpts *opts) {
    VipsOperation *op = vips_operation_new("Lab2XYZ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_temp) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->temp, opts->temp_n);
                vips_object_set(VIPS_OBJECT(op), "temp", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LabQ2Lab(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LabQ2Lab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LabQ2LabS(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LabQ2LabS");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LabQ2sRGB(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LabQ2sRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LabS2Lab(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LabS2Lab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_LabS2LabQ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("LabS2LabQ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Oklab2Oklch(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Oklab2Oklch");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Oklab2XYZ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Oklab2XYZ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Oklch2Oklab(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Oklch2Oklab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_XYZ2CMYK(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("XYZ2CMYK");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_XYZ2Lab(VipsImage * input, VipsImage ** out_out, GenXYZ2LabOpts *opts) {
    VipsOperation *op = vips_operation_new("XYZ2Lab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_temp) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->temp, opts->temp_n);
                vips_object_set(VIPS_OBJECT(op), "temp", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_XYZ2Oklab(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("XYZ2Oklab");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_XYZ2Yxy(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("XYZ2Yxy");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_XYZ2scRGB(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("XYZ2scRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_Yxy2XYZ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("Yxy2XYZ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_abs(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("abs");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_add(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("add");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_affine(VipsImage * input, double * matrix, int matrix_n, VipsImage ** out_out, GenAffineOpts *opts) {
    VipsOperation *op = vips_operation_new("affine");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(matrix, matrix_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "matrix", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (opts) {
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
        if (opts->has_oarea) {
            {
                VipsArrayInt *arr = vips_array_int_new(opts->oarea, opts->oarea_n);
                vips_object_set(VIPS_OBJECT(op), "oarea", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_odx) {
            vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL);
        }
        if (opts->has_ody) {
            vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL);
        }
        if (opts->has_idx) {
            vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL);
        }
        if (opts->has_idy) {
            vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_premultiplied) {
            vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL);
        }
        if (opts->has_extend) {
            vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_arrayjoin(VipsImage **input, int input_n, VipsImage ** out_out, GenArrayjoinOpts *opts) {
    VipsOperation *op = vips_operation_new("arrayjoin");
    if (!op) return -1;

    {
        VipsArrayImage *arr = vips_array_image_new(input, input_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (opts) {
        if (opts->has_across) {
            vips_object_set(VIPS_OBJECT(op), "across", opts->across, NULL);
        }
        if (opts->has_shim) {
            vips_object_set(VIPS_OBJECT(op), "shim", opts->shim, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_halign) {
            vips_object_set(VIPS_OBJECT(op), "halign", (int)opts->halign, NULL);
        }
        if (opts->has_valign) {
            vips_object_set(VIPS_OBJECT(op), "valign", (int)opts->valign, NULL);
        }
        if (opts->has_hspacing) {
            vips_object_set(VIPS_OBJECT(op), "hspacing", opts->hspacing, NULL);
        }
        if (opts->has_vspacing) {
            vips_object_set(VIPS_OBJECT(op), "vspacing", opts->vspacing, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_autorot(VipsImage * input, VipsImage ** out_out, int * out_angle, int * out_flip) {
    VipsOperation *op = vips_operation_new("autorot");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);
    g_object_get(VIPS_OBJECT(op), "angle", out_angle, NULL);
    g_object_get(VIPS_OBJECT(op), "flip", out_flip, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_avg(VipsImage * input, double * out_out) {
    VipsOperation *op = vips_operation_new("avg");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandbool(VipsImage * input, VipsOperationBoolean boolean, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("bandbool");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandfold(VipsImage * input, VipsImage ** out_out, GenBandfoldOpts *opts) {
    VipsOperation *op = vips_operation_new("bandfold");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_factor) {
            vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandjoin(VipsImage **input, int input_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("bandjoin");
    if (!op) return -1;

    {
        VipsArrayImage *arr = vips_array_image_new(input, input_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandjoin_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("bandjoin_const");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(c, c_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandmean(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("bandmean");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandrank(VipsImage **input, int input_n, VipsImage ** out_out, GenBandrankOpts *opts) {
    VipsOperation *op = vips_operation_new("bandrank");
    if (!op) return -1;

    {
        VipsArrayImage *arr = vips_array_image_new(input, input_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (opts) {
        if (opts->has_index) {
            vips_object_set(VIPS_OBJECT(op), "index", opts->index, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_bandunfold(VipsImage * input, VipsImage ** out_out, GenBandunfoldOpts *opts) {
    VipsOperation *op = vips_operation_new("bandunfold");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_factor) {
            vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_black(int width, int height, VipsImage ** out_out, GenBlackOpts *opts) {
    VipsOperation *op = vips_operation_new("black");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_bands) {
            vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_boolean(VipsImage * left, VipsImage * right, VipsOperationBoolean boolean, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("boolean");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_boolean_const(VipsImage * input, VipsOperationBoolean boolean, double * c, int c_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("boolean_const");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "boolean", (int)boolean, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(c, c_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_buildlut(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("buildlut");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_byteswap(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("byteswap");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_cache(VipsImage * input, VipsImage ** out_out, GenCacheOpts *opts) {
    VipsOperation *op = vips_operation_new("cache");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_maxTiles) {
            vips_object_set(VIPS_OBJECT(op), "max-tiles", opts->maxTiles, NULL);
        }
        if (opts->has_tileHeight) {
            vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL);
        }
        if (opts->has_tileWidth) {
            vips_object_set(VIPS_OBJECT(op), "tile-width", opts->tileWidth, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_canny(VipsImage * input, VipsImage ** out_out, GenCannyOpts *opts) {
    VipsOperation *op = vips_operation_new("canny");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_sigma) {
            vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL);
        }
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_cast(VipsImage * input, VipsBandFormat format, VipsImage ** out_out, GenCastOpts *opts) {
    VipsOperation *op = vips_operation_new("cast");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "format", (int)format, NULL)) goto error;

    if (opts) {
        if (opts->has_shift) {
            vips_object_set(VIPS_OBJECT(op), "shift", (gboolean)opts->shift, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_clamp(VipsImage * input, VipsImage ** out_out, GenClampOpts *opts) {
    VipsOperation *op = vips_operation_new("clamp");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_min) {
            vips_object_set(VIPS_OBJECT(op), "min", opts->min, NULL);
        }
        if (opts->has_max) {
            vips_object_set(VIPS_OBJECT(op), "max", opts->max, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_compass(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenCompassOpts *opts) {
    VipsOperation *op = vips_operation_new("compass");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (opts) {
        if (opts->has_times) {
            vips_object_set(VIPS_OBJECT(op), "times", opts->times, NULL);
        }
        if (opts->has_angle) {
            vips_object_set(VIPS_OBJECT(op), "angle", (int)opts->angle, NULL);
        }
        if (opts->has_combine) {
            vips_object_set(VIPS_OBJECT(op), "combine", (int)opts->combine, NULL);
        }
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
        if (opts->has_layers) {
            vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL);
        }
        if (opts->has_cluster) {
            vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_complex(VipsImage * input, VipsOperationComplex cmplx, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("complex");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "cmplx", (int)cmplx, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_complex2(VipsImage * left, VipsImage * right, VipsOperationComplex2 cmplx, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("complex2");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "cmplx", (int)cmplx, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_complexform(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("complexform");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_complexget(VipsImage * input, VipsOperationComplexget get, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("complexget");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "get", (int)get, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_composite2(VipsImage * base, VipsImage * overlay, VipsBlendMode mode, VipsImage ** out_out, GenComposite2Opts *opts) {
    VipsOperation *op = vips_operation_new("composite2");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "base", base, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "overlay", overlay, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mode", (int)mode, NULL)) goto error;

    if (opts) {
        if (opts->has_x) {
            vips_object_set(VIPS_OBJECT(op), "x", opts->x, NULL);
        }
        if (opts->has_y) {
            vips_object_set(VIPS_OBJECT(op), "y", opts->y, NULL);
        }
        if (opts->has_compositingSpace) {
            vips_object_set(VIPS_OBJECT(op), "compositing-space", (int)opts->compositingSpace, NULL);
        }
        if (opts->has_premultiplied) {
            vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_conv(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvOpts *opts) {
    VipsOperation *op = vips_operation_new("conv");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (opts) {
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
        if (opts->has_layers) {
            vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL);
        }
        if (opts->has_cluster) {
            vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_conva(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvaOpts *opts) {
    VipsOperation *op = vips_operation_new("conva");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (opts) {
        if (opts->has_layers) {
            vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL);
        }
        if (opts->has_cluster) {
            vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_convasep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvasepOpts *opts) {
    VipsOperation *op = vips_operation_new("convasep");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (opts) {
        if (opts->has_layers) {
            vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_convf(VipsImage * input, VipsImage * mask, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("convf");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_convi(VipsImage * input, VipsImage * mask, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("convi");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_convsep(VipsImage * input, VipsImage * mask, VipsImage ** out_out, GenConvsepOpts *opts) {
    VipsOperation *op = vips_operation_new("convsep");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (opts) {
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
        if (opts->has_layers) {
            vips_object_set(VIPS_OBJECT(op), "layers", opts->layers, NULL);
        }
        if (opts->has_cluster) {
            vips_object_set(VIPS_OBJECT(op), "cluster", opts->cluster, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_copy(VipsImage * input, VipsImage ** out_out, GenCopyOpts *opts) {
    VipsOperation *op = vips_operation_new("copy");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_width) {
            vips_object_set(VIPS_OBJECT(op), "width", opts->width, NULL);
        }
        if (opts->has_height) {
            vips_object_set(VIPS_OBJECT(op), "height", opts->height, NULL);
        }
        if (opts->has_bands) {
            vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL);
        }
        if (opts->has_format) {
            vips_object_set(VIPS_OBJECT(op), "format", (int)opts->format, NULL);
        }
        if (opts->has_coding) {
            vips_object_set(VIPS_OBJECT(op), "coding", (int)opts->coding, NULL);
        }
        if (opts->has_interpretation) {
            vips_object_set(VIPS_OBJECT(op), "interpretation", (int)opts->interpretation, NULL);
        }
        if (opts->has_xres) {
            vips_object_set(VIPS_OBJECT(op), "xres", opts->xres, NULL);
        }
        if (opts->has_yres) {
            vips_object_set(VIPS_OBJECT(op), "yres", opts->yres, NULL);
        }
        if (opts->has_xoffset) {
            vips_object_set(VIPS_OBJECT(op), "xoffset", opts->xoffset, NULL);
        }
        if (opts->has_yoffset) {
            vips_object_set(VIPS_OBJECT(op), "yoffset", opts->yoffset, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_countlines(VipsImage * input, VipsDirection direction, double * out_nolines) {
    VipsOperation *op = vips_operation_new("countlines");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "nolines", out_nolines, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_dE00(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("dE00");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_dE76(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("dE76");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_dECMC(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("dECMC");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_deviate(VipsImage * input, double * out_out) {
    VipsOperation *op = vips_operation_new("deviate");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_divide(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("divide");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_extract_area(VipsImage * input, int left, int top, int width, int height, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("extract_area");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "top", top, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_extract_band(VipsImage * input, int band, VipsImage ** out_out, GenExtractBandOpts *opts) {
    VipsOperation *op = vips_operation_new("extract_band");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "band", band, NULL)) goto error;

    if (opts) {
        if (opts->has_n) {
            vips_object_set(VIPS_OBJECT(op), "n", opts->n, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_eye(int width, int height, VipsImage ** out_out, GenEyeOpts *opts) {
    VipsOperation *op = vips_operation_new("eye");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_factor) {
            vips_object_set(VIPS_OBJECT(op), "factor", opts->factor, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_falsecolour(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("falsecolour");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_fastcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("fastcor");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_fill_nearest(VipsImage * input, VipsImage ** out_out, VipsImage ** out_distance) {
    VipsOperation *op = vips_operation_new("fill_nearest");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);
    g_object_get(VIPS_OBJECT(op), "distance", out_distance, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_flatten(VipsImage * input, VipsImage ** out_out, GenFlattenOpts *opts) {
    VipsOperation *op = vips_operation_new("flatten");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_maxAlpha) {
            vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_flip(VipsImage * input, VipsDirection direction, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("flip");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_float2rad(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("float2rad");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_fractsurf(int width, int height, double fractalDimension, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("fractsurf");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "fractal-dimension", fractalDimension, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_freqmult(VipsImage * input, VipsImage * mask, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("freqmult");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_fwfft(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("fwfft");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_gamma(VipsImage * input, VipsImage ** out_out, GenGammaOpts *opts) {
    VipsOperation *op = vips_operation_new("gamma");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_exponent) {
            vips_object_set(VIPS_OBJECT(op), "exponent", opts->exponent, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_gaussblur(VipsImage * input, double sigma, VipsImage ** out_out, GenGaussblurOpts *opts) {
    VipsOperation *op = vips_operation_new("gaussblur");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error;

    if (opts) {
        if (opts->has_minAmpl) {
            vips_object_set(VIPS_OBJECT(op), "min-ampl", opts->minAmpl, NULL);
        }
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_gaussmat(double sigma, double minAmpl, VipsImage ** out_out, GenGaussmatOpts *opts) {
    VipsOperation *op = vips_operation_new("gaussmat");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "min-ampl", minAmpl, NULL)) goto error;

    if (opts) {
        if (opts->has_separable) {
            vips_object_set(VIPS_OBJECT(op), "separable", (gboolean)opts->separable, NULL);
        }
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_gaussnoise(int width, int height, VipsImage ** out_out, GenGaussnoiseOpts *opts) {
    VipsOperation *op = vips_operation_new("gaussnoise");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_sigma) {
            vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL);
        }
        if (opts->has_mean) {
            vips_object_set(VIPS_OBJECT(op), "mean", opts->mean, NULL);
        }
        if (opts->has_seed) {
            vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_globalbalance(VipsImage * input, VipsImage ** out_out, GenGlobalbalanceOpts *opts) {
    VipsOperation *op = vips_operation_new("globalbalance");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_gamma) {
            vips_object_set(VIPS_OBJECT(op), "gamma", opts->gamma, NULL);
        }
        if (opts->has_intOutput) {
            vips_object_set(VIPS_OBJECT(op), "int-output", (gboolean)opts->intOutput, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_gravity(VipsImage * input, VipsCompassDirection direction, int width, int height, VipsImage ** out_out, GenGravityOpts *opts) {
    VipsOperation *op = vips_operation_new("gravity");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_extend) {
            vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_grey(int width, int height, VipsImage ** out_out, GenGreyOpts *opts) {
    VipsOperation *op = vips_operation_new("grey");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_grid(VipsImage * input, int tileHeight, int across, int down, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("grid");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "tile-height", tileHeight, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "across", across, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "down", down, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_cum(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("hist_cum");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_entropy(VipsImage * input, double * out_out) {
    VipsOperation *op = vips_operation_new("hist_entropy");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_equal(VipsImage * input, VipsImage ** out_out, GenHistEqualOpts *opts) {
    VipsOperation *op = vips_operation_new("hist_equal");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_band) {
            vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_find(VipsImage * input, VipsImage ** out_out, GenHistFindOpts *opts) {
    VipsOperation *op = vips_operation_new("hist_find");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_band) {
            vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_find_indexed(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenHistFindIndexedOpts *opts) {
    VipsOperation *op = vips_operation_new("hist_find_indexed");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error;

    if (opts) {
        if (opts->has_combine) {
            vips_object_set(VIPS_OBJECT(op), "combine", (int)opts->combine, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_find_ndim(VipsImage * input, VipsImage ** out_out, GenHistFindNdimOpts *opts) {
    VipsOperation *op = vips_operation_new("hist_find_ndim");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_bins) {
            vips_object_set(VIPS_OBJECT(op), "bins", opts->bins, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_ismonotonic(VipsImage * input, int * out_monotonic) {
    VipsOperation *op = vips_operation_new("hist_ismonotonic");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "monotonic", out_monotonic, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_local(VipsImage * input, int width, int height, VipsImage ** out_out, GenHistLocalOpts *opts) {
    VipsOperation *op = vips_operation_new("hist_local");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_maxSlope) {
            vips_object_set(VIPS_OBJECT(op), "max-slope", opts->maxSlope, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_match(VipsImage * input, VipsImage * ref, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("hist_match");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_norm(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("hist_norm");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hist_plot(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("hist_plot");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hough_circle(VipsImage * input, VipsImage ** out_out, GenHoughCircleOpts *opts) {
    VipsOperation *op = vips_operation_new("hough_circle");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_scale) {
            vips_object_set(VIPS_OBJECT(op), "scale", opts->scale, NULL);
        }
        if (opts->has_minRadius) {
            vips_object_set(VIPS_OBJECT(op), "min-radius", opts->minRadius, NULL);
        }
        if (opts->has_maxRadius) {
            vips_object_set(VIPS_OBJECT(op), "max-radius", opts->maxRadius, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_hough_line(VipsImage * input, VipsImage ** out_out, GenHoughLineOpts *opts) {
    VipsOperation *op = vips_operation_new("hough_line");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_width) {
            vips_object_set(VIPS_OBJECT(op), "width", opts->width, NULL);
        }
        if (opts->has_height) {
            vips_object_set(VIPS_OBJECT(op), "height", opts->height, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_icc_export(VipsImage * input, VipsImage ** out_out, GenIccExportOpts *opts) {
    VipsOperation *op = vips_operation_new("icc_export");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_pcs) {
            vips_object_set(VIPS_OBJECT(op), "pcs", (int)opts->pcs, NULL);
        }
        if (opts->has_intent) {
            vips_object_set(VIPS_OBJECT(op), "intent", (int)opts->intent, NULL);
        }
        if (opts->has_blackPointCompensation) {
            vips_object_set(VIPS_OBJECT(op), "black-point-compensation", (gboolean)opts->blackPointCompensation, NULL);
        }
        if (opts->has_outputProfile) {
            vips_object_set(VIPS_OBJECT(op), "output-profile", opts->outputProfile, NULL);
        }
        if (opts->has_depth) {
            vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_icc_import(VipsImage * input, VipsImage ** out_out, GenIccImportOpts *opts) {
    VipsOperation *op = vips_operation_new("icc_import");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_pcs) {
            vips_object_set(VIPS_OBJECT(op), "pcs", (int)opts->pcs, NULL);
        }
        if (opts->has_intent) {
            vips_object_set(VIPS_OBJECT(op), "intent", (int)opts->intent, NULL);
        }
        if (opts->has_blackPointCompensation) {
            vips_object_set(VIPS_OBJECT(op), "black-point-compensation", (gboolean)opts->blackPointCompensation, NULL);
        }
        if (opts->has_embedded) {
            vips_object_set(VIPS_OBJECT(op), "embedded", (gboolean)opts->embedded, NULL);
        }
        if (opts->has_inputProfile) {
            vips_object_set(VIPS_OBJECT(op), "input-profile", opts->inputProfile, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_identity(VipsImage ** out_out, GenIdentityOpts *opts) {
    VipsOperation *op = vips_operation_new("identity");
    if (!op) return -1;


    if (opts) {
        if (opts->has_bands) {
            vips_object_set(VIPS_OBJECT(op), "bands", opts->bands, NULL);
        }
        if (opts->has_ushort) {
            vips_object_set(VIPS_OBJECT(op), "ushort", (gboolean)opts->ushort, NULL);
        }
        if (opts->has_size) {
            vips_object_set(VIPS_OBJECT(op), "size", opts->size, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_ifthenelse(VipsImage * cond, VipsImage * in1, VipsImage * in2, VipsImage ** out_out, GenIfthenelseOpts *opts) {
    VipsOperation *op = vips_operation_new("ifthenelse");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "cond", cond, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "in1", in1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error;

    if (opts) {
        if (opts->has_blend) {
            vips_object_set(VIPS_OBJECT(op), "blend", (gboolean)opts->blend, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_insert(VipsImage * main, VipsImage * sub, int x, int y, VipsImage ** out_out, GenInsertOpts *opts) {
    VipsOperation *op = vips_operation_new("insert");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "main", main, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sub", sub, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "x", x, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "y", y, NULL)) goto error;

    if (opts) {
        if (opts->has_expand) {
            vips_object_set(VIPS_OBJECT(op), "expand", (gboolean)opts->expand, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_invert(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("invert");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_invertlut(VipsImage * input, VipsImage ** out_out, GenInvertlutOpts *opts) {
    VipsOperation *op = vips_operation_new("invertlut");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_size) {
            vips_object_set(VIPS_OBJECT(op), "size", opts->size, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_invfft(VipsImage * input, VipsImage ** out_out, GenInvfftOpts *opts) {
    VipsOperation *op = vips_operation_new("invfft");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_real) {
            vips_object_set(VIPS_OBJECT(op), "real", (gboolean)opts->real, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_join(VipsImage * in1, VipsImage * in2, VipsDirection direction, VipsImage ** out_out, GenJoinOpts *opts) {
    VipsOperation *op = vips_operation_new("join");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in1", in1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;

    if (opts) {
        if (opts->has_expand) {
            vips_object_set(VIPS_OBJECT(op), "expand", (gboolean)opts->expand, NULL);
        }
        if (opts->has_shim) {
            vips_object_set(VIPS_OBJECT(op), "shim", opts->shim, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_align) {
            vips_object_set(VIPS_OBJECT(op), "align", (int)opts->align, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_labelregions(VipsImage * input, VipsImage ** out_mask, int * out_segments) {
    VipsOperation *op = vips_operation_new("labelregions");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "mask", out_mask, NULL);
    g_object_get(VIPS_OBJECT(op), "segments", out_segments, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_linear(VipsImage * input, double * a, int a_n, double * b, int b_n, VipsImage ** out_out, GenLinearOpts *opts) {
    VipsOperation *op = vips_operation_new("linear");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(a, a_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "a", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }
    {
        VipsArrayDouble *arr = vips_array_double_new(b, b_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "b", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_linecache(VipsImage * input, VipsImage ** out_out, GenLinecacheOpts *opts) {
    VipsOperation *op = vips_operation_new("linecache");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_tileHeight) {
            vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL);
        }
        if (opts->has_access) {
            vips_object_set(VIPS_OBJECT(op), "access", (int)opts->access, NULL);
        }
        if (opts->has_threaded) {
            vips_object_set(VIPS_OBJECT(op), "threaded", (gboolean)opts->threaded, NULL);
        }
        if (opts->has_persistent) {
            vips_object_set(VIPS_OBJECT(op), "persistent", (gboolean)opts->persistent, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_logmat(double sigma, double minAmpl, VipsImage ** out_out, GenLogmatOpts *opts) {
    VipsOperation *op = vips_operation_new("logmat");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "sigma", sigma, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "min-ampl", minAmpl, NULL)) goto error;

    if (opts) {
        if (opts->has_separable) {
            vips_object_set(VIPS_OBJECT(op), "separable", (gboolean)opts->separable, NULL);
        }
        if (opts->has_precision) {
            vips_object_set(VIPS_OBJECT(op), "precision", (int)opts->precision, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mapim(VipsImage * input, VipsImage * index, VipsImage ** out_out, GenMapimOpts *opts) {
    VipsOperation *op = vips_operation_new("mapim");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error;

    if (opts) {
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_premultiplied) {
            vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL);
        }
        if (opts->has_extend) {
            vips_object_set(VIPS_OBJECT(op), "extend", (int)opts->extend, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_maplut(VipsImage * input, VipsImage * lut, VipsImage ** out_out, GenMaplutOpts *opts) {
    VipsOperation *op = vips_operation_new("maplut");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "lut", lut, NULL)) goto error;

    if (opts) {
        if (opts->has_band) {
            vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_butterworth(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_butterworth");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_butterworth_band(int width, int height, double order, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskButterworthBandOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_butterworth_band");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_butterworth_ring(int width, int height, double order, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskButterworthRingOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_butterworth_ring");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "order", order, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_fractal(int width, int height, double fractalDimension, VipsImage ** out_out, GenMaskFractalOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_fractal");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "fractal-dimension", fractalDimension, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_gaussian(int width, int height, double frequencyCutoff, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_gaussian");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_gaussian_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, double amplitudeCutoff, VipsImage ** out_out, GenMaskGaussianBandOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_gaussian_band");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_gaussian_ring(int width, int height, double frequencyCutoff, double amplitudeCutoff, double ringwidth, VipsImage ** out_out, GenMaskGaussianRingOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_gaussian_ring");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "amplitude-cutoff", amplitudeCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_ideal(int width, int height, double frequencyCutoff, VipsImage ** out_out, GenMaskIdealOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_ideal");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_ideal_band(int width, int height, double frequencyCutoffX, double frequencyCutoffY, double radius, VipsImage ** out_out, GenMaskIdealBandOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_ideal_band");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-x", frequencyCutoffX, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff-y", frequencyCutoffY, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "radius", radius, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mask_ideal_ring(int width, int height, double frequencyCutoff, double ringwidth, VipsImage ** out_out, GenMaskIdealRingOpts *opts) {
    VipsOperation *op = vips_operation_new("mask_ideal_ring");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "frequency-cutoff", frequencyCutoff, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ringwidth", ringwidth, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_nodc) {
            vips_object_set(VIPS_OBJECT(op), "nodc", (gboolean)opts->nodc, NULL);
        }
        if (opts->has_reject) {
            vips_object_set(VIPS_OBJECT(op), "reject", (gboolean)opts->reject, NULL);
        }
        if (opts->has_optical) {
            vips_object_set(VIPS_OBJECT(op), "optical", (gboolean)opts->optical, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_match(VipsImage * ref, VipsImage * sec, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMatchOpts *opts) {
    VipsOperation *op = vips_operation_new("match");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xr1", xr1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yr1", yr1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xs1", xs1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ys1", ys1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xr2", xr2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yr2", yr2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xs2", xs2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ys2", ys2, NULL)) goto error;

    if (opts) {
        if (opts->has_hwindow) {
            vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL);
        }
        if (opts->has_harea) {
            vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL);
        }
        if (opts->has_search) {
            vips_object_set(VIPS_OBJECT(op), "search", (gboolean)opts->search, NULL);
        }
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_math(VipsImage * input, VipsOperationMath math, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("math");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "math", (int)math, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_math2(VipsImage * left, VipsImage * right, VipsOperationMath2 math2, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("math2");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "math2", (int)math2, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_math2_const(VipsImage * input, VipsOperationMath2 math2, double * c, int c_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("math2_const");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "math2", (int)math2, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(c, c_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_matrixinvert(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("matrixinvert");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_matrixmultiply(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("matrixmultiply");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_maxpair(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("maxpair");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_merge(VipsImage * ref, VipsImage * sec, VipsDirection direction, int dx, int dy, VipsImage ** out_out, GenMergeOpts *opts) {
    VipsOperation *op = vips_operation_new("merge");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "dx", dx, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "dy", dy, NULL)) goto error;

    if (opts) {
        if (opts->has_mblend) {
            vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_minpair(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("minpair");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_morph(VipsImage * input, VipsImage * mask, VipsOperationMorphology morph, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("morph");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "mask", mask, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "morph", (int)morph, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mosaic(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xref, int yref, int xsec, int ysec, VipsImage ** out_out, int * out_dx0, int * out_dy0, double * out_scale1, double * out_angle1, double * out_dy1, double * out_dx1, GenMosaicOpts *opts) {
    VipsOperation *op = vips_operation_new("mosaic");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xref", xref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yref", yref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xsec", xsec, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ysec", ysec, NULL)) goto error;

    if (opts) {
        if (opts->has_hwindow) {
            vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL);
        }
        if (opts->has_harea) {
            vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL);
        }
        if (opts->has_mblend) {
            vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL);
        }
        if (opts->has_bandno) {
            vips_object_set(VIPS_OBJECT(op), "bandno", opts->bandno, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);
    g_object_get(VIPS_OBJECT(op), "dx0", out_dx0, NULL);
    g_object_get(VIPS_OBJECT(op), "dy0", out_dy0, NULL);
    g_object_get(VIPS_OBJECT(op), "scale1", out_scale1, NULL);
    g_object_get(VIPS_OBJECT(op), "angle1", out_angle1, NULL);
    g_object_get(VIPS_OBJECT(op), "dy1", out_dy1, NULL);
    g_object_get(VIPS_OBJECT(op), "dx1", out_dx1, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_mosaic1(VipsImage * ref, VipsImage * sec, VipsDirection direction, int xr1, int yr1, int xs1, int ys1, int xr2, int yr2, int xs2, int ys2, VipsImage ** out_out, GenMosaic1Opts *opts) {
    VipsOperation *op = vips_operation_new("mosaic1");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "sec", sec, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "direction", (int)direction, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xr1", xr1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yr1", yr1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xs1", xs1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ys1", ys1, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xr2", xr2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yr2", yr2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xs2", xs2, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ys2", ys2, NULL)) goto error;

    if (opts) {
        if (opts->has_hwindow) {
            vips_object_set(VIPS_OBJECT(op), "hwindow", opts->hwindow, NULL);
        }
        if (opts->has_harea) {
            vips_object_set(VIPS_OBJECT(op), "harea", opts->harea, NULL);
        }
        if (opts->has_search) {
            vips_object_set(VIPS_OBJECT(op), "search", (gboolean)opts->search, NULL);
        }
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
        if (opts->has_mblend) {
            vips_object_set(VIPS_OBJECT(op), "mblend", opts->mblend, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_msb(VipsImage * input, VipsImage ** out_out, GenMsbOpts *opts) {
    VipsOperation *op = vips_operation_new("msb");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_band) {
            vips_object_set(VIPS_OBJECT(op), "band", opts->band, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_multiply(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("multiply");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_percent(VipsImage * input, double percent, int * out_threshold) {
    VipsOperation *op = vips_operation_new("percent");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "percent", percent, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "threshold", out_threshold, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_perlin(int width, int height, VipsImage ** out_out, GenPerlinOpts *opts) {
    VipsOperation *op = vips_operation_new("perlin");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_cellSize) {
            vips_object_set(VIPS_OBJECT(op), "cell-size", opts->cellSize, NULL);
        }
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_seed) {
            vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_phasecor(VipsImage * input, VipsImage * in2, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("phasecor");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "in2", in2, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_premultiply(VipsImage * input, VipsImage ** out_out, GenPremultiplyOpts *opts) {
    VipsOperation *op = vips_operation_new("premultiply");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_maxAlpha) {
            vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_prewitt(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("prewitt");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_profile(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows) {
    VipsOperation *op = vips_operation_new("profile");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "columns", out_columns, NULL);
    g_object_get(VIPS_OBJECT(op), "rows", out_rows, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_project(VipsImage * input, VipsImage ** out_columns, VipsImage ** out_rows) {
    VipsOperation *op = vips_operation_new("project");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "columns", out_columns, NULL);
    g_object_get(VIPS_OBJECT(op), "rows", out_rows, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_quadratic(VipsImage * input, VipsImage * coeff, VipsImage ** out_out, GenQuadraticOpts *opts) {
    VipsOperation *op = vips_operation_new("quadratic");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "coeff", coeff, NULL)) goto error;

    if (opts) {
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_rad2float(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("rad2float");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_rank(VipsImage * input, int width, int height, int index, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("rank");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "index", index, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_recomb(VipsImage * input, VipsImage * m, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("recomb");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "m", m, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_reduce(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenReduceOpts *opts) {
    VipsOperation *op = vips_operation_new("reduce");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_kernel) {
            vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL);
        }
        if (opts->has_gap) {
            vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_reduceh(VipsImage * input, double hshrink, VipsImage ** out_out, GenReducehOpts *opts) {
    VipsOperation *op = vips_operation_new("reduceh");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_kernel) {
            vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL);
        }
        if (opts->has_gap) {
            vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_reducev(VipsImage * input, double vshrink, VipsImage ** out_out, GenReducevOpts *opts) {
    VipsOperation *op = vips_operation_new("reducev");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_kernel) {
            vips_object_set(VIPS_OBJECT(op), "kernel", (int)opts->kernel, NULL);
        }
        if (opts->has_gap) {
            vips_object_set(VIPS_OBJECT(op), "gap", opts->gap, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_relational(VipsImage * left, VipsImage * right, VipsOperationRelational relational, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("relational");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "relational", (int)relational, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_relational_const(VipsImage * input, VipsOperationRelational relational, double * c, int c_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("relational_const");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "relational", (int)relational, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(c, c_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_remainder(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("remainder");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_remainder_const(VipsImage * input, double * c, int c_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("remainder_const");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    {
        VipsArrayDouble *arr = vips_array_double_new(c, c_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "c", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_remosaic(VipsImage * input, const char * oldStr, const char * newStr, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("remosaic");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "old-str", oldStr, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "new-str", newStr, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_replicate(VipsImage * input, int across, int down, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("replicate");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "across", across, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "down", down, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_rot(VipsImage * input, VipsAngle angle, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("rot");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "angle", (int)angle, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_rot45(VipsImage * input, VipsImage ** out_out, GenRot45Opts *opts) {
    VipsOperation *op = vips_operation_new("rot45");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_angle) {
            vips_object_set(VIPS_OBJECT(op), "angle", (int)opts->angle, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_rotate(VipsImage * input, double angle, VipsImage ** out_out, GenRotateOpts *opts) {
    VipsOperation *op = vips_operation_new("rotate");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "angle", angle, NULL)) goto error;

    if (opts) {
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_odx) {
            vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL);
        }
        if (opts->has_ody) {
            vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL);
        }
        if (opts->has_idx) {
            vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL);
        }
        if (opts->has_idy) {
            vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_round(VipsImage * input, VipsOperationRound round, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("round");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "round", (int)round, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sRGB2HSV(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("sRGB2HSV");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sRGB2scRGB(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("sRGB2scRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_scRGB2BW(VipsImage * input, VipsImage ** out_out, GenScRGB2BWOpts *opts) {
    VipsOperation *op = vips_operation_new("scRGB2BW");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_depth) {
            vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_scRGB2XYZ(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("scRGB2XYZ");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_scRGB2sRGB(VipsImage * input, VipsImage ** out_out, GenScRGB2sRGBOpts *opts) {
    VipsOperation *op = vips_operation_new("scRGB2sRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_depth) {
            vips_object_set(VIPS_OBJECT(op), "depth", opts->depth, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_scale(VipsImage * input, VipsImage ** out_out, GenScaleOpts *opts) {
    VipsOperation *op = vips_operation_new("scale");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_exp) {
            vips_object_set(VIPS_OBJECT(op), "exp", opts->exp, NULL);
        }
        if (opts->has_log) {
            vips_object_set(VIPS_OBJECT(op), "log", (gboolean)opts->log, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_scharr(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("scharr");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sequential(VipsImage * input, VipsImage ** out_out, GenSequentialOpts *opts) {
    VipsOperation *op = vips_operation_new("sequential");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_tileHeight) {
            vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sharpen(VipsImage * input, VipsImage ** out_out, GenSharpenOpts *opts) {
    VipsOperation *op = vips_operation_new("sharpen");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_sigma) {
            vips_object_set(VIPS_OBJECT(op), "sigma", opts->sigma, NULL);
        }
        if (opts->has_x1) {
            vips_object_set(VIPS_OBJECT(op), "x1", opts->x1, NULL);
        }
        if (opts->has_y2) {
            vips_object_set(VIPS_OBJECT(op), "y2", opts->y2, NULL);
        }
        if (opts->has_y3) {
            vips_object_set(VIPS_OBJECT(op), "y3", opts->y3, NULL);
        }
        if (opts->has_m1) {
            vips_object_set(VIPS_OBJECT(op), "m1", opts->m1, NULL);
        }
        if (opts->has_m2) {
            vips_object_set(VIPS_OBJECT(op), "m2", opts->m2, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_shrink(VipsImage * input, double hshrink, double vshrink, VipsImage ** out_out, GenShrinkOpts *opts) {
    VipsOperation *op = vips_operation_new("shrink");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_ceil) {
            vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_shrinkh(VipsImage * input, int hshrink, VipsImage ** out_out, GenShrinkhOpts *opts) {
    VipsOperation *op = vips_operation_new("shrinkh");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "hshrink", hshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_ceil) {
            vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_shrinkv(VipsImage * input, int vshrink, VipsImage ** out_out, GenShrinkvOpts *opts) {
    VipsOperation *op = vips_operation_new("shrinkv");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "vshrink", vshrink, NULL)) goto error;

    if (opts) {
        if (opts->has_ceil) {
            vips_object_set(VIPS_OBJECT(op), "ceil", (gboolean)opts->ceil, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sign(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("sign");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_similarity(VipsImage * input, VipsImage ** out_out, GenSimilarityOpts *opts) {
    VipsOperation *op = vips_operation_new("similarity");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_scale) {
            vips_object_set(VIPS_OBJECT(op), "scale", opts->scale, NULL);
        }
        if (opts->has_angle) {
            vips_object_set(VIPS_OBJECT(op), "angle", opts->angle, NULL);
        }
        if (opts->has_interpolate) {
            vips_object_set(VIPS_OBJECT(op), "interpolate", opts->interpolate, NULL);
        }
        if (opts->has_background) {
            {
                VipsArrayDouble *arr = vips_array_double_new(opts->background, opts->background_n);
                vips_object_set(VIPS_OBJECT(op), "background", arr, NULL);
                vips_area_unref(VIPS_AREA(arr));
            }
        }
        if (opts->has_odx) {
            vips_object_set(VIPS_OBJECT(op), "odx", opts->odx, NULL);
        }
        if (opts->has_ody) {
            vips_object_set(VIPS_OBJECT(op), "ody", opts->ody, NULL);
        }
        if (opts->has_idx) {
            vips_object_set(VIPS_OBJECT(op), "idx", opts->idx, NULL);
        }
        if (opts->has_idy) {
            vips_object_set(VIPS_OBJECT(op), "idy", opts->idy, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sines(int width, int height, VipsImage ** out_out, GenSinesOpts *opts) {
    VipsOperation *op = vips_operation_new("sines");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
        if (opts->has_hfreq) {
            vips_object_set(VIPS_OBJECT(op), "hfreq", opts->hfreq, NULL);
        }
        if (opts->has_vfreq) {
            vips_object_set(VIPS_OBJECT(op), "vfreq", opts->vfreq, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_smartcrop(VipsImage * input, int width, int height, int * out_attentionX, VipsImage ** out_out, int * out_attentionY, GenSmartcropOpts *opts) {
    VipsOperation *op = vips_operation_new("smartcrop");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_interesting) {
            vips_object_set(VIPS_OBJECT(op), "interesting", (int)opts->interesting, NULL);
        }
        if (opts->has_premultiplied) {
            vips_object_set(VIPS_OBJECT(op), "premultiplied", (gboolean)opts->premultiplied, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "attention-x", out_attentionX, NULL);
    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);
    g_object_get(VIPS_OBJECT(op), "attention-y", out_attentionY, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sobel(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("sobel");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_spcor(VipsImage * input, VipsImage * ref, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("spcor");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "ref", ref, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_spectrum(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("spectrum");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_stats(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("stats");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_stdif(VipsImage * input, int width, int height, VipsImage ** out_out, GenStdifOpts *opts) {
    VipsOperation *op = vips_operation_new("stdif");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_s0) {
            vips_object_set(VIPS_OBJECT(op), "s0", opts->s0, NULL);
        }
        if (opts->has_b) {
            vips_object_set(VIPS_OBJECT(op), "b", opts->b, NULL);
        }
        if (opts->has_m0) {
            vips_object_set(VIPS_OBJECT(op), "m0", opts->m0, NULL);
        }
        if (opts->has_a) {
            vips_object_set(VIPS_OBJECT(op), "a", opts->a, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_subsample(VipsImage * input, int xfac, int yfac, VipsImage ** out_out, GenSubsampleOpts *opts) {
    VipsOperation *op = vips_operation_new("subsample");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xfac", xfac, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yfac", yfac, NULL)) goto error;

    if (opts) {
        if (opts->has_point) {
            vips_object_set(VIPS_OBJECT(op), "point", (gboolean)opts->point, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_subtract(VipsImage * left, VipsImage * right, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("subtract");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "left", left, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "right", right, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_sum(VipsImage **input, int input_n, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("sum");
    if (!op) return -1;

    {
        VipsArrayImage *arr = vips_array_image_new(input, input_n);
        int ret = vips_object_set(VIPS_OBJECT(op), "in", arr, NULL);
        vips_area_unref(VIPS_AREA(arr));
        if (ret) goto error;
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_tilecache(VipsImage * input, VipsImage ** out_out, GenTilecacheOpts *opts) {
    VipsOperation *op = vips_operation_new("tilecache");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_tileWidth) {
            vips_object_set(VIPS_OBJECT(op), "tile-width", opts->tileWidth, NULL);
        }
        if (opts->has_tileHeight) {
            vips_object_set(VIPS_OBJECT(op), "tile-height", opts->tileHeight, NULL);
        }
        if (opts->has_maxTiles) {
            vips_object_set(VIPS_OBJECT(op), "max-tiles", opts->maxTiles, NULL);
        }
        if (opts->has_access) {
            vips_object_set(VIPS_OBJECT(op), "access", (int)opts->access, NULL);
        }
        if (opts->has_threaded) {
            vips_object_set(VIPS_OBJECT(op), "threaded", (gboolean)opts->threaded, NULL);
        }
        if (opts->has_persistent) {
            vips_object_set(VIPS_OBJECT(op), "persistent", (gboolean)opts->persistent, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_tonelut(VipsImage ** out_out, GenTonelutOpts *opts) {
    VipsOperation *op = vips_operation_new("tonelut");
    if (!op) return -1;


    if (opts) {
        if (opts->has_inMax) {
            vips_object_set(VIPS_OBJECT(op), "in-max", opts->inMax, NULL);
        }
        if (opts->has_outMax) {
            vips_object_set(VIPS_OBJECT(op), "out-max", opts->outMax, NULL);
        }
        if (opts->has_Lb) {
            vips_object_set(VIPS_OBJECT(op), "Lb", opts->Lb, NULL);
        }
        if (opts->has_Lw) {
            vips_object_set(VIPS_OBJECT(op), "Lw", opts->Lw, NULL);
        }
        if (opts->has_Ps) {
            vips_object_set(VIPS_OBJECT(op), "Ps", opts->Ps, NULL);
        }
        if (opts->has_Pm) {
            vips_object_set(VIPS_OBJECT(op), "Pm", opts->Pm, NULL);
        }
        if (opts->has_Ph) {
            vips_object_set(VIPS_OBJECT(op), "Ph", opts->Ph, NULL);
        }
        if (opts->has_S) {
            vips_object_set(VIPS_OBJECT(op), "S", opts->S, NULL);
        }
        if (opts->has_M) {
            vips_object_set(VIPS_OBJECT(op), "M", opts->M, NULL);
        }
        if (opts->has_H) {
            vips_object_set(VIPS_OBJECT(op), "H", opts->H, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_transpose3d(VipsImage * input, VipsImage ** out_out, GenTranspose3dOpts *opts) {
    VipsOperation *op = vips_operation_new("transpose3d");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_pageHeight) {
            vips_object_set(VIPS_OBJECT(op), "page-height", opts->pageHeight, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_uhdr2scRGB(VipsImage * input, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("uhdr2scRGB");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_unpremultiply(VipsImage * input, VipsImage ** out_out, GenUnpremultiplyOpts *opts) {
    VipsOperation *op = vips_operation_new("unpremultiply");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_maxAlpha) {
            vips_object_set(VIPS_OBJECT(op), "max-alpha", opts->maxAlpha, NULL);
        }
        if (opts->has_alphaBand) {
            vips_object_set(VIPS_OBJECT(op), "alpha-band", opts->alphaBand, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_worley(int width, int height, VipsImage ** out_out, GenWorleyOpts *opts) {
    VipsOperation *op = vips_operation_new("worley");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_cellSize) {
            vips_object_set(VIPS_OBJECT(op), "cell-size", opts->cellSize, NULL);
        }
        if (opts->has_seed) {
            vips_object_set(VIPS_OBJECT(op), "seed", opts->seed, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_wrap(VipsImage * input, VipsImage ** out_out, GenWrapOpts *opts) {
    VipsOperation *op = vips_operation_new("wrap");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "in", input, NULL)) goto error;

    if (opts) {
        if (opts->has_x) {
            vips_object_set(VIPS_OBJECT(op), "x", opts->x, NULL);
        }
        if (opts->has_y) {
            vips_object_set(VIPS_OBJECT(op), "y", opts->y, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_xyz(int width, int height, VipsImage ** out_out, GenXyzOpts *opts) {
    VipsOperation *op = vips_operation_new("xyz");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_csize) {
            vips_object_set(VIPS_OBJECT(op), "csize", opts->csize, NULL);
        }
        if (opts->has_dsize) {
            vips_object_set(VIPS_OBJECT(op), "dsize", opts->dsize, NULL);
        }
        if (opts->has_esize) {
            vips_object_set(VIPS_OBJECT(op), "esize", opts->esize, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_zone(int width, int height, VipsImage ** out_out, GenZoneOpts *opts) {
    VipsOperation *op = vips_operation_new("zone");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "width", width, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "height", height, NULL)) goto error;

    if (opts) {
        if (opts->has_uchar) {
            vips_object_set(VIPS_OBJECT(op), "uchar", (gboolean)opts->uchar, NULL);
        }
    }

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

int gen_vips_zoom(VipsImage * input, int xfac, int yfac, VipsImage ** out_out) {
    VipsOperation *op = vips_operation_new("zoom");
    if (!op) return -1;

    if (vips_object_set(VIPS_OBJECT(op), "input", input, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "xfac", xfac, NULL)) goto error;
    if (vips_object_set(VIPS_OBJECT(op), "yfac", yfac, NULL)) goto error;

    if (vips_cache_operation_buildp(&op)) goto error;

    g_object_get(VIPS_OBJECT(op), "out", out_out, NULL);

    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return 0;

error:
    vips_object_unref_outputs(VIPS_OBJECT(op));
    g_object_unref(op);
    return -1;
}

